lantiq: fix lantiq_mei.c and amazonse.dsti for adsl modem firmware
[openwrt/openwrt.git] / package / kernel / lantiq / ltq-adsl-mei / src / lantiq_mei.c
index 443b9d9..df04de7 100644 (file)
 #define ltq_w32_mask(clear, set, reg)       ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
 */
 
-#define LTQ_RCU_BASE_ADDR   0x1F203000
+#define LTQ_RCU_BASE_ADDR       0x1F203000
 #define LTQ_ICU_BASE_ADDR       0x1F880200
 #define LTQ_MEI_BASE_ADDR       0x1E116000
 #define LTQ_PMU_BASE_ADDR       0x1F102000
-#define LTQ_MEI_DYING_GASP_INT  (INT_NUM_IM1_IRL0 + 21)
-#define LTQ_USB_OC_INT          (INT_NUM_IM4_IRL0 + 23)
-#define LTQ_MEI_INT             (INT_NUM_IM1_IRL0 + 23)
+
+
+#ifdef CONFIG_DANUBE
+# define LTQ_MEI_INT             (INT_NUM_IM1_IRL0 + 23)
+# define LTQ_MEI_DYING_GASP_INT  (INT_NUM_IM1_IRL0 + 21)
+# define LTQ_USB_OC_INT          (INT_NUM_IM4_IRL0 + 23)
+#endif
+
+#ifdef CONFIG_AMAZON_SE
+# define LTQ_MEI_INT             (INT_NUM_IM2_IRL0 + 9)
+# define LTQ_MEI_DYING_GASP_INT  (INT_NUM_IM2_IRL0 + 11)
+# define LTQ_USB_OC_INT          (INT_NUM_IM2_IRL0 + 20)
+#endif
+
+#ifdef CONFIG_AR9
+# define LTQ_MEI_INT             (INT_NUM_IM1_IRL0 + 23)
+# define LTQ_MEI_DYING_GASP_INT  (INT_NUM_IM1_IRL0 + 21)
+# define LTQ_USB_OC_INT          (INT_NUM_IM1_IRL0 + 28)
+#endif
+
+#ifndef LTQ_MEI_INT
+#error "Unknown Lantiq ARCH!"
+#endif
 
 #define LTQ_RCU_RST_REQ_DFE            (1 << 7)
 #define LTQ_RCU_RST_REQ_AFE            (1 << 11)
@@ -1327,37 +1347,16 @@ IFX_MEI_RunAdslModem (DSL_DEV_Device_t *pDev)
 
        im0_register = (*LTQ_ICU_IM0_IER) & (1 << 20);
        im2_register = (*LTQ_ICU_IM2_IER) & (1 << 20);
+
        /* Turn off irq */
-       #ifdef CONFIG_SOC_AMAZON_SE
-#define        IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL0 + 23)
-       disable_irq (IFXMIPS_USB_OC_INT0);
-//     disable_irq (IFXMIPS_USB_OC_INT2);
-       #elif defined(CONFIG_SOC_AR9)
-#define        IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL1 + 28)
-       disable_irq (IFXMIPS_USB_OC_INT0);
-//     disable_irq (IFXMIPS_USB_OC_INT2);
-       #elif defined(CONFIG_SOC_XWAY)
        disable_irq (LTQ_USB_OC_INT);
-       #else
-       #error unkonwn arch
-       #endif
        disable_irq (pDev->nIrq[IFX_DYING_GASP]);
 
        IFX_MEI_RunArc (pDev);
 
        MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready, 1000);
 
-       #ifdef CONFIG_SOC_AMAZON_SE
-       MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
-//     MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
-       #elif defined(CONFIG_SOC_AR9)
-       MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
-//     MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
-       #elif defined(CONFIG_SOC_XWAY)
        MEI_MASK_AND_ACK_IRQ (LTQ_USB_OC_INT);
-       #else
-       #error unkonwn arch
-       #endif
        MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
 
        /* Re-enable irq */
@@ -1513,13 +1512,31 @@ IFX_MEI_DFEMemoryAlloc (DSL_DEV_Device_t * pDev, long size)
                         allocate_size = size;
                 else
                         allocate_size = SDRAM_SEGMENT_SIZE;
