/* * ------------------------------------------------------------------ Copyright (c) 2023 by Lattice Semiconductor Corporation ALL RIGHTS RESERVED ------------------------------------------------------------------ DISCLAIMER: LATTICE MAKES NO WARRANTIES ON THIS FILE OR ITS CONTENTS, WHETHER EXPRESSED, IMPLIED, STATUTORY, OR IN ANY PROVISION OF THE LATTICE PROPEL LICENSE AGREEMENT OR COMMUNICATION WITH LICENSEE, AND LATTICE SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. LATTICE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED HEREIN WILL MEET LICENSEE 'S REQUIREMENTS, OR THAT LICENSEE' S OPERATION OF ANY DEVICE, SOFTWARE OR SYSTEM USING THIS FILE OR ITS CONTENTS WILL BE UNINTERRUPTED OR ERROR FREE, OR THAT DEFECTS HEREIN WILL BE CORRECTED. LICENSEE ASSUMES RESPONSIBILITY FOR SELECTION OF MATERIALS TO ACHIEVE ITS INTENDED RESULTS, AND FOR THE PROPER INSTALLATION, USE, AND RESULTS OBTAINED THEREFROM. LICENSEE ASSUMES THE ENTIRE RISK OF THE FILE AND ITS CONTENTS PROVING DEFECTIVE OR FAILING TO PERFORM PROPERLY AND IN SUCH EVENT, LICENSEE SHALL ASSUME THE ENTIRE COST AND RISK OF ANY REPAIR, SERVICE, CORRECTION, OR ANY OTHER LIABILITIES OR DAMAGES CAUSED BY OR ASSOCIATED WITH THE SOFTWARE. IN NO EVENT SHALL LATTICE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS FILE OR ITS CONTENTS, EVEN IF LATTICE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. LATTICE 'S SOLE LIABILITY, AND LICENSEE' S SOLE REMEDY, IS SET FORTH ABOVE. LATTICE DOES NOT WARRANT OR REPRESENT THAT THIS FILE, ITS CONTENTS OR USE THEREOF DOES NOT INFRINGE ON THIRD PARTIES' INTELLECTUAL PROPERTY RIGHTS, INCLUDING ANY PATENT. IT IS THE USER' S RESPONSIBILITY TO VERIFY THE USER SOFTWARE DESIGN FOR CONSISTENCY AND FUNCTIONALITY THROUGH THE USE OF FORMAL SOFTWARE VALIDATION METHODS. ------------------------------------------------------------------ * */ #include "device_soft_rst.h" uint32_t g_simulation_enable; int device_power_on_soft_rst(void) { /* * DCTL Default value taken from hardware */ DCTL_data *dctl = dctl_setup(); /* * LPM NYET Response Threshold. */ dctl->LPM_NYET_thres = 0xf; /* * This bit clears the interrupts and all the CSRs except GSTS, GSNPSID, * GGPIO, GUID, GUSB2PHYCFGn registers, GUSB3PIPECTLn registers, DCFG, * DCTL, DEVTEN, and DSTS registers. */ dctl->CSFTRST = 1; if(dctl_write() != 0) { return -12; } if(dctl_read()!=0) { return -16; } /* * Wait until the hardware pull dctl.CSFTRST down. * This resets the device controller. */ while(dctl->CSFTRST != 0) { dctl_read(); } /* * Global Event Buffer Address (Low) Register. Holds the lower 32 bits of * start address of the external memory for the Event Buffer. * During operation, hardware does not update this address. * Global Event Buffer Address (High) Register.Holds the higher 32 bits of * start address of the external memory for the Event Buffer. * During operation, hardware does not update this address. */ uint64_t evnt_address = EVENT_FIFO_ADDR_USB23; uint32_t dev_number = 0; //this number is zero in device mode if(gevntadr_init(dev_number, evnt_address) != 0) { return -2; } if(gevntadr_get(dev_number, &evnt_address) != 0) { return -3; } if(evnt_address != EVENT_FIFO_ADDR_USB23) { return -4; } /* * Event Buffer Size in bytes (EVNTSiz) Holds the size of the Event Buffer * in bytes must be a multiple of four. * This is programmed by software once during initialization. * The minimum size of the event buffer is 32 bytes */ uint32_t event_size = EVENT_FIFO_SIZE; uint32_t gevntsiz_dev_number = 0; uint32_t event_intr_mask = 0; //interrupt is enabled if(gevntsiz_init(gevntsiz_dev_number, event_size, event_intr_mask) != 0) { return -5; } if(gevntsiz_get(gevntsiz_dev_number,&event_size,&event_intr_mask) != 0) { return -6; } if(event_size != EVENT_FIFO_SIZE) { return -7; } /* * This register holds the number of valid bytes in the Event Buffer */ uint32_t event_count = 0x0; uint32_t gevntcount_dev_number = 0; uint32_t event_hndlr_busy = 0; if(gevntcount_init(gevntcount_dev_number, event_count,event_hndlr_busy) != 0) { return -8; } if(gevntcount_get(gevntcount_dev_number, &event_count,&event_hndlr_busy) != 0) { return -9; } if(event_count != 0) { return -10; } /* * Simulation Speed Up Factor. Program this register (GCTL) to * override scaledown. */ GCTL_data *gctl = gctl_setup(); /* * Table 1-17, Link waits for 8us of LFPS before it detects a valid * U2 Exit. */ gctl->U2EXIT_LFPS = 0x1; /* * Table 1-17, * Port capability direction for device configuration. */ gctl->PRTCAPDIR = 0x2; /* * Table 1-17 * If this bit is set, then device attempts three more times to * connect at SS, even if it previously failed to operate in SS * mode. For each attempt, the device checks receiver * termination eight times. */ gctl->U2RSTECN = 0x1; /* * Table 1-17, * More info from PWERDNSCALE from the document. */ gctl->PWRDNSCALE = 0x0618; if(g_simulation_enable) { if(g_usb_speed == 0x4) { /* * RAM Clock Select (RAMClkSel) : pipe clock */ gctl->RAMCLKSEL = 0x01; /* * Table 1-17, Enables scale-down of all timing values except * Device mode suspend and resume. These include Speed * enumeration, HNP/SRP, and Host mode suspend and * resume. */ gctl->SCALEDOWN = 0x03;//0x02 } else { /* * Table 1-17, Enables scale-down of all timing values except * Device mode suspend and resume. These include Speed * enumeration, HNP/SRP, and Host mode suspend and * resume. */ gctl->SCALEDOWN = 0x03;//0x01 } } else { gctl->SCALEDOWN = 0x0; /* * RAM Clock Select (RAMClkSel) : pipe clock */ gctl->RAMCLKSEL = 0x0; } if(gctl_write() != 0) { return -11; } /* * Program device speed [2:0] bits and periodic frame interval * DCFG.DEVSPD=3'b000: High-speed * DCFG.DEVSPD=3'b001: Full-speed * DCFG.DEVSPD=3'b100: Super-speed */ DCFG_data *dcfg = dcfg_setup(); dcfg ->DEVSPD = (g_usb_speed & 0x7); /**@todo why reserved bit are set, ask FPGA team.*/ dcfg ->reserved_11_10 = 0x2; /* * Refer Table number 1-78 for more information. */ dcfg ->NUMP = 0x4; if(dcfg_write() != 0) { return -13; } /* * At a minimum, enable USB Reset, Connection Done, * and USB/Link State Change events (DEVTEN) */ DEVTEN_data *devten = devten_setup(); devten ->DISSCONNEVTEN = 0x1; devten ->USBRSTEVTEN = 0x1; devten ->CONNECTDONEEVTEN = 0x1; devten->ULSTCNGEN = 0x1; if(devten_write() != 0) { return -14; } if(DEPSTARTCFG_cmd(0x0) != 0) { return -15; } DEPCFG_Par1 DEPCFG_Par1_EP0 = {0}; DEPCFG_Par1_EP0.event_enable_mask = 0x5; DEPCFG_Par0 DEPCFG_Par0_EP0 = {0}; if(g_usb_speed == super_speed_usb) { DEPCFG_Par0_EP0.maximum_packet_size = 0x200; } else { DEPCFG_Par0_EP0.maximum_packet_size = 0x040; } if(DEPCFG_cmd(0x0, 0x00000000,&DEPCFG_Par1_EP0,&DEPCFG_Par0_EP0)!=0) { return -19; } DEPCFG_Par1 DEPCFG_Par1_EP1 = {0}; DEPCFG_Par1_EP1.USB_ep_dir = 0x1; DEPCFG_Par1_EP1.event_enable_mask = 0x5; DEPCFG_Par0 DEPCFG_Par0_EP1 = {0}; if(g_usb_speed == super_speed_usb) { DEPCFG_Par0_EP1.maximum_packet_size = 0x200; } else { DEPCFG_Par0_EP1.maximum_packet_size = 0x40; } if(DEPCFG_cmd(0x1, 0x00000000,&DEPCFG_Par1_EP1,&DEPCFG_Par0_EP1) != 0) { return -20; } if(DEPXFERCFG_cmd(0x0) != 0) { return -21; } if(DEPXFERCFG_cmd(0x1) != 0) { return -22; } /* * Prepare a buffer for a setup packet, initialize a setup TRB. */ if(TRB_control_setup() != 0) { return -23; } /* * Write DALEPENA.Enable physical endpoints 0 & 1 by writing 0x3 to * this register. */ DALEPENA_data *dalepena_data = dalepena_setup(); dalepena_data ->USBACTEP = 0x00000003; if(dalepena_write()!=0) { return -17; } /** * @todo unknown registers and values to be provided by FPGA team. */ uint32_t *unknown_reg = reg_setup(0x402b << 2); *unknown_reg = 0x020E4500; if( ltcusb_raw_write() != 0) { return -24; } /* * Write DCTL.Set DCTL.RunStop to ‘1’ to allow the device to attach * to the host. */ DCTL_data *dctl_data = dctl_setup(); dctl_data->LPM_NYET_thres = 0xf; dctl_data->RUN_STOP = 0x1; if(dctl_write()!=0) { return -18; } /** * @todo unknown registers and values to be provided by FPGA team. */ unknown_reg = reg_setup(0x4023 << 2); *unknown_reg = 0x90940001; if( ltcusb_raw_write() != 0) { return -25; } return 0; }