diff --git a/stratosphere/boot/source/boot_main.cpp b/stratosphere/boot/source/boot_main.cpp index fca0b78e6..8f50a24a1 100644 --- a/stratosphere/boot/source/boot_main.cpp +++ b/stratosphere/boot/source/boot_main.cpp @@ -12,6 +12,7 @@ #define PMC_BASE 0x7000E400 #define MAX_GPIOS 0x3D #define MAX_PINMUX 0xA2 +#define MAX_PINMUX_5X 0xAF extern "C" { extern u32 __start__; @@ -223,8 +224,8 @@ static int gpio_set_value(u64 gpio_base_vaddr, unsigned int gpio_pad_name) { return gpio_out_val; } - -static const std::tuple g_pinmux_map[] = { + +static const std::tuple g_pinmux_map[] = { {0x00003000, 0x72FF, 0x01}, /* Sdmmc1Clk */ {0x00003004, 0x72FF, 0x02}, /* Sdmmc1Cmd */ {0x00003008, 0x72FF, 0x02}, /* Sdmmc1Dat3 */ @@ -387,6 +388,349 @@ static const std::tuple g_pinmux_map[] = { {0x00003288, 0x72FF, 0x01}, /* GpioPz3 */ {0x0000328C, 0x72FF, 0x01}, /* GpioPz4 */ {0x00003290, 0x72FF, 0x01}, /* GpioPz5 */ + + /* 5.0.0+ only */ + {0x00003294, 0x1F2FF, 0x02}, /* Sdmmc2Dat0 */ + {0x00003298, 0x1F2FF, 0x02}, /* Sdmmc2Dat1 */ + {0x0000329C, 0x1F2FF, 0x02}, /* Sdmmc2Dat2 */ + {0x000032A0, 0x1F2FF, 0x02}, /* Sdmmc2Dat3 */ + {0x000032A4, 0x1F2FF, 0x02}, /* Sdmmc2Dat4 */ + {0x000032A8, 0x1F2FF, 0x02}, /* Sdmmc2Dat5 */ + {0x000032AC, 0x1F2FF, 0x02}, /* Sdmmc2Dat6 */ + {0x000032B0, 0x1F2FF, 0x02}, /* Sdmmc2Dat7 */ + {0x000032B4, 0x1F2FF, 0x02}, /* Sdmmc2Clk */ + {0x000032B8, 0x1F2FF, 0x00}, /* Sdmmc2Clkb */ + {0x000032BC, 0x1F2FF, 0x02}, /* Sdmmc2Cmd */ + {0x000032C0, 0x1F2FF, 0x00}, /* Sdmmc2Dqs */ + {0x000032C4, 0x1F2FF, 0x00}, /* Sdmmc2Dqsb */ +}; + +static const std::tuple g_pinmux_config_map_icosa[] = { + {0x5D, 0x00, 0x67}, + {0x47, 0x28, 0x7F}, + {0x48, 0x00, 0x67}, + {0x46, 0x00, 0x67}, + {0x49, 0x00, 0x67}, + {0x30, 0x40, 0x27F}, + {0x31, 0x40, 0x27F}, + {0x0D, 0x20, 0x27F}, + {0x0C, 0x00, 0x267}, + {0x10, 0x20, 0x27F}, + {0x0F, 0x00, 0x267}, + {0x0E, 0x20, 0x27F}, + {0x00, 0x48, 0x7F}, + {0x01, 0x50, 0x7F}, + {0x05, 0x50, 0x7F}, + {0x04, 0x50, 0x7F}, + {0x03, 0x50, 0x7F}, + {0x02, 0x50, 0x7F}, + {0x5B, 0x00, 0x78}, + {0x7C, 0x01, 0x67}, + {0x80, 0x01, 0x7F}, + {0x34, 0x40, 0x27F}, + {0x35, 0x40, 0x27F}, + {0x55, 0x20, 0x78}, + {0x56, 0x20, 0x7F}, + {0xA1, 0x30, 0x7F}, + {0x5C, 0x00, 0x78}, + {0x59, 0x00, 0x60}, + {0x5A, 0x30, 0x78}, + {0x2C, 0x40, 0x27F}, + {0x2D, 0x40, 0x27F}, + {0x2E, 0x40, 0x27F}, + {0x2F, 0x40, 0x27F}, + {0x3B, 0x20, 0x7F}, + {0x3C, 0x00, 0x67}, + {0x3D, 0x20, 0x7F}, + {0x36, 0x00, 0x67}, + {0x37, 0x30, 0x7F}, + {0x38, 0x00, 0x67}, + {0x39, 0x28, 0x7F}, + {0x54, 0x00, 0x67}, + {0x9B, 0x30, 0x7F}, + {0x1C, 0x00, 0x67}, + {0x1D, 0x30, 0x7F}, + {0x1E, 0x00, 0x67}, + {0x1F, 0x00, 0x67}, + {0x3F, 0x20, 0x7F}, + {0x40, 0x00, 0x67}, + {0x41, 0x20, 0x7F}, + {0x42, 0x00, 0x67}, + {0x43, 0x28, 0x7F}, + {0x44, 0x00, 0x67}, + {0x45, 0x28, 0x7F}, + {0x22, 0x00, 0x67}, + {0x23, 0x28, 0x7F}, + {0x20, 0x00, 0x67}, + {0x21, 0x00, 0x67}, + {0x4B, 0x28, 0x7F}, + {0x4C, 0x00, 0x67}, + {0x4A, 0x00, 0x67}, + {0x4D, 0x00, 0x67}, + {0x64, 0x20, 0x27F}, + {0x5F, 0x34, 0x7F}, + {0x60, 0x04, 0x67}, + {0x61, 0x2C, 0x7F}, + {0x2A, 0x04, 0x67}, + {0x2B, 0x04, 0x67}, + {0x8F, 0x24, 0x7F}, + {0x33, 0x34, 0x27F}, + {0x52, 0x2C, 0x7F}, + {0x53, 0x24, 0x7F}, + {0x77, 0x04, 0x67}, + {0x78, 0x34, 0x7F}, + {0x11, 0x04, 0x67}, + {0x06, 0x2C, 0x7F}, + {0x08, 0x24, 0x7F}, + {0x09, 0x24, 0x7F}, + {0x0A, 0x24, 0x7F}, + {0x0B, 0x24, 0x7F}, + {0x88, 0x34, 0x7F}, + {0x86, 0x2C, 0x7F}, + {0x82, 0x24, 0x7F}, + {0x85, 0x34, 0x7F}, + {0x89, 0x24, 0x7F}, + {0x8A, 0x34, 0x7F}, + {0x8B, 0x34, 0x7F}, + {0x8C, 0x34, 0x7F}, + {0x8D, 0x24, 0x7F}, + {0x7D, 0x04, 0x67}, + {0x7E, 0x04, 0x67}, + {0x81, 0x04, 0x67}, + {0x9C, 0x34, 0x7F}, + {0x9D, 0x34, 0x7F}, + {0x9E, 0x2C, 0x7F}, + {0x9F, 0x34, 0x7F}, + {0xA0, 0x04, 0x67}, + {0x4F, 0x04, 0x67}, + {0x51, 0x04, 0x67}, + {0x3A, 0x24, 0x7F}, + {0x92, 0x4C, 0x7F}, + {0x93, 0x4C, 0x7F}, + {0x94, 0x44, 0x7F}, + {0x95, 0x04, 0x67}, + {0x96, 0x34, 0x7F}, + {0x97, 0x04, 0x67}, + {0x98, 0x34, 0x7F}, + {0x99, 0x34, 0x7F}, + {0x9A, 0x04, 0x67}, + {0x3E, 0x24, 0x7F}, + {0x6A, 0x04, 0x67}, + {0x6B, 0x04, 0x67}, + {0x6C, 0x2C, 0x7F}, + {0x6D, 0x04, 0x67}, + {0x6E, 0x04, 0x67}, + {0x6F, 0x24, 0x7F}, + {0x91, 0x24, 0x7F}, + {0x70, 0x04, 0x7F}, + {0x71, 0x04, 0x67}, + {0x72, 0x04, 0x67}, + {0x65, 0x34, 0x7F}, + {0x66, 0x04, 0x67}, + {0x67, 0x04, 0x267}, + {0x5E, 0x05, 0x07}, + {0x17, 0x05, 0x07}, + {0x18, 0x05, 0x07}, + {0x19, 0x05, 0x07}, + {0x1A, 0x05, 0x07}, + {0x1B, 0x05, 0x07}, + {0x26, 0x05, 0x07}, + {0x27, 0x05, 0x07}, + {0x28, 0x05, 0x07}, + {0x29, 0x05, 0x07}, + {0x90, 0x05, 0x07}, + {0x32, 0x05, 0x07}, + {0x75, 0x05, 0x07}, + {0x76, 0x05, 0x07}, + {0x79, 0x05, 0x07}, + {0x7A, 0x05, 0x07}, + {0x8E, 0x05, 0x07}, + {0x07, 0x05, 0x07}, + {0x87, 0x05, 0x07}, + {0x83, 0x05, 0x07}, + {0x84, 0x05, 0x07}, + {0x7B, 0x05, 0x07}, + {0x7F, 0x05, 0x07}, + {0x58, 0x00, 0x00}, + {0x50, 0x05, 0x07}, + {0x4E, 0x05, 0x07}, + {0x12, 0x05, 0x07}, + {0x13, 0x05, 0x07}, + {0x14, 0x05, 0x07}, + {0x15, 0x05, 0x07}, + {0x16, 0x05, 0x07}, + {0x73, 0x05, 0x07}, + {0x74, 0x05, 0x07}, + {0x24, 0x05, 0x07}, + {0x25, 0x05, 0x07}, + {0x62, 0x05, 0x07}, + {0x68, 0x05, 0x07}, + {0x69, 0x05, 0x07}, + {0x63, 0x05, 0x07}, +}; + +static const std::tuple g_pinmux_config_map_copper[] = { + {0x10, 0x20, 0x27F}, + {0x0F, 0x00, 0x267}, + {0x0E, 0x20, 0x27F}, + {0x5B, 0x00, 0x00}, + {0x80, 0x01, 0x7F}, + {0x34, 0x40, 0x267}, + {0x35, 0x40, 0x267}, + {0x55, 0x00, 0x18}, + {0x56, 0x01, 0x67}, + {0x5C, 0x00, 0x00}, + {0x59, 0x00, 0x00}, + {0x5A, 0x10, 0x18}, + {0x2C, 0x40, 0x267}, + {0x2D, 0x40, 0x267}, + {0x2E, 0x40, 0x267}, + {0x2F, 0x40, 0x267}, + {0x36, 0x00, 0x67}, + {0x37, 0x30, 0x7F}, + {0x38, 0x00, 0x67}, + {0x39, 0x28, 0x7F}, + {0x54, 0x00, 0x67}, + {0x9B, 0x30, 0x7F}, + {0x42, 0x00, 0x67}, + {0x43, 0x28, 0x7F}, + {0x44, 0x00, 0x67}, + {0x45, 0x28, 0x7F}, + {0x4B, 0x28, 0x7F}, + {0x4C, 0x00, 0x67}, + {0x4A, 0x00, 0x67}, + {0x4D, 0x00, 0x67}, + {0x64, 0x20, 0x27F}, + {0x63, 0x40, 0x267}, + {0x5E, 0x04, 0x67}, + {0x60, 0x04, 0x67}, + {0x17, 0x24, 0x7F}, + {0x18, 0x24, 0x7F}, + {0x27, 0x04, 0x67}, + {0x2A, 0x04, 0x67}, + {0x2B, 0x04, 0x67}, + {0x90, 0x24, 0x7F}, + {0x32, 0x24, 0x27F}, + {0x33, 0x34, 0x27F}, + {0x76, 0x04, 0x67}, + {0x79, 0x04, 0x67}, + {0x08, 0x24, 0x7F}, + {0x09, 0x24, 0x7F}, + {0x0A, 0x24, 0x7F}, + {0x0B, 0x24, 0x7F}, + {0x88, 0x34, 0x7F}, + {0x89, 0x24, 0x7F}, + {0x8A, 0x34, 0x7F}, + {0x8B, 0x34, 0x7F}, + {0x8D, 0x34, 0x7F}, + {0x81, 0x04, 0x67}, + {0x9D, 0x34, 0x7F}, + {0x9F, 0x34, 0x7F}, + {0xA1, 0x34, 0x7F}, + {0x92, 0x4C, 0x7F}, + {0x93, 0x4C, 0x7F}, + {0x94, 0x44, 0x7F}, + {0x96, 0x34, 0x7F}, + {0x98, 0x34, 0x7F}, + {0x99, 0x34, 0x7F}, + {0x12, 0x04, 0x7F}, + {0x13, 0x04, 0x67}, + {0x14, 0x04, 0x7F}, + {0x6A, 0x04, 0x67}, + {0x6B, 0x04, 0x67}, + {0x6C, 0x2C, 0x7F}, + {0x6D, 0x04, 0x67}, + {0x6E, 0x04, 0x67}, + {0x6F, 0x24, 0x7F}, + {0x70, 0x04, 0x7F}, + {0x73, 0x04, 0x67}, + {0x69, 0x24, 0x7F}, + {0x5D, 0x05, 0x07}, + {0x5F, 0x05, 0x07}, + {0x61, 0x05, 0x07}, + {0x47, 0x05, 0x07}, + {0x48, 0x05, 0x07}, + {0x46, 0x05, 0x07}, + {0x49, 0x05, 0x07}, + {0x19, 0x05, 0x07}, + {0x1A, 0x05, 0x07}, + {0x1B, 0x05, 0x07}, + {0x26, 0x05, 0x07}, + {0x28, 0x05, 0x07}, + {0x29, 0x05, 0x07}, + {0x8F, 0x05, 0x07}, + {0x30, 0x05, 0x07}, + {0x31, 0x05, 0x07}, + {0x52, 0x05, 0x07}, + {0x53, 0x05, 0x07}, + {0x75, 0x05, 0x07}, + {0x77, 0x05, 0x07}, + {0x78, 0x05, 0x07}, + {0x7A, 0x05, 0x07}, + {0x0D, 0x05, 0x07}, + {0x0C, 0x05, 0x07}, + {0x11, 0x05, 0x07}, + {0x8E, 0x05, 0x07}, + {0x00, 0x05, 0x07}, + {0x01, 0x05, 0x07}, + {0x05, 0x05, 0x07}, + {0x04, 0x05, 0x07}, + {0x03, 0x05, 0x07}, + {0x02, 0x05, 0x07}, + {0x06, 0x05, 0x07}, + {0x07, 0x05, 0x07}, + {0x87, 0x05, 0x07}, + {0x86, 0x05, 0x07}, + {0x82, 0x05, 0x07}, + {0x83, 0x05, 0x07}, + {0x85, 0x05, 0x07}, + {0x84, 0x05, 0x07}, + {0x8C, 0x05, 0x07}, + {0x7B, 0x05, 0x07}, + {0x7C, 0x05, 0x07}, + {0x7D, 0x05, 0x07}, + {0x7E, 0x05, 0x07}, + {0x7F, 0x05, 0x07}, + {0x9C, 0x05, 0x07}, + {0x9E, 0x05, 0x07}, + {0xA0, 0x05, 0x07}, + {0x58, 0x00, 0x00}, + {0x4F, 0x05, 0x07}, + {0x50, 0x05, 0x07}, + {0x4E, 0x05, 0x07}, + {0x51, 0x05, 0x07}, + {0x3A, 0x05, 0x07}, + {0x3B, 0x05, 0x07}, + {0x3C, 0x05, 0x07}, + {0x3D, 0x05, 0x07}, + {0x95, 0x05, 0x07}, + {0x97, 0x05, 0x07}, + {0x9A, 0x05, 0x07}, + {0x15, 0x05, 0x07}, + {0x16, 0x05, 0x07}, + {0x1C, 0x05, 0x07}, + {0x1D, 0x05, 0x07}, + {0x1E, 0x05, 0x07}, + {0x1F, 0x05, 0x07}, + {0x3E, 0x05, 0x07}, + {0x3F, 0x05, 0x07}, + {0x40, 0x05, 0x07}, + {0x41, 0x05, 0x07}, + {0x91, 0x05, 0x07}, + {0x71, 0x05, 0x07}, + {0x72, 0x05, 0x07}, + {0x74, 0x05, 0x07}, + {0x22, 0x05, 0x07}, + {0x23, 0x05, 0x07}, + {0x20, 0x05, 0x07}, + {0x21, 0x05, 0x07}, + {0x24, 0x05, 0x07}, + {0x25, 0x05, 0x07}, + {0x62, 0x05, 0x07}, + {0x65, 0x05, 0x07}, + {0x66, 0x05, 0x07}, + {0x67, 0x05, 0x07}, + {0x68, 0x05, 0x07}, }; static int pinmux_update_park(u64 pinmux_base_vaddr, unsigned int pinmux_idx) { @@ -416,6 +760,472 @@ static int pinmux_update_park(u64 pinmux_base_vaddr, unsigned int pinmux_idx) { return pinmux_val; } +static int pinmux_update_pad(u64 pinmux_base_vaddr, unsigned int pinmux_idx, unsigned int pinmux_config_val, unsigned int pinmux_config_mask_val) { + /* Fetch this PINMUX's register offset */ + u32 pinmux_reg_offset = std::get<0>(g_pinmux_map[pinmux_idx]); + + /* Fetch this PINMUX's mask value */ + u32 pinmux_mask_val = std::get<1>(g_pinmux_map[pinmux_idx]); + + /* Read from the PINMUX register */ + u32 pinmux_val = *((u32 *)pinmux_base_vaddr + pinmux_reg_offset); + + /* This PINMUX register is locked */ + if (pinmux_val & 0x80) + return pinmux_val; + + u32 pm_config_val = (pinmux_config_val & 0x07); + u32 pm_val = pm_config_val; + + /* Adjust PM */ + if (pinmux_config_mask_val & 0x07) { + /* Default to safe value */ + if (pm_config_val >= 0x06) + pm_val = 0x04; + + /* Apply additional changes first */ + if (pm_config_val == 0x05) { + /* This pin supports PUPD change */ + if (pinmux_mask_val & 0x0C) { + /* Change PUPD */ + if ((pinmux_val & 0x0C) != 0x04) { + pinmux_val &= 0xFFFFFFF3; + pinmux_val |= 0x04; + } + } + + /* This pin supports Tristate change */ + if (pinmux_mask_val & 0x10) { + /* Change Tristate */ + if (!(pinmux_val & 0x10)) { + pinmux_val |= 0x10; + } + } + + /* This pin supports EInput change */ + if (pinmux_mask_val & 0x40) { + /* Change EInput */ + if (pinmux_val & 0x40) { + pinmux_val &= 0xFFFFFFBF; + } + } + + /* Default to safe value */ + pm_val = 0x04; + } + + /* Translate PM value if necessary */ + if ((pm_val & 0xFF) == 0x04) + pm_val = std::get<2>(g_pinmux_map[pinmux_idx]); + + /* This pin supports PM change */ + if (pinmux_mask_val & 0x03) { + /* Change PM */ + if ((pinmux_val & 0x03) != (pm_val & 0x03)) { + pinmux_val &= 0xFFFFFFFC; + pinmux_val |= (pm_val & 0x03); + } + } + } + + u32 pupd_config_val = (pinmux_config_val & 0x18); + + /* Adjust PUPD */ + if (pinmux_config_mask_val & 0x18) { + if (pupd_config_val < 0x11) { + /* This pin supports PUPD change */ + if (pinmux_mask_val & 0x0C) { + /* Change PUPD */ + if ((pinmux_val & 0x0C) != (pupd_config_val >> 0x03)) { + pinmux_val &= 0xFFFFFFF3; + pinmux_val |= (pupd_config_val >> 0x01); + } + } + } + } + + u32 eod_config_val = (pinmux_config_val & 0x60); + + /* Adjust EOd field */ + if (pinmux_config_mask_val & 0x60) { + if (eod_config_val == 0x20) { + /* This pin supports Tristate change */ + if (pinmux_mask_val & 0x10) { + /* Change Tristate */ + if (!(pinmux_val & 0x10)) { + pinmux_val |= 0x10; + } + } + + /* This pin supports EInput change */ + if (pinmux_mask_val & 0x40) { + /* Change EInput */ + if (!(pinmux_val & 0x40)) { + pinmux_val |= 0x40; + } + } + + /* This pin supports EOd change */ + if (pinmux_mask_val & 0x800) { + /* Change EOd */ + if (pinmux_val & 0x800) { + pinmux_val &= 0xFFFFF7FF; + } + } + } else if (eod_config_val == 0x40) { + /* This pin supports Tristate change */ + if (pinmux_mask_val & 0x10) { + /* Change Tristate */ + if (pinmux_val & 0x10) { + pinmux_val &= 0xFFFFFFEF; + } + } + + /* This pin supports EInput change */ + if (pinmux_mask_val & 0x40) { + /* Change EInput */ + if (!(pinmux_val & 0x40)) { + pinmux_val |= 0x40; + } + } + + /* This pin supports EOd change */ + if (pinmux_mask_val & 0x800) { + /* Change EOd */ + if (pinmux_val & 0x800) { + pinmux_val &= 0xFFFFF7FF; + } + } + } else if (eod_config_val == 0x60) { + /* This pin supports Tristate change */ + if (pinmux_mask_val & 0x10) { + /* Change Tristate */ + if (pinmux_val & 0x10) { + pinmux_val &= 0xFFFFFFEF; + } + } + + /* This pin supports EInput change */ + if (pinmux_mask_val & 0x40) { + /* Change EInput */ + if (!(pinmux_val & 0x40)) { + pinmux_val |= 0x40; + } + } + + /* This pin supports EOd change */ + if (pinmux_mask_val & 0x800) { + /* Change EOd */ + if (!(pinmux_val & 0x800)) { + pinmux_val |= 0x800; + } + } + } else { + /* This pin supports Tristate change */ + if (pinmux_mask_val & 0x10) { + /* Change Tristate */ + if (pinmux_val & 0x10) { + pinmux_val &= 0xFFFFFFEF; + } + } + + /* This pin supports EInput change */ + if (pinmux_mask_val & 0x40) { + /* Change EInput */ + if (pinmux_val & 0x40) { + pinmux_val &= 0xFFFFFFBF; + } + } + + /* This pin supports EOd change */ + if (pinmux_mask_val & 0x800) { + /* Change EOd */ + if (pinmux_val & 0x800) { + pinmux_val &= 0xFFFFF7FF; + } + } + } + } + + u32 lock_config_val = (pinmux_config_val & 0x80); + + /* Adjust Lock */ + if (pinmux_config_mask_val & 0x80) { + /* This pin supports Lock change */ + if (pinmux_mask_val & 0x80) { + /* Change Lock */ + if ((pinmux_val ^ pinmux_config_val) & 0x80) { + pinmux_val &= 0xFFFFFF7F; + pinmux_val |= lock_config_val; + } + } + } + + u32 ioreset_config_val = ((pinmux_config_val >> 0x08) & 0x10000); + + /* Adjust IoReset */ + if (pinmux_config_mask_val & 0x100) { + /* This pin supports IoReset change */ + if (pinmux_mask_val & 0x10000) { + /* Change IoReset */ + if (((pinmux_val >> 0x10) ^ (pinmux_config_val >> 0x08)) & 0x01) { + pinmux_val |= ioreset_config_val; + } + } + } + + u32 park_config_val = ((pinmux_config_val >> 0x0A) & 0x20); + + /* Adjust Park */ + if (pinmux_config_mask_val & 0x400) { + /* This pin supports Park change */ + if (pinmux_mask_val & 0x20) { + /* Change Park */ + if (((pinmux_val >> 0x05) ^ (pinmux_config_val >> 0x0A)) & 0x01) { + pinmux_val |= park_config_val; + } + } + } + + u32 elpdr_config_val = ((pinmux_config_val >> 0x0B) & 0x100); + + /* Adjust ELpdr */ + if (pinmux_config_mask_val & 0x800) { + /* This pin supports ELpdr change */ + if (pinmux_mask_val & 0x100) { + /* Change ELpdr */ + if (((pinmux_val >> 0x08) ^ (pinmux_config_val >> 0x0B)) & 0x01) { + pinmux_val |= elpdr_config_val; + } + } + } + + u32 ehsm_config_val = ((pinmux_config_val >> 0x0C) & 0x200); + + /* Adjust EHsm */ + if (pinmux_config_mask_val & 0x1000) { + /* This pin supports EHsm change */ + if (pinmux_mask_val & 0x200) { + /* Change EHsm */ + if (((pinmux_val >> 0x09) ^ (pinmux_config_val >> 0x0C)) & 0x01) { + pinmux_val |= ehsm_config_val; + } + } + } + + u32 eiohv_config_val = ((pinmux_config_val >> 0x09) & 0x400); + + /* Adjust EIoHv */ + if (pinmux_config_mask_val & 0x200) { + /* This pin supports EIoHv change */ + if (pinmux_mask_val & 0x400) { + /* Change EIoHv */ + if (((pinmux_val >> 0x0A) ^ (pinmux_config_val >> 0x09)) & 0x01) { + pinmux_val |= eiohv_config_val; + } + } + } + + u32 eschmt_config_val = ((pinmux_config_val >> 0x0D) & 0x1000); + + /* Adjust ESchmt */ + if (pinmux_config_mask_val & 0x2000) { + /* This pin supports ESchmt change */ + if (pinmux_mask_val & 0x1000) { + /* Change ESchmt */ + if (((pinmux_val >> 0x0C) ^ (pinmux_config_val >> 0x0D)) & 0x01) { + pinmux_val |= eschmt_config_val; + } + } + } + + u32 preemp_config_val = ((pinmux_config_val >> 0x0D) & 0x8000); + + /* Adjust Preemp */ + if (pinmux_config_mask_val & 0x10000) { + + /* This pin supports Preemp change */ + if (pinmux_mask_val & 0x8000) { + /* Change Preemp */ + if (((pinmux_val >> 0x0F) ^ (pinmux_config_val >> 0x10)) & 0x01) { + pinmux_val |= preemp_config_val; + } + } + } + + u32 drvtype_config_val = ((pinmux_config_val >> 0x0E) & 0x6000); + + /* Adjust DrvType */ + if (pinmux_config_mask_val & 0xC000) { + /* This pin supports DrvType change */ + if (pinmux_mask_val & 0x6000) { + /* Change DrvType */ + if (((pinmux_val >> 0x0D) ^ (pinmux_config_val >> 0x0E)) & 0x03) { + pinmux_val |= drvtype_config_val; + } + } + } + + /* Write to the appropriate PINMUX register */ + *((u32 *)pinmux_base_vaddr + pinmux_reg_offset) = pinmux_val; + + /* Do a dummy read from the PINMUX register */ + pinmux_val = *((u32 *)pinmux_base_vaddr + pinmux_reg_offset); + + return pinmux_val; +} + +static const std::tuple g_drivepad_map[] = { + {0x000008E4, 0x01F1F000}, /* AlsProxInt */ + {0x000008E8, 0x01F1F000}, /* ApReady */ + {0x000008EC, 0x01F1F000}, /* ApWakeBt */ + {0x000008F0, 0x01F1F000}, /* ApWakeNfc */ + {0x000008F4, 0x01F1F000}, /* AudMclk */ + {0x000008F8, 0x01F1F000}, /* BattBcl */ + {0x000008FC, 0x01F1F000}, /* BtRst */ + {0x00000900, 0x01F1F000}, /* BtWakeAp */ + {0x00000904, 0x01F1F000}, /* ButtonHome */ + {0x00000908, 0x01F1F000}, /* ButtonPowerOn */ + {0x0000090C, 0x01F1F000}, /* ButtonSlideSw */ + {0x00000910, 0x01F1F000}, /* ButtonVolDown */ + {0x00000914, 0x01F1F000}, /* ButtonVolUp */ + {0x00000918, 0x01F1F000}, /* Cam1Mclk */ + {0x0000091C, 0x01F1F000}, /* Cam1Pwdn */ + {0x00000920, 0x01F1F000}, /* Cam1Strobe */ + {0x00000924, 0x01F1F000}, /* Cam2Mclk */ + {0x00000928, 0x01F1F000}, /* Cam2Pwdn */ + {0x0000092C, 0x01F1F000}, /* CamAfEn */ + {0x00000930, 0x01F1F000}, /* CamFlashEn */ + {0x00000934, 0x01F1F000}, /* CamI2cScl */ + {0x00000938, 0x01F1F000}, /* CamI2cSda */ + {0x0000093C, 0x01F1F000}, /* CamRst */ + {0x00000940, 0x01F1F000}, /* Clk32kIn */ + {0x00000944, 0x01F1F000}, /* Clk32kOut */ + {0x00000948, 0x01F1F000}, /* ClkReq */ + {0x0000094C, 0x01F1F000}, /* CorePwrReq */ + {0x00000950, 0x01F1F000}, /* CpuPwrReq */ + {0x00000954, 0xF0000000}, /* Dap1Din */ + {0x00000958, 0xF0000000}, /* Dap1Dout */ + {0x0000095C, 0xF0000000}, /* Dap1Fs */ + {0x00000960, 0xF0000000}, /* Dap1Sclk */ + {0x00000964, 0xF0000000}, /* Dap2Din */ + {0x00000968, 0xF0000000}, /* Dap2Dout */ + {0x0000096C, 0xF0000000}, /* Dap2Fs */ + {0x00000970, 0xF0000000}, /* Dap2Sclk */ + {0x00000974, 0x01F1F000}, /* Dap4Din */ + {0x00000978, 0x01F1F000}, /* Dap4Dout */ + {0x0000097C, 0x01F1F000}, /* Dap4Fs */ + {0x00000980, 0x01F1F000}, /* Dap4Sclk */ + {0x00000984, 0x01F1F000}, /* Dmic1Clk */ + {0x00000988, 0x01F1F000}, /* Dmic1Dat */ + {0x0000098C, 0x01F1F000}, /* Dmic2Clk */ + {0x00000990, 0x01F1F000}, /* Dmic2Dat */ + {0x00000994, 0x01F1F000}, /* Dmic3Clk */ + {0x00000998, 0x01F1F000}, /* Dmic3Dat */ + {0x0000099C, 0x01F1F000}, /* DpHpd */ + {0x000009A0, 0x01F1F000}, /* DvfsClk */ + {0x000009A4, 0x01F1F000}, /* DvfsPwm */ + {0x000009A8, 0x01F1F000}, /* Gen1I2cScl */ + {0x000009AC, 0x01F1F000}, /* Gen1I2cSda */ + {0x000009B0, 0x01F1F000}, /* Gen2I2cScl */ + {0x000009B4, 0x01F1F000}, /* Gen2I2cSda */ + {0x000009B8, 0x01F1F000}, /* Gen3I2cScl */ + {0x000009BC, 0x01F1F000}, /* Gen3I2cSda */ + {0x000009C0, 0x01F1F000}, /* GpioPa6 */ + {0x000009C4, 0x01F1F000}, /* GpioPcc7 */ + {0x000009C8, 0x01F1F000}, /* GpioPe6 */ + {0x000009CC, 0x01F1F000}, /* GpioPe7 */ + {0x000009D0, 0x01F1F000}, /* GpioPh6 */ + {0x000009D4, 0xF0000000}, /* GpioPk0 */ + {0x000009D8, 0xF0000000}, /* GpioPk1 */ + {0x000009DC, 0xF0000000}, /* GpioPk2 */ + {0x000009E0, 0xF0000000}, /* GpioPk3 */ + {0x000009E4, 0xF0000000}, /* GpioPk4 */ + {0x000009E8, 0xF0000000}, /* GpioPk5 */ + {0x000009EC, 0xF0000000}, /* GpioPk6 */ + {0x000009F0, 0xF0000000}, /* GpioPk7 */ + {0x000009F4, 0xF0000000}, /* GpioPl0 */ + {0x000009F8, 0xF0000000}, /* GpioPl1 */ + {0x000009FC, 0x07F7F000}, /* GpioPz0 */ + {0x00000A00, 0x07F7F000}, /* GpioPz1 */ + {0x00000A04, 0x07F7F000}, /* GpioPz2 */ + {0x00000A08, 0x07F7F000}, /* GpioPz3 */ + {0x00000A0C, 0x07F7F000}, /* GpioPz4 */ + {0x00000A10, 0x07F7F000}, /* GpioPz5 */ + {0x00000A14, 0x01F1F000}, /* GpioX1Aud */ + {0x00000A18, 0x01F1F000}, /* GpioX3Aud */ + {0x00000A1C, 0x01F1F000}, /* GpsEn */ + {0x00000A20, 0x01F1F000}, /* GpsRst */ + {0x00000A24, 0x01F1F000}, /* HdmiCec */ + {0x00000A28, 0x01F1F000}, /* HdmiIntDpHpd */ + {0x00000A2C, 0x01F1F000}, /* JtagRtck */ + {0x00000A30, 0x01F1F000}, /* LcdBlEn */ + {0x00000A34, 0x01F1F000}, /* LcdBlPwm */ + {0x00000A38, 0x01F1F000}, /* LcdGpio1 */ + {0x00000A3C, 0x01F1F000}, /* LcdGpio2 */ + {0x00000A40, 0x01F1F000}, /* LcdRst */ + {0x00000A44, 0x01F1F000}, /* LcdTe */ + {0x00000A48, 0x01F1F000}, /* ModemWakeAp */ + {0x00000A4C, 0x01F1F000}, /* MotionInt */ + {0x00000A50, 0x01F1F000}, /* NfcEn */ + {0x00000A54, 0x01F1F000}, /* NfcInt */ + {0x00000A58, 0x01F1F000}, /* PexL0ClkReqN */ + {0x00000A5C, 0x01F1F000}, /* PexL0RstN */ + {0x00000A60, 0x01F1F000}, /* PexL1ClkreqN */ + {0x00000A64, 0x01F1F000}, /* PexL1RstN */ + {0x00000A68, 0x01F1F000}, /* PexWakeN */ + {0x00000A6C, 0x01F1F000}, /* PwrI2cScl */ + {0x00000A70, 0x01F1F000}, /* PwrI2cSda */ + {0x00000A74, 0x01F1F000}, /* PwrIntN */ + {0x00000A78, 0x07F7F000}, /* QspiComp */ + {0x00000A90, 0xF0000000}, /* QspiSck */ + {0x00000A94, 0x01F1F000}, /* SataLedActive */ + {0x00000A98, 0xF7F7F000}, /* Sdmmc1Pad */ + {0x00000AB0, 0xF7F7F000}, /* Sdmmc3Pad */ + {0x00000AC8, 0x01F1F000}, /* Shutdown */ + {0x00000ACC, 0x01F1F000}, /* SpdifIn */ + {0x00000AD0, 0x01F1F000}, /* SpdifOut */ + {0x00000AD4, 0xF0000000}, /* Spi1Cs0 */ + {0x00000AD8, 0xF0000000}, /* Spi1Cs1 */ + {0x00000ADC, 0xF0000000}, /* Spi1Miso */ + {0x00000AE0, 0xF0000000}, /* Spi1Mosi */ + {0x00000AE4, 0xF0000000}, /* Spi1Sck */ + {0x00000AE8, 0xF0000000}, /* Spi2Cs0 */ + {0x00000AEC, 0xF0000000}, /* Spi2Cs1 */ + {0x00000AF0, 0xF0000000}, /* Spi2Miso */ + {0x00000AF4, 0xF0000000}, /* Spi2Mosi */ + {0x00000AF8, 0xF0000000}, /* Spi2Sck */ + {0x00000AFC, 0xF0000000}, /* Spi4Cs0 */ + {0x00000B00, 0xF0000000}, /* Spi4Miso */ + {0x00000B04, 0xF0000000}, /* Spi4Mosi */ + {0x00000B08, 0xF0000000}, /* Spi4Sck */ + {0x00000B0C, 0x01F1F000}, /* TempAlert */ + {0x00000B10, 0x01F1F000}, /* TouchClk */ + {0x00000B14, 0x01F1F000}, /* TouchInt */ + {0x00000B18, 0x01F1F000}, /* TouchRst */ + {0x00000B1C, 0x01F1F000}, /* Uart1Cts */ + {0x00000B20, 0x01F1F000}, /* Uart1Rts */ + {0x00000B24, 0x01F1F000}, /* Uart1Rx */ + {0x00000B28, 0x01F1F000}, /* Uart1Tx */ + {0x00000B2C, 0x01F1F000}, /* Uart2Cts */ + {0x00000B30, 0x01F1F000}, /* Uart2Rts */ + {0x00000B34, 0x01F1F000}, /* Uart2Rx */ + {0x00000B38, 0x01F1F000}, /* Uart2Tx */ + {0x00000B3C, 0x01F1F000}, /* Uart3Cts */ + {0x00000B40, 0x01F1F000}, /* Uart3Rts */ + {0x00000B44, 0x01F1F000}, /* Uart3Rx */ + {0x00000B48, 0x01F1F000}, /* Uart3Tx */ + {0x00000B4C, 0x01F1F000}, /* Uart4Cts */ + {0x00000B50, 0x01F1F000}, /* Uart4Rts */ + {0x00000B54, 0x01F1F000}, /* Uart4Rx */ + {0x00000B58, 0x01F1F000}, /* Uart4Tx */ + {0x00000B5C, 0x01F1F000}, /* UsbVbusEn0 */ + {0x00000B60, 0x01F1F000}, /* UsbVbusEn1 */ + {0x00000B64, 0x01F1F000}, /* WifiEn */ + {0x00000B68, 0x01F1F000}, /* WifiRst */ + {0x00000B6C, 0x01F1F000}, /* WifiWakeAp */ +}; + int main(int argc, char **argv) { consoleDebugInit(debugDevice_SVC); @@ -506,7 +1316,22 @@ int main(int argc, char **argv) pinmux_update_park(pinmux_base_vaddr, i); } - /* TODO: Set initial PINMUX configuration */ + if ((hardware_type == 0x00) || (hardware_type == 0x02)) { + /* Configure all PINMUX pads (minus BattBcl) for Icosa or Hoag */ + for (unsigned int i = 0; i < (MAX_PINMUX - 1); i++) { + pinmux_update_pad(pinmux_base_vaddr, std::get<0>(g_pinmux_config_map_icosa[i]), std::get<1>(g_pinmux_config_map_icosa[i]), std::get<2>(g_pinmux_config_map_icosa[i])); + } + } else if (hardware_type == 0x01) { + /* Configure all PINMUX pads (minus BattBcl) for Copper */ + for (unsigned int i = 0; i < (MAX_PINMUX - 1); i++) { + pinmux_update_pad(pinmux_base_vaddr, std::get<0>(g_pinmux_config_map_copper[i]), std::get<1>(g_pinmux_config_map_copper[i]), std::get<2>(g_pinmux_config_map_copper[i])); + } + } else if (hardware_type == 0x03) { + /* TODO: Configure PINMUX pads for Mariko */ + } else { + /* Invalid */ + } + /* TODO: Set initial PINMUX drive pad configuration */ /* TODO: Set initial wake pin configuration */