Commit c580d92b0e7da1277c0ea9934a9bf8335dbbf46e
1 parent
eae473c1
Fill in WLAN and BT platform data in CAL area as expected by Maemo.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4968 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
52 additions
and
6 deletions
hw/flash.h
| ... | ... | @@ -39,6 +39,7 @@ uint8_t nand_getio(struct nand_flash_s *s); |
| 39 | 39 | void onenand_base_update(void *opaque, target_phys_addr_t new); |
| 40 | 40 | void onenand_base_unmap(void *opaque); |
| 41 | 41 | void *onenand_init(uint32_t id, int regshift, qemu_irq irq); |
| 42 | +void *onenand_raw_otp(void *opaque); | |
| 42 | 43 | |
| 43 | 44 | /* ecc.c */ |
| 44 | 45 | struct ecc_state_s { | ... | ... |
hw/nseries.c
| ... | ... | @@ -50,6 +50,7 @@ struct n800_s { |
| 50 | 50 | struct tusb_s *usb; |
| 51 | 51 | void *retu; |
| 52 | 52 | void *tahvo; |
| 53 | + void *nand; | |
| 53 | 54 | }; |
| 54 | 55 | |
| 55 | 56 | /* GPIO pins */ |
| ... | ... | @@ -101,6 +102,7 @@ struct n800_s { |
| 101 | 102 | #define N8X0_TMP105_GPIO 125 |
| 102 | 103 | |
| 103 | 104 | /* Config */ |
| 105 | +#define BT_UART 0 | |
| 104 | 106 | #define XLDR_LL_UART 1 |
| 105 | 107 | |
| 106 | 108 | /* Addresses on the I2C bus 0 */ |
| ... | ... | @@ -118,6 +120,12 @@ struct n800_s { |
| 118 | 120 | #define N8X0_USB_ASYNC_CS 1 |
| 119 | 121 | #define N8X0_USB_SYNC_CS 4 |
| 120 | 122 | |
| 123 | +#define N8X0_BD_ADDR 0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81 | |
| 124 | + | |
| 125 | +typedef struct { | |
| 126 | + uint8_t b[6]; | |
| 127 | +} __attribute__((packed)) bdaddr_t; /* XXX: move to BT headers */ | |
| 128 | + | |
| 121 | 129 | static void n800_mmc_cs_cb(void *opaque, int line, int level) |
| 122 | 130 | { |
| 123 | 131 | /* TODO: this seems to actually be connected to the menelaus, to |
| ... | ... | @@ -135,14 +143,42 @@ static void n8x0_gpio_setup(struct n800_s *s) |
| 135 | 143 | qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]); |
| 136 | 144 | } |
| 137 | 145 | |
| 146 | +#define MAEMO_CAL_HEADER(...) \ | |
| 147 | + 'C', 'o', 'n', 'F', 0x02, 0x00, 0x04, 0x00, \ | |
| 148 | + __VA_ARGS__, \ | |
| 149 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 150 | + | |
| 151 | +static const uint8_t n8x0_cal_wlan_mac[] = { | |
| 152 | + MAEMO_CAL_HEADER('w', 'l', 'a', 'n', '-', 'm', 'a', 'c') | |
| 153 | + 0x1c, 0x00, 0x00, 0x00, 0x47, 0xd6, 0x69, 0xb3, | |
| 154 | + 0x30, 0x08, 0xa0, 0x83, 0x00, 0x00, 0x00, 0x00, | |
| 155 | + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, | |
| 156 | + 0x89, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, | |
| 157 | + 0x5d, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, | |
| 158 | +}; | |
| 159 | + | |
| 160 | +static const uint8_t n8x0_cal_bt_id[] = { | |
| 161 | + MAEMO_CAL_HEADER('b', 't', '-', 'i', 'd', 0, 0, 0) | |
| 162 | + 0x0a, 0x00, 0x00, 0x00, 0xa3, 0x4b, 0xf6, 0x96, | |
| 163 | + 0xa8, 0xeb, 0xb2, 0x41, 0x00, 0x00, 0x00, 0x00, | |
| 164 | + N8X0_BD_ADDR, | |
| 165 | +}; | |
| 166 | + | |
| 138 | 167 | static void n8x0_nand_setup(struct n800_s *s) |
| 139 | 168 | { |
| 169 | + char *otp_region; | |
| 170 | + | |
| 140 | 171 | /* Either ec40xx or ec48xx are OK for the ID */ |
| 141 | 172 | omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update, |
| 142 | 173 | onenand_base_unmap, |
| 143 | - onenand_init(0xec4800, 1, | |
| 144 | - omap2_gpio_in_get(s->cpu->gpif, | |
| 145 | - N8X0_ONENAND_GPIO)[0])); | |
| 174 | + (s->nand = onenand_init(0xec4800, 1, | |
| 175 | + omap2_gpio_in_get(s->cpu->gpif, | |
| 176 | + N8X0_ONENAND_GPIO)[0]))); | |
| 177 | + otp_region = onenand_raw_otp(s->nand); | |
| 178 | + | |
| 179 | + memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac)); | |
| 180 | + memcpy(otp_region + 0x800, n8x0_cal_bt_id, sizeof(n8x0_cal_bt_id)); | |
| 181 | + /* XXX: in theory should also update the OOB for both pages */ | |
| 146 | 182 | } |
| 147 | 183 | |
| 148 | 184 | static void n8x0_i2c_setup(struct n800_s *s) |
| ... | ... | @@ -1048,6 +1084,8 @@ static struct omap_partition_info_s { |
| 1048 | 1084 | { 0, 0, 0, 0 } |
| 1049 | 1085 | }; |
| 1050 | 1086 | |
| 1087 | +static bdaddr_t n8x0_bd_addr = {{ N8X0_BD_ADDR }}; | |
| 1088 | + | |
| 1051 | 1089 | static int n8x0_atag_setup(void *p, int model) |
| 1052 | 1090 | { |
| 1053 | 1091 | uint8_t *b; |
| ... | ... | @@ -1067,7 +1105,7 @@ static int n8x0_atag_setup(void *p, int model) |
| 1067 | 1105 | #if 0 |
| 1068 | 1106 | stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */ |
| 1069 | 1107 | stw_raw(w ++, 4); /* u16 len */ |
| 1070 | - stw_raw(w ++, XLDR_LL_UART); /* u8 console_uart */ | |
| 1108 | + stw_raw(w ++, XLDR_LL_UART + 1); /* u8 console_uart */ | |
| 1071 | 1109 | stw_raw(w ++, 115200); /* u32 console_speed */ |
| 1072 | 1110 | #endif |
| 1073 | 1111 | |
| ... | ... | @@ -1111,8 +1149,8 @@ static int n8x0_atag_setup(void *p, int model) |
| 1111 | 1149 | stb_raw(b ++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */ |
| 1112 | 1150 | stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */ |
| 1113 | 1151 | stb_raw(b ++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */ |
| 1114 | - stb_raw(b ++, 1); /* u8 bt_uart */ | |
| 1115 | - memset(b, 0, 6); /* u8 bd_addr[6] */ | |
| 1152 | + stb_raw(b ++, BT_UART + 1); /* u8 bt_uart */ | |
| 1153 | + memcpy(b, &n8x0_bd_addr, 6); /* u8 bd_addr[6] */ | |
| 1116 | 1154 | b += 6; |
| 1117 | 1155 | stb_raw(b ++, 0x02); /* u8 bt_sysclk (38.4) */ |
| 1118 | 1156 | w = (void *) b; | ... | ... |
hw/onenand.c