Merge branch develop-3.10
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rknandbase.c
index 3aad71266a92b1c77f610aa0888b1d27af2a9dc1..887fe973f4cbcd856f0d063d53750b300c18af76 100755 (executable)
@@ -7,6 +7,7 @@
 #include <linux/interrupt.h>\r
 #include <linux/bootmem.h>\r
 #include <asm/io.h>\r
+#include <asm/cacheflush.h>\r
 #include <linux/platform_device.h>\r
 #include <linux/semaphore.h>\r
 #include <linux/clk.h>\r
@@ -21,7 +22,9 @@ struct rknand_info {
     int tag;\r
     int enable;\r
     int clk_rate[2];\r
-    int reserved0[8];\r
+    int nand_suspend_state;\r
+    int nand_shutdown_state;\r
+    int reserved0[6];\r
     \r
     void (*rknand_suspend)(void);\r
     void (*rknand_resume)(void);\r
@@ -58,27 +61,31 @@ int rknand_get_part_info(char **s)
 }\r
 EXPORT_SYMBOL(rknand_get_part_info); \r
 \r
-static char sn_data[512];\r
-static char vendor0[512];\r
-\r
+static char nand_idb_data[2048];\r
 char GetSNSectorInfo(char * pbuf)\r
 {\r
-    memcpy(pbuf,sn_data,0x200);\r
+    memcpy(pbuf,&nand_idb_data[0x600],0x200);\r
     return 0;\r
 }\r
 \r
 char GetSNSectorInfoBeforeNandInit(char * pbuf)\r
 {\r
-    memcpy(pbuf,sn_data,0x200);\r
+    memcpy(pbuf,&nand_idb_data[0x600],0x200);\r
     return 0;\r
 } \r
 \r
 char GetVendor0InfoBeforeNandInit(char * pbuf)\r
 {\r
-    memcpy(pbuf,vendor0 + 8,504);\r
+    memcpy(pbuf,&nand_idb_data[0x400+8],504);\r
     return 0;\r
 }\r
 \r
+char* rknand_get_idb_data(void)\r
+{\r
+    return nand_idb_data;\r
+}\r
+EXPORT_SYMBOL(rknand_get_idb_data);\r
+\r
 int  GetParamterInfo(char * pbuf , int len)\r
 {\r
     int ret = -1;\r
@@ -136,28 +143,40 @@ int rk_nand_get_device(struct rknand_info ** prknand_Info)
 }\r
 EXPORT_SYMBOL(rk_nand_get_device);\r
 \r
-int rknand_dma_map_single(unsigned long ptr,int size,int dir)\r
+unsigned long rknand_dma_flush_dcache(unsigned long ptr,int size,int dir)\r
 {\r
-    return dma_map_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);\r
+#ifdef CONFIG_ARM64\r
+       __flush_dcache_area((void *)ptr, size + 63);\r
+#else\r
+     __cpuc_flush_dcache_area((void*)ptr, size + 63);\r
+#endif\r
+    return ((unsigned long )virt_to_phys((void *)ptr));\r
+}\r
+EXPORT_SYMBOL(rknand_dma_flush_dcache);\r
+\r
+unsigned long rknand_dma_map_single(unsigned long ptr,int size,int dir)\r
+{\r
+    return dma_map_single(NULL,(void*)ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);\r
 }\r
 EXPORT_SYMBOL(rknand_dma_map_single);\r
 \r
 void rknand_dma_unmap_single(unsigned long ptr,int size,int dir)\r
 {\r
-    dma_unmap_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);\r
+    dma_unmap_single(NULL, (dma_addr_t)ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);\r
 }\r
 EXPORT_SYMBOL(rknand_dma_unmap_single);\r
 \r
 int rknand_flash_cs_init(int id)\r
 {\r
-\r
+    return 0;\r
 }\r
 EXPORT_SYMBOL(rknand_flash_cs_init);\r
 \r
-int rknand_get_reg_addr(int *pNandc0,int *pNandc1,int *pSDMMC0,int *pSDMMC1,int *pSDMMC2)\r
+int rknand_get_reg_addr(unsigned long *pNandc0,unsigned long *pNandc1,unsigned long *pSDMMC0,unsigned long *pSDMMC1,unsigned long *pSDMMC2)\r
 {\r
-       *pNandc0 = g_nandc_info[0].reg_base;\r
-       *pNandc1 = g_nandc_info[1].reg_base;\r
+       *pNandc0 = (unsigned long)g_nandc_info[0].reg_base;\r
+       *pNandc1 = (unsigned long)g_nandc_info[1].reg_base;\r
+       return 0;\r
 }\r
 EXPORT_SYMBOL(rknand_get_reg_addr);\r
 \r
@@ -166,11 +185,11 @@ int rknand_nandc_irq_init(int id,int mode,void * pfun)
     int ret = 0;\r
     int irq= g_nandc_info[id].irq;\r
 \r