-               org_mem_ptr = kmalloc (allocate_size + 1024, GFP_KERNEL);
+        
+               org_mem_ptr = kmalloc (allocate_size, GFP_KERNEL);
                if (org_mem_ptr == NULL) {
                         IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n", idx, allocate_size);
                        err = -ENOMEM;
                        goto allocate_error;
                }
-                mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
+               
+               if (((unsigned long)org_mem_ptr) & (1023)) {
+                       /* Pointer not 1k aligned, so free it and allocate a larger chunk
+                        * for further alignment.
+                        */
+                       kfree(org_mem_ptr);
+                       org_mem_ptr = kmalloc (allocate_size + 1024, GFP_KERNEL);
+                       if (org_mem_ptr == NULL) {
+                               IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n",
+                                             idx, allocate_size + 1024);
+                               err = -ENOMEM;
+                               goto allocate_error;
+                       }
+                       mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
+               } else {
+                       mem_ptr = (unsigned long) org_mem_ptr;
+               }
+
                 adsl_mem_info[idx].address = (char *) mem_ptr;
                 adsl_mem_info[idx].org_address = org_mem_ptr;
                 adsl_mem_info[idx].size = allocate_size;
@@ -1591,6 +1608,7 @@ DSL_BSP_FWDownload (DSL_DEV_Device_t * pDev, const char *buf,
 
        size_t nRead = 0, nCopy = 0;
        char *mem_ptr;
+       char *org_mem_ptr = NULL;
        ssize_t retval = -ENOMEM;
        int idx = 0;
 
@@ -1634,17 +1652,33 @@ DSL_BSP_FWDownload (DSL_DEV_Device_t * pDev, const char *buf,
                DSL_DEV_PRIVATE(pDev)->img_hdr =
                        (ARC_IMG_HDR *) adsl_mem_info[0].address;
 
-               adsl_mem_info[XDATA_REGISTER].org_address = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
-               adsl_mem_info[XDATA_REGISTER].address =
-                       (char *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].org_address + 1023) & 0xFFFFFC00);
-
-               adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
-
-               if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
+               org_mem_ptr = kmalloc (SDRAM_SEGMENT_SIZE, GFP_KERNEL);
+               if (org_mem_ptr == NULL) {
                        IFX_MEI_EMSG ("kmalloc memory fail!\n");
                        retval = -ENOMEM;
                        goto error;
                }
+               
+               if (((unsigned long)org_mem_ptr) & (1023)) {
+                       /* Pointer not 1k aligned, so free it and allocate a larger chunk
+                        * for further alignment.
+                        */
+                       kfree(org_mem_ptr);
+                       org_mem_ptr = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
+                       if (org_mem_ptr == NULL) {
+                               IFX_MEI_EMSG ("kmalloc memory fail!\n");
+                               retval = -ENOMEM;
+                               goto error;
+                       }
+                       adsl_mem_info[XDATA_REGISTER].address =
+                               (char *) ((unsigned long) (org_mem_ptr + 1023) & ~(1024 -1));
+               } else {
+                       adsl_mem_info[XDATA_REGISTER].address = org_mem_ptr;
+               }
+               
+               adsl_mem_info[XDATA_REGISTER].org_address = org_mem_ptr;
+               adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
+
                adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
                IFX_MEI_DMSG("-> IFX_MEI_BarUpdate()\n");
                IFX_MEI_BarUpdate (pDev, (DSL_DEV_PRIVATE(pDev)->nBar));
@@ -2272,12 +2306,11 @@ IFX_MEI_InitDevice (int num)
                 /* Power up MEI */
 #ifdef CONFIG_LANTIQ_AMAZON_SE
                *LTQ_PMU_PWDCR &= ~(1 << 9);  // enable dsl
-                *LTQ_PMU_PWDCR &= ~(1 << 15); // enable AHB base
-#else
-               temp = ltq_r32(LTQ_PMU_PWDCR);
-               temp &= 0xffff7dbe;
-               ltq_w32(temp, LTQ_PMU_PWDCR);
+               *LTQ_PMU_PWDCR &= ~(1 << 15); // enable AHB base
 #endif
+               temp = ltq_r32(LTQ_PMU_PWDCR);
+               temp &= 0xffff7dbe;
+               ltq_w32(temp, LTQ_PMU_PWDCR);
        }
        pDev->nInUse = 0;
        DSL_DEV_PRIVATE(pDev)->modem_ready = 0;