1 /* shared patches for k2 and magpie */
10 #include "usbfifo_api.h"
12 #include "adf_os_io.h"
16 #define USB_EP4_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
17 #define USB_EP3_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
19 extern USB_FIFO_CONFIG usbFifoConf;
20 extern Action eUsbCxFinishAction;
21 extern void _fw_usb_suspend_reboot();
23 typedef void (* USBFIFO_recv_command)(VBUF *cmd);
24 USBFIFO_recv_command m_origUsbfifoRecvCmd = NULL;
26 void _fw_usbfifo_recv_command(VBUF *buf)
31 cmd_data = (uint8_t *)(buf->desc_list->buf_addr +
32 buf->desc_list->data_offset);
33 tmp = *((uint32_t *)cmd_data);
34 if (tmp == 0xFFFFFFFF)
35 _fw_usb_suspend_reboot();
37 m_origUsbfifoRecvCmd(buf);
40 void _fw_usbfifo_init(USB_FIFO_CONFIG *pConfig)
42 m_origUsbfifoRecvCmd = pConfig->recv_command;
44 usbFifoConf.get_command_buf = pConfig->get_command_buf;
45 usbFifoConf.recv_command = _fw_usbfifo_recv_command;
46 usbFifoConf.get_event_buf = pConfig->get_event_buf;
47 usbFifoConf.send_event_done = pConfig->send_event_done;
50 void cold_reboot(void)
52 A_PRINTF("Cold reboot initiated.");
53 #if defined(PROJECT_MAGPIE)
54 iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, 0);
55 #elif defined(PROJECT_K2)
56 iowrite32(MAGPIE_REG_RST_STATUS_ADDR, 0);
57 #endif /* #if defined(PROJECT_MAGPIE) */
62 * support more than 64 bytes command on ep3
64 void usb_status_in_patch(void)
69 static uint16_t buf_len;
70 static VBUF *evntbuf = NULL;
71 static volatile uint32_t *regaddr;
72 static BOOLEAN cmd_is_new = TRUE;
73 BOOLEAN cmd_end = FALSE;
76 evntbuf = usbFifoConf.get_event_buf();
77 if (evntbuf != NULL) {
78 regaddr = (uint32_t *)VBUF_GET_DATA_ADDR(evntbuf);
79 buf_len = evntbuf->buf_length;
81 mUSB_STATUS_IN_INT_DISABLE();
88 if (buf_len > USB_EP3_MAX_PKT_SIZE) {
89 reg_buf_len = USB_EP3_MAX_PKT_SIZE;
90 buf_len -= USB_EP3_MAX_PKT_SIZE;
93 * controller supposed will take care of zero-length? */
95 reg_buf_len = buf_len;
100 for (count = 0; count < (reg_buf_len / 4); count++)
102 iowrite32_usb(ZM_EP3_DATA_OFFSET, *regaddr);
106 remainder = reg_buf_len % 4;
111 iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7);
114 iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3);
117 iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1);
121 iowrite32_usb(ZM_EP3_DATA_OFFSET, *regaddr);
123 /* Restore CBus FIFO size to word size */
124 iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF);
127 mUSB_EP3_XFER_DONE();
129 if (evntbuf != NULL && cmd_end) {
130 usbFifoConf.send_event_done(evntbuf);
136 * support more than 64 bytes command on ep4
138 void usb_reg_out_patch(void)
143 static volatile uint32_t *regaddr;
144 static uint16_t cmd_len;
146 BOOLEAN cmd_is_last = FALSE;
147 static BOOLEAN cmd_is_new = TRUE;
149 /* get the size of this transcation */
150 usbfifolen = ioread8_usb(ZM_EP4_BYTE_COUNT_LOW_OFFSET);
152 if (usbfifolen > USB_EP4_MAX_PKT_SIZE) {
153 A_PRINTF("EP4 FIFO Bug? Buffer is too big: %x\n", usbfifolen);
157 /* check is command is new */
160 buf = usbFifoConf.get_command_buf();
164 A_PRINTF("%s: Filed to get new buffer.\n", __func__);
168 /* copy free, assignment buffer of the address */
169 regaddr = (uint32_t *)buf->desc_list->buf_addr;
174 /* just in case, suppose should not happen */
178 /* if size is smaller, this is the last command!
179 * zero-length supposed should be set through 0x27/bit7->0x19/bit4, not here
181 if(usbfifolen < USB_EP4_MAX_PKT_SIZE)
184 /* accumulate the size */
185 cmd_len += usbfifolen;
187 if (cmd_len > buf->desc_list->buf_size) {
188 A_PRINTF("%s: Data length on EP4 FIFO is bigger as "
189 "allocated buffer data! Drop it!\n", __func__);
193 /* round it to alignment */
195 usbfifolen = (usbfifolen >> 2) + 1;
197 usbfifolen = usbfifolen >> 2;
199 /* retrieve the data from fifo */
200 for(ii = 0; ii < usbfifolen; ii++) {
201 /* read fifo data out */
202 ep4_data = ioread32_usb(ZM_EP4_DATA_OFFSET);
207 /* if this is the last command, callback to HTC */
209 buf->desc_list->next_desc = NULL;
210 buf->desc_list->data_offset = 0;
211 buf->desc_list->data_size = cmd_len;
212 buf->desc_list->control = 0;
213 buf->next_buf = NULL;
214 buf->buf_length = cmd_len;
216 usbFifoConf.recv_command(buf);
223 /* we might get no command buffer here?
224 * but if we return here, the ep4 fifo will be lock out,
225 * so that we still read them out but just drop it? */
226 for(ii = 0; ii < usbfifolen; ii++)
227 ep4_data = ioread32_usb(ZM_EP4_DATA_OFFSET);
230 /* mUSB_STATUS_IN_INT_ENABLE(); */
237 * - theoretically ep6 configured same way as ep1
238 * so, if there are some problems we should have it
240 * - do we really need support usb1.1?
242 extern uint16_t u8UsbConfigValue;
243 extern uint16_t u8UsbInterfaceValue;
244 extern uint16_t u8UsbInterfaceAlternateSetting;
245 extern SetupPacket ControlCmd;
246 extern void vUsbClrEPx(void);
248 #undef FS_C1_I0_A0_EP_NUMBER
249 #define FS_C1_I0_A0_EP_NUMBER 6
251 #define FS_C1_I0_A0_EP6_BLKSIZE BLK512BYTE
252 #define FS_C1_I0_A0_EP6_BLKNO DOUBLE_BLK
253 #define FS_C1_I0_A0_EP6_DIRECTION DIRECTION_OUT
254 #define FS_C1_I0_A0_EP6_TYPE TF_TYPE_BULK
255 #define FS_C1_I0_A0_EP6_MAX_PACKET 0x0040
256 #define FS_C1_I0_A0_EP6_bInterval 0
259 #define FS_C1_I0_A0_EP6_FIFO_START \
260 (FS_C1_I0_A0_EP5_FIFO_START + FS_C1_I0_A0_EP5_FIFO_NO)
261 #define FS_C1_I0_A0_EP6_FIFO_NO \
262 (FS_C1_I0_A0_EP6_BLKNO * FS_C1_I0_A0_EP6_BLKSIZE)
263 #define FS_C1_I0_A0_EP6_FIFO_CONFIG \
264 (0x80 | ((FS_C1_I0_A0_EP6_BLKSIZE - 1) << 4) | \
265 ((FS_C1_I0_A0_EP6_BLKNO - 1) << 2) | FS_C1_I0_A0_EP6_TYPE)
266 #define FS_C1_I0_A0_EP6_FIFO_MAP \
267 (((1 - FS_C1_I0_A0_EP6_DIRECTION) << 4) | EP6)
268 #define FS_C1_I0_A0_EP6_MAP \
269 (FS_C1_I0_A0_EP6_FIFO_START | (FS_C1_I0_A0_EP6_FIFO_START << 4) | \
270 (MASK_F0 >> (4*FS_C1_I0_A0_EP6_DIRECTION)))
272 void vUSBFIFO_EP6Cfg_FS_patch(void)
274 #if (FS_C1_I0_A0_EP_NUMBER >= 6)
278 mUsbEPMap(EP6, FS_C1_I0_A0_EP6_MAP);
279 mUsbFIFOMap(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_MAP);
280 mUsbFIFOConfig(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_CONFIG);
282 for(i = FS_C1_I0_A0_EP6_FIFO_START + 1 ;
283 i < FS_C1_I0_A0_EP6_FIFO_START + FS_C1_I0_A0_EP6_FIFO_NO ; i ++)
285 mUsbFIFOConfig(i, (FS_C1_I0_A0_EP6_FIFO_CONFIG & (~BIT7)) );
288 mUsbEPMxPtSzHigh(EP6, FS_C1_I0_A0_EP6_DIRECTION,
289 (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
290 mUsbEPMxPtSzLow(EP6, FS_C1_I0_A0_EP6_DIRECTION,
291 (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
292 mUsbEPinHighBandSet(EP6, FS_C1_I0_A0_EP6_DIRECTION,
293 FS_C1_I0_A0_EP6_MAX_PACKET);
297 void vUsbFIFO_EPxCfg_FS_patch(void)
299 switch (u8UsbConfigValue)
301 #if (FS_CONFIGURATION_NUMBER >= 1)
302 /* Configuration 0X01 */
304 switch (u8UsbInterfaceValue)
306 #if (FS_C1_INTERFACE_NUMBER >= 1)
309 switch (u8UsbInterfaceAlternateSetting)
312 #if (FS_C1_I0_ALT_NUMBER >= 1)
313 /* AlternateSetting 0 */
318 /* patch up this ep6_fs config */
319 vUSBFIFO_EP6Cfg_FS_patch();
337 /* mCHECK_STACK(); */
340 BOOLEAN bSet_configuration_patch(void)
342 /* do some defaul configuration */
343 bSet_configuration();
345 /* overwrite defaul FIFO configuration for FullSpeed USB */
346 if ((mLOW_BYTE(mDEV_REQ_VALUE()) != 0) && !mUsbHighSpeedST())
347 vUsbFIFO_EPxCfg_FS_patch();
349 eUsbCxFinishAction = ACT_DONE;
353 extern BOOLEAN bStandardCommand(void);
355 BOOLEAN bStandardCommand_patch(void)
357 if (mDEV_REQ_REQ() == USB_SET_CONFIGURATION) {
360 #if ENABLE_SWAP_DATA_MODE
361 /* SWAP FUNCTION should be enabled while DMA engine
362 * is not working, the best place to enable it
363 * is before we trigger the DMA */
364 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
365 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
367 #if SYSTEM_MODULE_HP_EP5
368 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
371 #if SYSTEM_MODULE_HP_EP6
372 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
375 #endif /* ENABLE_SWAP_DATA_MODE */
378 return bStandardCommand();
382 * usb descriptor patch
385 extern uint16_t *u8ConfigDescriptorEX;
386 extern uint16_t *pu8DescriptorEX;
387 extern uint16_t u16TxRxCounter;
388 extern SetupPacket ControlCmd;
389 extern uint16_t *u8UsbDeviceDescriptor;
390 extern BOOLEAN bGet_descriptor(void);
392 uint16_t ConfigDescriptorPatch[30];
393 uint16_t UsbDeviceDescriptorPatch[9];
395 #define BCD_DEVICE_OFFSET 6
396 #define BCD_DEVICE_FW_SIGNATURE 0xffff
397 #define VENDOR_ID_OFFSET 4
398 #define PRODUCT_ID_OFFSET 5
400 #define EP3_TRANSFER_TYPE_OFFSET 17
401 #define EP3_INT_INTERVAL 19
402 #define EP4_TRANSFER_TYPE_OFFSET 21
403 #define EP4_INT_INTERVAL 22
405 BOOLEAN bGet_descriptor_patch(void)
407 if (mDEV_REQ_VALUE_HIGH() == 1)
409 uint8_t *p = (uint8_t *)u8UsbDeviceDescriptor;
411 /* Copy Usb Device Descriptor */
412 ath_hal_memcpy(UsbDeviceDescriptorPatch, p,
413 sizeof(UsbDeviceDescriptorPatch));
415 /* Change bcdDevice. we need it to detect if FW
417 UsbDeviceDescriptorPatch[BCD_DEVICE_OFFSET] =
418 BCD_DEVICE_FW_SIGNATURE;
420 pu8DescriptorEX = UsbDeviceDescriptorPatch;
421 u16TxRxCounter = mTABLE_LEN(u8UsbDeviceDescriptor[0]);
423 if (u16TxRxCounter > mDEV_REQ_LENGTH())
424 u16TxRxCounter = mDEV_REQ_LENGTH();
429 } else if (mDEV_REQ_VALUE_HIGH() == 2) {
430 uint8_t *p = (uint8_t *)u8ConfigDescriptorEX;
432 /* Copy ConfigDescriptor */
433 ath_hal_memcpy(ConfigDescriptorPatch, p,
434 sizeof(ConfigDescriptorPatch));
436 /* place holder for EPx patches */
438 if (mDEV_REQ_VALUE_LOW() == 0) {
439 /* configuration no: 0 */
440 pu8DescriptorEX = ConfigDescriptorPatch;
441 u16TxRxCounter = ConfigDescriptorPatch[1];
445 if (u16TxRxCounter > mDEV_REQ_LENGTH())
446 u16TxRxCounter = mDEV_REQ_LENGTH();
451 return bGet_descriptor();