3838/* BAR0 registers */
3939#define ASMT_REG_ADDR 0x3000
4040
41- #define ASMT_REG_DATA 0x3004
41+ #define ASMT_REG_WDATA 0x3004
42+ #define ASMT_REG_RDATA 0x3008
4243
4344#define ASMT_REG_STATUS 0x3009
4445#define ASMT_REG_STATUS_BUSY BIT(7)
4546
46- #define ASMT_REG_WDATA 0x3010
47- #define ASMT_REG_RDATA 0x3018
47+ #define ASMT_REG_CODE_WDATA 0x3010
48+ #define ASMT_REG_CODE_RDATA 0x3018
49+
50+ #define ASMT_MMIO_CPU_MISC 0x500e
51+ #define ASMT_MMIO_CPU_MISC_CODE_RAM_WR BIT(0)
52+
53+ #define ASMT_MMIO_CPU_MODE_NEXT 0x5040
54+ #define ASMT_MMIO_CPU_MODE_CUR 0x5041
55+
56+ #define ASMT_MMIO_CPU_MODE_RAM BIT(0)
57+ #define ASMT_MMIO_CPU_MODE_HALFSPEED BIT(1)
58+
59+ #define ASMT_MMIO_CPU_EXEC_CTRL 0x5042
60+ #define ASMT_MMIO_CPU_EXEC_CTRL_RESET BIT(0)
61+ #define ASMT_MMIO_CPU_EXEC_CTRL_HALT BIT(1)
4862
4963#define TIMEOUT_USEC 10000
5064#define RESET_TIMEOUT_USEC 500000
@@ -178,11 +192,41 @@ static int asmedia_wait_reset(struct pci_dev *pdev)
178192 return ret ;
179193}
180194
181- static void asmedia_write_reg (struct usb_hcd * hcd , u16 addr , u8 data ) {
195+ static u8 asmedia_read_reg (struct usb_hcd * hcd , u16 addr ) {
182196 void __iomem * regs = hcd -> regs ;
183197 u8 status ;
184198 int ret ;
185199
200+ ret = readb_poll_timeout (regs + ASMT_REG_STATUS ,
201+ status , !(status & ASMT_REG_STATUS_BUSY ),
202+ 1000 , TIMEOUT_USEC );
203+
204+ if (ret ) {
205+ dev_err (hcd -> self .controller ,
206+ "Read reg wait timed out ([%04x])\n" , addr );
207+ return ~0 ;
208+ }
209+
210+ writew_relaxed (addr , regs + ASMT_REG_ADDR );
211+
212+ ret = readb_poll_timeout (regs + ASMT_REG_STATUS ,
213+ status , !(status & ASMT_REG_STATUS_BUSY ),
214+ 1000 , TIMEOUT_USEC );
215+
216+ if (ret ) {
217+ dev_err (hcd -> self .controller ,
218+ "Read reg addr timed out ([%04x])\n" , addr );
219+ return ~0 ;
220+ }
221+
222+ return readb_relaxed (regs + ASMT_REG_RDATA );
223+ }
224+
225+ static void asmedia_write_reg (struct usb_hcd * hcd , u16 addr , u8 data , bool wait ) {
226+ void __iomem * regs = hcd -> regs ;
227+ u8 status ;
228+ int ret , i ;
229+
186230 writew_relaxed (addr , regs + ASMT_REG_ADDR );
187231
188232 ret = readb_poll_timeout (regs + ASMT_REG_STATUS ,
@@ -191,44 +235,66 @@ static void asmedia_write_reg(struct usb_hcd *hcd, u16 addr, u8 data) {
191235
192236 if (ret )
193237 dev_err (hcd -> self .controller ,
194- "Write addr timed out ([%04x] = %02x)\n" ,
238+ "Write reg addr timed out ([%04x] = %02x)\n" ,
195239 addr , data );
196240
197- writeb_relaxed (data , regs + ASMT_REG_DATA );
241+ writeb_relaxed (data , regs + ASMT_REG_WDATA );
198242
199243 ret = readb_poll_timeout (regs + ASMT_REG_STATUS ,
200244 status , !(status & ASMT_REG_STATUS_BUSY ),
201245 1000 , TIMEOUT_USEC );
202246
203247 if (ret )
204248 dev_err (hcd -> self .controller ,
205- "Write data timed out ([%04x] = %02x)\n" ,
249+ "Write reg data timed out ([%04x] = %02x)\n" ,
250+ addr , data );
251+
252+ if (!wait )
253+ return ;
254+
255+ for (i = 0 ; i < TIMEOUT_USEC ; i ++ ) {
256+ if (asmedia_read_reg (hcd , addr ) == data )
257+ break ;
258+ }
259+
260+ if (i >= TIMEOUT_USEC ) {
261+ dev_err (hcd -> self .controller ,
262+ "Verify register timed out ([%04x] = %02x)\n" ,
206263 addr , data );
264+ }
207265}
208266
209267static int asmedia_load_fw (struct pci_dev * pdev , const struct firmware * fw )
210268{
211269 struct usb_hcd * hcd ;
212270 void __iomem * regs ;
213271 const u16 * fw_data = (const u16 * )fw -> data ;
272+ u16 raddr ;
214273 u32 data ;
215274 size_t index = 0 , addr = 0 ;
216275 size_t words = fw -> size >> 1 ;
217- int ret ;
276+ int ret , i ;
218277
219278 hcd = dev_get_drvdata (& pdev -> dev );
220279 regs = hcd -> regs ;
221280
222- asmedia_write_reg (hcd , 0x5040 , 2 );
223- asmedia_write_reg (hcd , 0x5042 , 1 );
281+ asmedia_write_reg (hcd , ASMT_MMIO_CPU_MODE_NEXT ,
282+ ASMT_MMIO_CPU_MODE_HALFSPEED , false);
283+
284+ asmedia_write_reg (hcd , ASMT_MMIO_CPU_EXEC_CTRL ,
285+ ASMT_MMIO_CPU_EXEC_CTRL_RESET , false);
224286
225287 ret = asmedia_wait_reset (pdev );
226288 if (ret ) {
227289 dev_err (hcd -> self .controller , "Failed pre-upload reset\n" );
228290 return ret ;
229291 }
230292
231- asmedia_write_reg (hcd , 0x500e , 1 );
293+ asmedia_write_reg (hcd , ASMT_MMIO_CPU_EXEC_CTRL ,
294+ ASMT_MMIO_CPU_EXEC_CTRL_HALT , false);
295+
296+ asmedia_write_reg (hcd , ASMT_MMIO_CPU_MISC ,
297+ ASMT_MMIO_CPU_MISC_CODE_RAM_WR , true);
232298
233299 pci_write_config_byte (pdev , ASMT_CFG_SRAM_ACCESS ,
234300 ASMT_CFG_SRAM_ACCESS_ENABLE );
@@ -243,18 +309,34 @@ static int asmedia_load_fw(struct pci_dev *pdev, const struct firmware *fw)
243309 pci_write_config_word (pdev , ASMT_CFG_SRAM_ADDR ,
244310 addr );
245311
246- writel_relaxed (data , regs + ASMT_REG_WDATA );
312+ writel_relaxed (data , regs + ASMT_REG_CODE_WDATA );
313+
314+ for (i = 0 ; i < TIMEOUT_USEC ; i ++ ) {
315+ pci_read_config_word (pdev , ASMT_CFG_SRAM_ADDR , & raddr );
316+ if (raddr != addr )
317+ break ;
318+ udelay (1 );
319+ }
320+
321+ if (raddr == addr ) {
322+ dev_err (hcd -> self .controller , "Word write timed out\n" );
323+ return - ETIMEDOUT ;
324+ }
247325
248326 if (++ index & 0x4000 )
249327 index += 0x4000 ;
250328 addr += 2 ;
251329 }
252330
253- asmedia_write_reg (hcd , 0x5040 , 3 );
254-
255331 pci_write_config_byte (pdev , ASMT_CFG_SRAM_ACCESS , 0 );
256332
257- asmedia_write_reg (hcd , 0x500e , 0 );
333+ asmedia_write_reg (hcd , ASMT_MMIO_CPU_MISC , 0 , true);
334+
335+ asmedia_write_reg (hcd , ASMT_MMIO_CPU_MODE_NEXT ,
336+ ASMT_MMIO_CPU_MODE_RAM |
337+ ASMT_MMIO_CPU_MODE_HALFSPEED , false);
338+
339+ asmedia_write_reg (hcd , ASMT_MMIO_CPU_EXEC_CTRL , 0 , false);
258340
259341 ret = asmedia_wait_reset (pdev );
260342 if (ret ) {
0 commit comments