and rk nand base drivers
authorZhaoyifeng <zyf@rock-chips.com>
Tue, 8 Apr 2014 03:14:06 +0000 (11:14 +0800)
committerZhaoyifeng <zyf@rock-chips.com>
Tue, 8 Apr 2014 03:14:06 +0000 (11:14 +0800)
arch/arm/boot/dts/rk3288.dtsi
arch/arm/configs/rockchip_defconfig [changed mode: 0644->0755]
arch/arm/mach-rockchip/rknandbase.c

index b6da49f583f6e766e9d456ab3110b6cd22c4162e..eac36e96f150bf292dda03dcae55de4143e26f40 100755 (executable)
        };
 
 
+       nandc0: nandc@0xff400000 {
+               compatible = "rockchip,rk-nandc";
+               reg = <0xff400000 0x4000>;
+               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;/*irq=70*/
+               nandc_id = <0>;
+               clocks = <&clk_nandc0>, <&clk_gates5 5>, <&clk_gates7 14>;
+               clock-names = "clk_nandc", "g_clk_nandc","hclk_nandc";
+               status = "okay";
+       };
+
+       nandc1: nandc@0xff410000 {
+           compatible = "rockchip,rk-nandc";
+               reg = <0xff410000 0x4000>;
+               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; /*irq=72*/
+               nandc_id = <1>;
+               clocks = <&clk_nandc1>, <&clk_gates5 6>, <&clk_gates7 15>;
+               clock-names = "clk_nandc","g_clk_nandc","hclk_nandc";
+               status = "okay";
+       };
+
        emmc: rksdmmc@ff0f0000 {
                compatible = "rockchip,rk_mmc";
                reg = <0xff0f0000 0x4000>;
old mode 100644 (file)
new mode 100755 (executable)
index 64dd6cd..65b0cda
@@ -209,10 +209,7 @@ CONFIG_RFKILL=y
 CONFIG_RFKILL_RK=y
 CONFIG_DEVTMPFS=y
 CONFIG_CMA=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_RKNAND=y
+CONFIG_BLOCK_RKNAND=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_UID_STAT=y
 CONFIG_SRAM=y
index 7db78f19ca4d8751fbd0ecfebc9850ec214fb580..3aad71266a92b1c77f610aa0888b1d27af2a9dc1 100755 (executable)
@@ -9,7 +9,9 @@
 #include <asm/io.h>\r
 #include <linux/platform_device.h>\r
 #include <linux/semaphore.h>\r
+#include <linux/clk.h>\r
 \r
+#define RKNAND_VERSION_AND_DATE  "rknandbase v1.0 2014-03-31"\r
 \r
 #ifdef CONFIG_OF\r
 #include <linux/of.h>\r
@@ -18,7 +20,8 @@
 struct rknand_info {\r
     int tag;\r
     int enable;\r
-    int reserved0[6];\r
+    int clk_rate[2];\r
+    int reserved0[8];\r
     \r
     void (*rknand_suspend)(void);\r
     void (*rknand_resume)(void);\r
@@ -33,7 +36,20 @@ struct rknand_info {
     int reserved1[16];\r
 };\r
 \r
+struct rk_nandc_info \r
+{\r
+    int             id;\r
+    void __iomem    * reg_base ;\r
+    int             irq;\r
+    int             clk_rate;\r
+       struct clk          *clk;  // flash clk\r
+       struct clk          *hclk; // nandc clk\r
+       struct clk          *gclk; // flash clk gate\r
+};\r
+\r
 struct rknand_info * gpNandInfo = NULL;\r
+static struct rk_nandc_info  g_nandc_info[2];\r
+\r
 static char *cmdline=NULL;\r
 int rknand_get_part_info(char **s)\r
 {\r
@@ -113,12 +129,12 @@ void rknand_device_unlock (void)
 EXPORT_SYMBOL(rknand_device_unlock);\r
 \r
 \r
-int rknand_get_device(struct rknand_info ** prknand_Info)\r
+int rk_nand_get_device(struct rknand_info ** prknand_Info)\r
 {\r
     *prknand_Info = gpNandInfo;\r
-    return 0;    \r
+    return 0;     \r
 }\r
-EXPORT_SYMBOL(rknand_get_device);\r
+EXPORT_SYMBOL(rk_nand_get_device);\r
 \r
 int rknand_dma_map_single(unsigned long ptr,int size,int dir)\r
 {\r
@@ -132,7 +148,7 @@ void rknand_dma_unmap_single(unsigned long ptr,int size,int dir)
 }\r
 EXPORT_SYMBOL(rknand_dma_unmap_single);\r
 \r
-int rknand_flash_cs_init(void)\r
+int rknand_flash_cs_init(int id)\r
 {\r
 \r
 }\r
@@ -140,41 +156,85 @@ EXPORT_SYMBOL(rknand_flash_cs_init);
 \r
 int rknand_get_reg_addr(int *pNandc0,int *pNandc1,int *pSDMMC0,int *pSDMMC1,int *pSDMMC2)\r
 {\r
-    //*pNandc = ioremap(RK30_NANDC_PHYS,RK30_NANDC_SIZE);\r
-    //*pSDMMC0 = ioremap(SDMMC0_BASE_ADDR, 0x4000);\r
-    //*pSDMMC1 = ioremap(SDMMC1_BASE_ADDR, 0x4000);\r
-    //*pSDMMC2 = ioremap(EMMC_BASE_ADDR,   0x4000);\r
-       *pNandc0 = ioremap(0x10500000,0x4000);\r
-       //*pNandc1 = NULL;\r
+       *pNandc0 = g_nandc_info[0].reg_base;\r
+       *pNandc1 = g_nandc_info[1].reg_base;\r
 }\r
-\r
 EXPORT_SYMBOL(rknand_get_reg_addr);\r
 \r
-static int g_nandc_irq = 59;\r
-int rknand_nandc_irq_init(int mode,void * pfun)\r
+int rknand_nandc_irq_init(int id,int mode,void * pfun)\r
 {\r
     int ret = 0;\r
+    int irq= g_nandc_info[id].irq;\r
+\r
     if(mode) //init\r
     {\r
-        ret = request_irq(g_nandc_irq, pfun, 0, "nandc", NULL);\r
-        if(ret)\r
-            printk("request IRQ_NANDC irq , ret=%x.........\n", ret);\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
     }\r
     else //deinit\r
     {\r
-        free_irq(g_nandc_irq,  NULL);\r
+        free_irq(irq,  NULL);\r
     }\r
     return ret;\r
 }\r
 EXPORT_SYMBOL(rknand_nandc_irq_init);\r
+\r
 static int rknand_probe(struct platform_device *pdev)\r
 {\r
-       g_nandc_irq = platform_get_irq(pdev, 0);\r
-       printk("g_nandc_irq: %d\n",g_nandc_irq);\r
-       if (g_nandc_irq < 0) {\r
+       unsigned int id = 0;\r
+       int irq ;\r
+       struct resource         *mem;\r
+       void __iomem    *membase;\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 g_nandc_irq;\r
+               return irq;\r
+       }\r
+\r
+#ifdef CONFIG_OF\r
+       if(0==of_property_read_u32(pdev->dev.of_node, "nandc_id", &id))\r
+       {\r
+           ;\r
+       }\r
+    pdev->id = id;\r
+#endif\r
+       printk("rknand_probe %d %x\n", pdev->id,mem);\r
+       \r
+       if(id == 0)\r
+       {\r
+        memcpy(vendor0,membase+0x1400,0x200);\r
+        memcpy(sn_data,membase+0x1600,0x200);\r
+       }\r
+\r
+    g_nandc_info[id].id = id;\r
+    g_nandc_info[id].irq = irq;\r
+    g_nandc_info[id].reg_base = membase;\r
+\r
+    g_nandc_info[id].hclk = devm_clk_get(&pdev->dev, "hclk_nandc");\r
+    g_nandc_info[id].clk = devm_clk_get(&pdev->dev, "clk_nandc");\r
+    g_nandc_info[id].gclk = devm_clk_get(&pdev->dev, "g_clk_nandc");\r
+\r
+       if (unlikely(IS_ERR(g_nandc_info[id].clk)) || unlikely(IS_ERR(g_nandc_info[id].hclk))\r
+       || unlikely(IS_ERR(g_nandc_info[id].gclk))) {\r
+        printk("rknand_probe get clk error\n");\r
+        return -1;\r
        }\r
+\r
+    clk_set_rate(g_nandc_info[id].clk,150*1000*1000);\r
+       g_nandc_info[id].clk_rate = clk_get_rate(g_nandc_info[id].clk );\r
+    printk("rknand_probe clk rate = %d\n",g_nandc_info[id].clk_rate);\r
+    gpNandInfo->clk_rate[id] = g_nandc_info[id].clk_rate;\r
+    \r
+       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
@@ -239,15 +299,15 @@ MODULE_ALIAS(DRIVER_NAME);
 static int __init rknand_part_init(void)\r
 {\r
        int ret = 0;\r
-    char * pbuf = ioremap(0x10501400,0x400);\r
-    memcpy(vendor0,pbuf,0x200);\r
-    memcpy(sn_data,pbuf+0x200,0x200);\r
-    iounmap(pbuf);\r
+       printk("%s\n", RKNAND_VERSION_AND_DATE);\r
+\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));\r
+    //memset(gpNandInfo,0,sizeof(struct rknand_info));// no need\r
+    \r
        ret = platform_driver_register(&rknand_driver);\r
        printk("rknand_driver:ret = %x \n",ret);\r
        return ret;\r