-    if(mode) //init\r
+    if(mode)\r
     {\r
         ret = request_irq(irq, pfun, 0, "nandc", g_nandc_info[id].reg_base);\r
         //if(ret)\r
-            printk("request IRQ_NANDC %x irq %x, ret=%x.........\n",id,irq, ret);\r
+        //printk("request IRQ_NANDC %x irq %x, ret=%x.........\n",id,irq, ret);\r
     }\r
     else //deinit\r
     {\r
@@ -186,17 +205,23 @@ static int rknand_probe(struct platform_device *pdev)
        int irq ;\r
        struct resource         *mem;\r
        void __iomem    *membase;\r
-       \r
+\r
+    if(gpNandInfo == NULL)\r
+    {\r
+        gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL);\r
+        if (!gpNandInfo)\r
+            return -ENOMEM;\r
+        gpNandInfo->nand_suspend_state = 0;\r
+        gpNandInfo->nand_shutdown_state = 0;\r
+       }\r
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);\r
        membase = devm_request_and_ioremap(&pdev->dev, mem);\r
-\r
-    irq = platform_get_irq(pdev, 0);\r
-       printk("nand irq: %d\n",irq);\r
-       if (irq < 0) {\r
-               dev_err(&pdev->dev, "no irq resource?\n");\r
-               return irq;\r
+       if (membase == 0) \r
+       {\r
+               dev_err(&pdev->dev, "no reg resource?\n");\r
+               return -1;\r
        }\r
-\r
+       //printk("rknand_probe %d %x %x\n", pdev->id,(int)mem,(int)membase);\r
 #ifdef CONFIG_OF\r
        if(0==of_property_read_u32(pdev->dev.of_node, "nandc_id", &id))\r
        {\r
@@ -204,14 +229,21 @@ static int rknand_probe(struct platform_device *pdev)
        }\r
     pdev->id = id;\r
 #endif\r
-       printk("rknand_probe %d %x\n", pdev->id,mem);\r
-       \r
-       if(id == 0)\r
+    if(id == 0)\r
        {\r
-        memcpy(vendor0,membase+0x1400,0x200);\r
-        memcpy(sn_data,membase+0x1600,0x200);\r
+        memcpy(nand_idb_data,membase+0x1000,0x800);\r
+       }\r
+       else if(id >= 2)\r
+       {\r
+               dev_err(&pdev->dev, "nandc id = %d error!\n",id);\r
        }\r
 \r
+    irq = platform_get_irq(pdev, 0);\r
+       //printk("nand irq: %d\n",irq);\r
+       if (irq < 0) {\r
+               dev_err(&pdev->dev, "no irq resource?\n");\r
+               return irq;\r
+       }\r
     g_nandc_info[id].id = id;\r
     g_nandc_info[id].irq = irq;\r
     g_nandc_info[id].reg_base = membase;\r
@@ -234,28 +266,35 @@ static int rknand_probe(struct platform_device *pdev)
        clk_prepare_enable( g_nandc_info[id].clk );\r
        clk_prepare_enable( g_nandc_info[id].hclk);\r
        clk_prepare_enable( g_nandc_info[id].gclk);\r
-\r
        return 0;\r
 }\r
 \r
 static int rknand_suspend(struct platform_device *pdev, pm_message_t state)\r
 {\r
-    if(gpNandInfo->rknand_suspend)\r
-        gpNandInfo->rknand_suspend();  \r
+    if(gpNandInfo->rknand_suspend  && gpNandInfo->nand_suspend_state == 0){\r
+       gpNandInfo->nand_suspend_state = 1;\r
+        gpNandInfo->rknand_suspend();\r
+        //TODO:nandc clk disable\r
+       }\r
        return 0;\r
 }\r
 \r
 static int rknand_resume(struct platform_device *pdev)\r
 {\r
-    if(gpNandInfo->rknand_resume)\r
+    if(gpNandInfo->rknand_resume && gpNandInfo->nand_suspend_state == 1){\r
+       gpNandInfo->nand_suspend_state = 0;\r
+       //TODO:nandc clk enable\r
        gpNandInfo->rknand_resume();  \r
+       }\r
        return 0;\r
 }\r
 \r
 static void rknand_shutdown(struct platform_device *pdev)\r
 {\r
-    if(gpNandInfo->rknand_buffer_shutdown)\r
-        gpNandInfo->rknand_buffer_shutdown();    \r
+    if(gpNandInfo->rknand_buffer_shutdown && gpNandInfo->nand_shutdown_state == 0){\r
+        gpNandInfo->nand_shutdown_state = 1;\r
+        gpNandInfo->rknand_buffer_shutdown();\r
+    }\r
 }\r
 \r
 void rknand_dev_cache_flush(void)\r
@@ -303,11 +342,9 @@ static int __init rknand_part_init(void)
 \r
        cmdline = strstr(saved_command_line, "mtdparts=") + 9;\r
 \r
-       gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL);\r
-       if (!gpNandInfo)\r
-               return -ENOMEM;\r
-    //memset(gpNandInfo,0,sizeof(struct rknand_info));// no need\r
-    \r
+       gpNandInfo = NULL;\r
+    memset(g_nandc_info,0,sizeof(g_nandc_info));\r
+\r
        ret = platform_driver_register(&rknand_driver);\r
        printk("rknand_driver:ret = %x \n",ret);\r
        return ret;\r