diff options
Diffstat (limited to 'packages/mamona/cx3110x-770he-0.8.1/770_performance_improvements.patch')
-rw-r--r-- | packages/mamona/cx3110x-770he-0.8.1/770_performance_improvements.patch | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/packages/mamona/cx3110x-770he-0.8.1/770_performance_improvements.patch b/packages/mamona/cx3110x-770he-0.8.1/770_performance_improvements.patch new file mode 100644 index 0000000000..be9be86b82 --- /dev/null +++ b/packages/mamona/cx3110x-770he-0.8.1/770_performance_improvements.patch @@ -0,0 +1,307 @@ +Index: cx3110x-0.8.1/src/sm_drv_spi.c +=================================================================== +--- cx3110x-0.8.1.orig/src/sm_drv_spi.c 2008-04-28 18:30:22.000000000 -0300 ++++ cx3110x-0.8.1/src/sm_drv_spi.c 2008-04-28 18:30:25.000000000 -0300 +@@ -99,10 +99,10 @@ + struct net_local *lp = dev->priv; + uint32_t host_ints, host_ints_ack, target_ints; + unsigned long timeout; +- int result; ++ int result, pass = 1; + + DEBUG(DBG_BH, "w\n"); +- ++again: + /* Here we wake the target up */ + target_ints = SPI_TARGET_INT_WAKEUP; + sm_spi_write(dev, SPI_ADRS_ARM_INTERRUPTS, +@@ -117,6 +117,11 @@ + if (time_after(jiffies, timeout)) { + printk(KERN_WARNING "We haven't got a READY interrupt" + " from WAKEUP. (firmware crashed?)\n"); ++ if (pass == 1) { ++ printk(KERN_WARNING "Try again...\n"); ++ pass = 2; ++ goto again; ++ } + lp->device_state = DEVSTATE_DEAD; + result = -1; + goto exit; +@@ -131,7 +136,10 @@ + (unsigned char *)&host_ints_ack, sizeof(host_ints_ack)); + + result = 0; +- ++ ++ if (pass == 2) { ++ printk(KERN_WARNING "succeeded!!!\n"); ++ } + exit: + DEBUG(DBG_BH, "W\n"); + return result; +@@ -150,49 +158,84 @@ + return 0; + } + +-static int sm_drv_spi_rx(struct net_device *dev) ++static int sm_drv_spi_is_rx_frame_available(struct net_device *dev) ++{ ++ uint32_t host_ints, host_ints_ack; ++ sm_spi_read(dev, SPI_ADRS_HOST_INTERRUPTS, (unsigned char *)&host_ints, sizeof(host_ints)); ++ if ((host_ints & SPI_HOST_INT_UPDATE) || (host_ints & SPI_HOST_INT_SW_UPDATE)) { ++ host_ints_ack = SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE; ++ sm_spi_write(dev, SPI_ADRS_HOST_INT_ACK, (unsigned char *)&host_ints_ack, sizeof(host_ints_ack)); ++ return 1; ++ } ++ return 0; ++} ++ ++static struct s_ic_msg * sm_drv_spi_alloc_frame_and_start_rx_transfer(struct net_device *dev) + { + struct net_local *lp = dev->priv; +- struct spi_hif_local_data *hif_lp = HIF_LP(lp); + struct s_sm_frame *frame; ++ unsigned short length; + struct s_ic_msg *ic_msg; ++ ++ frame = frame_skb_alloc(dev, lp->sm_descr.mtu + lp->sm_descr.rxoffset, 0); ++ if (frame == NULL) return NULL; ++ ++ /* dummy read to flush SPI DMA controller bug */ ++ sm_spi_read(dev, SPI_ADRS_GEN_PURP_1, (unsigned char *)&length, sizeof(length)); ++ ++ sm_spi_read(dev, SPI_ADRS_DMA_DATA, (unsigned char *)&length, sizeof(length)); ++ DEBUG(DBG_BH, "%s: received frame len=%d\n", DRIVER_NAME, length); ++ ++ if (length > SPI_MAX_PACKET_SIZE) ++ length = SPI_MAX_PACKET_SIZE; ++ ++ sm_spi_dma_read_start(dev, SPI_ADRS_DMA_DATA, (unsigned char *) frame->data, length); ++ ++ ic_msg = FRAME_ICMSG(frame); ++ ic_msg->frame = frame; ++ ic_msg->channel = 0; ++ ic_msg->flags = 0; ++ ic_msg->length = length; ++ ic_msg->address = 0; ++ ic_msg->data = frame->data; ++ ++ return ic_msg; ++} ++ ++static int sm_drv_spi_rx(struct net_device *dev) ++{ ++ struct net_local *lp = dev->priv; ++ struct spi_hif_local_data *hif_lp = HIF_LP(lp); ++ struct s_ic_msg *ic_msg, *ic_msg_next; + int result, err; +- unsigned short length; + int32_t callb_mask = 0; +- ++ + err = sm_drv_spi_wakeup(dev); + if (err < 0) { + result = -1; + goto exit; + } + +- frame = frame_skb_alloc(dev, lp->sm_descr.mtu + lp->sm_descr.rxoffset, +- 0); +- if (frame != NULL) { +- ic_msg = FRAME_ICMSG(frame); +- ic_msg->frame = frame; +- +- /* dummy read to flush SPI DMA controller bug */ +- sm_spi_read(dev, SPI_ADRS_GEN_PURP_1, (unsigned char *)&length, +- sizeof(length)); +- +- sm_spi_read(dev, SPI_ADRS_DMA_DATA, (unsigned char *)&length, +- sizeof(length)); +- +- DEBUG(DBG_BH, "%s: received frame len=%d\n", DRIVER_NAME, +- length); +- +- if (length > SPI_MAX_PACKET_SIZE) +- length = SPI_MAX_PACKET_SIZE; ++ ic_msg_next = sm_drv_spi_alloc_frame_and_start_rx_transfer(dev); ++ if (ic_msg_next == NULL) { ++ printk("Couldn't allocate RX frame\n"); ++ result = -1; ++ goto exit; ++ } + +- sm_spi_dma_read(dev, SPI_ADRS_DMA_DATA, +- (unsigned char *) frame->data, length); +- +- ic_msg->channel = 0; +- ic_msg->flags = 0; +- ic_msg->length = length; +- ic_msg->address = 0; +- ic_msg->data = frame->data; ++ while (ic_msg_next) { ++ sm_spi_dma_read_wait_for_completion(); ++ ic_msg = ic_msg_next; ++ ic_msg_next = NULL; ++ ++ if (sm_drv_spi_is_rx_frame_available(dev)) { ++ ic_msg_next = sm_drv_spi_alloc_frame_and_start_rx_transfer(dev); ++ if (ic_msg_next == NULL) { ++ printk("Couldn't allocate RX frame\n"); ++ result = -1; ++ goto exit; ++ } ++ } + + hif_lp->spi_packets++; + spin_lock_bh(&lp->sm_lock); +@@ -207,13 +250,14 @@ + + DEBUG(DBG_IC,"Callback mask: %d\n", callb_mask); + +- if(callb_mask < 0) ++ if (callb_mask < 0) { + printk(KERN_WARNING "prism_interconnect_message_handle" + "returned error %d\n", callb_mask); +- } else +- printk("Couldn't allocate RX frame\n"); +- +- handle_sm_callback(dev, callb_mask); ++ result = -1; ++ goto exit; ++ } ++ handle_sm_callback(dev, callb_mask); ++ } + + result = 0; + +Index: cx3110x-0.8.1/src/sm_drv_spi_io.c +=================================================================== +--- cx3110x-0.8.1.orig/src/sm_drv_spi_io.c 2008-04-28 18:30:25.000000000 -0300 ++++ cx3110x-0.8.1/src/sm_drv_spi_io.c 2008-04-28 18:35:59.000000000 -0300 +@@ -120,7 +120,7 @@ + } + + +-int cx3110x_spi_dma_read(struct net_device *dev, unsigned long address, void * buffer, unsigned int length) ++int cx3110x_spi_dma_read_start(struct net_device *dev, unsigned long address, void * buffer, unsigned int length) + { + SPI_CS_ON(); + +@@ -170,13 +170,22 @@ + omap_start_dma(spi_dma.dma_rx_ch); + omap_start_dma(spi_dma.dma_tx_ch); + +- /* Wait for reading to complete */ +- while(!spi_dma.dma_rx_done) { +- udelay(5); ++ return 0; ++} ++ ++int cx3110x_spi_dma_read_wait_for_completion() ++{ ++ int wait_limit = 15000 * 5; ++ int wait_cycles = 0; ++ ++ /* Wait for DMA reading to complete */ ++ while ((!spi_dma.dma_rx_done || !spi_dma.dma_tx_done) && wait_cycles < wait_limit) { ++ wait_cycles++; ++ udelay(1); + } + +- while(!spi_dma.dma_tx_done) { +- udelay(5); ++ if (wait_cycles >= wait_limit) { ++ printk("McBSP read DMA timeout, spi_dma.dma_rx_done=%d, spi_dma.dma_tx_done=%d\n", spi_dma.dma_rx_done, spi_dma.dma_tx_done); + } + + spi_dma.dma_rx_done = 0; +@@ -184,11 +193,14 @@ + + SPI_CS_OFF(); + +- return 0; ++ return wait_cycles; + } + + int cx3110x_spi_dma_write(struct net_device *dev, unsigned long address, void * buffer, unsigned int length) + { ++ int wait_limit = 15000 * 5; ++ int wait_cycles = 0; ++ + SPI_CS_ON(); + + omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2, address << 8); +@@ -239,16 +251,20 @@ + omap_start_dma(spi_dma.dma_rx_ch); + omap_start_dma(spi_dma.dma_tx_ch); + +- /* We don't want to turn CS off before transfer is done */ +- +- while(!spi_dma.dma_rx_done) { +- udelay(5); ++ /* Wait for DMA writing to complete */ ++ while ((!spi_dma.dma_rx_done || !spi_dma.dma_tx_done) && wait_cycles < wait_limit) { ++ wait_cycles++; ++ udelay(1); + } + + while(!spi_dma.dma_tx_done) { + udelay(5); + } + ++ if (wait_cycles >= wait_limit) { ++ printk("McBSP write DMA timeout, spi_dma.dma_rx_done=%d, spi_dma.dma_tx_done=%d\n", spi_dma.dma_rx_done, spi_dma.dma_tx_done); ++ } ++ + spi_dma.dma_rx_done = 0; + spi_dma.dma_tx_done = 0; + +@@ -320,7 +336,7 @@ + int cx3110x_spi_start(struct net_device *dev) + { + struct omap_mcbsp_spi_cfg spi_cfg; +- int r, div = 1, rate_mhz, max_mhz = 14; ++ int r, div = 1, rate_mhz, max_mhz = 16; + struct net_local * lp; + struct spi_hif_local_data * spi_lp; + +@@ -368,11 +384,11 @@ + + cx3110x_hw_reset(); + +- while(rate_mhz/div >= max_mhz) ++ while(rate_mhz/(div+1) >= max_mhz) + div++; + +- printk("McBSP2: freq_limit=%dMHz, base_freq=%dMHz, divisor=%d (%d.%dMHz)\n", +- max_mhz, rate_mhz, div, rate_mhz / div, (rate_mhz * 10 / div) % 10); ++ printk("McBSP2: freq_limit=%dMHz, base_freq=%dMHz, div=%d (%d.%dMHz)\n", ++ max_mhz, rate_mhz, div, rate_mhz / (div+1), (rate_mhz * 10 / (div+1)) % 10); + + spi_dma.dma_tx_done = 0; + spi_dma.dma_rx_done = 0; +Index: cx3110x-0.8.1/src/sm_drv_spi_io.h +=================================================================== +--- cx3110x-0.8.1.orig/src/sm_drv_spi_io.h 2008-04-28 18:30:22.000000000 -0300 ++++ cx3110x-0.8.1/src/sm_drv_spi_io.h 2008-04-28 18:30:25.000000000 -0300 +@@ -27,15 +27,17 @@ + + int cx3110x_spi_read(struct net_device * dev, unsigned long address, unsigned char * buffer, unsigned int length); + int cx3110x_spi_write(struct net_device * dev, unsigned long address, unsigned char * buffer, unsigned int length); +-int cx3110x_spi_dma_read(struct net_device *dev, unsigned long address, void * buffer, unsigned int length); ++int cx3110x_spi_dma_read_start(struct net_device *dev, unsigned long address, void * buffer, unsigned int length); ++int cx3110x_spi_dma_read_wait_for_completion(void); + int cx3110x_spi_dma_write(struct net_device *dev, unsigned long address, void * buffer, unsigned int length); + + void cx3110x_dump_register(struct net_device * dev); + +-#define sm_spi_read(dev, addr, data, len) cx3110x_spi_read(dev, (addr), (data), (len)) ++#define sm_spi_read(dev, addr, data, len) cx3110x_spi_read(dev, (addr), (data), (len)) + #define sm_spi_write(dev, addr, data, len) cx3110x_spi_write(dev, (addr), (data), (len)) + +-#define sm_spi_dma_read(dev, addr, data, len) cx3110x_spi_dma_read(dev, (addr), (data), (len)) ++#define sm_spi_dma_read_start(dev, addr, data, len) cx3110x_spi_dma_read_start(dev, (addr), (data), (len)) ++#define sm_spi_dma_read_wait_for_completion() cx3110x_spi_dma_read_wait_for_completion() + #define sm_spi_dma_write(dev, addr, data, len) cx3110x_spi_dma_write(dev, (addr), (data), (len)) + + #endif |