1 // SPDX-License-Identifier: GPL-2.0
2
3 /* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */
4
5 #include <asm/cacheflush.h>
6 #include <linux/clk.h>
7 #include <linux/dma-mapping.h>
8 #include <linux/interrupt.h>
9 #include <linux/irq.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/sched.h>
14 #include <linux/slab.h>
15 #ifdef CONFIG_OF
16 #include <linux/of.h>
17 #endif
18
19 #include "nandc.h"
20 #include "rkflash_api.h"
21 #include "rkflash_blk.h"
22
23 #define RKNANDC_VERSION_AND_DATE "rknandc_base v1.1 2017-01-11"
24 #define RKNANDC_CLK_SET_RATE (150 * 1000 * 1000)
25
26 struct rknandc_info {
27 void __iomem *reg_base;
28 int irq;
29 int clk_rate;
30 struct clk *clk; /* controller's clk*/
31 struct clk *ahb_clk; /* ahb clk gate*/
32 struct clk *g_clk; /* clk_src_en gate*/
33 };
34
35 static struct rknandc_info g_nandc_info;
36 static struct device *g_nandc_dev;
37 static struct completion nandc_irq_complete;
38
rknandc_dma_map_single(unsigned long ptr,int size,int dir)39 unsigned long rknandc_dma_map_single(unsigned long ptr, int size, int dir)
40 {
41 return dma_map_single(g_nandc_dev, (void *)ptr, size
42 , dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
43 }
44
rknandc_dma_unmap_single(unsigned long ptr,int size,int dir)45 void rknandc_dma_unmap_single(unsigned long ptr, int size, int dir)
46 {
47 dma_unmap_single(g_nandc_dev, (dma_addr_t)ptr, size
48 , dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
49 }
50
rknandc_interrupt(int irq,void * dev_id)51 static irqreturn_t rknandc_interrupt(int irq, void *dev_id)
52 {
53 nandc_clean_irq();
54 complete(&nandc_irq_complete);
55 return IRQ_HANDLED;
56 }
57
rknandc_irq_config(int mode,void * pfun)58 static int rknandc_irq_config(int mode, void *pfun)
59 {
60 int ret = 0;
61 int irq = g_nandc_info.irq;
62
63 if (mode)
64 ret = request_irq(irq, pfun, 0, "rknandc",
65 g_nandc_info.reg_base);
66 else
67 free_irq(irq, NULL);
68 return ret;
69 }
70
rknandc_irq_init(void)71 static int rknandc_irq_init(void)
72 {
73 init_completion(&nandc_irq_complete);
74 rknandc_irq_config(1, rknandc_interrupt);
75 return 0;
76 }
77
rknandc_irq_deinit(void)78 static int rknandc_irq_deinit(void)
79 {
80 rknandc_irq_config(0, rknandc_interrupt);
81 return 0;
82 }
83
rknandc_probe(struct platform_device * pdev)84 static int rknandc_probe(struct platform_device *pdev)
85 {
86 int irq;
87 struct resource *mem;
88 void __iomem *membase;
89 int ret;
90
91 g_nandc_dev = &pdev->dev;
92 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
93 membase = devm_ioremap_resource(&pdev->dev, mem);
94 if (!membase) {
95 dev_err(&pdev->dev, "no reg resource?\n");
96 return -1;
97 }
98
99 irq = platform_get_irq(pdev, 0);
100 if (irq < 0) {
101 dev_err(&pdev->dev, "no irq resource?\n");
102 return irq;
103 }
104
105 g_nandc_info.irq = irq;
106 g_nandc_info.reg_base = membase;
107 g_nandc_info.ahb_clk = devm_clk_get(&pdev->dev, "hclk_nandc");
108 g_nandc_info.clk = devm_clk_get(&pdev->dev, "clk_nandc");
109 g_nandc_info.g_clk = devm_clk_get(&pdev->dev, "g_clk_nandc");
110 if (unlikely(IS_ERR(g_nandc_info.clk)) ||
111 unlikely(IS_ERR(g_nandc_info.ahb_clk))) {
112 dev_err(&pdev->dev, "%s get clk error\n", __func__);
113 return -1;
114 }
115 clk_prepare_enable(g_nandc_info.ahb_clk);
116 if (!(IS_ERR(g_nandc_info.g_clk)))
117 clk_prepare_enable(g_nandc_info.g_clk);
118
119 clk_set_rate(g_nandc_info.clk, RKNANDC_CLK_SET_RATE);
120 g_nandc_info.clk_rate = clk_get_rate(g_nandc_info.clk);
121 clk_prepare_enable(g_nandc_info.clk);
122 dev_info(&pdev->dev,
123 "%s clk rate = %d\n",
124 __func__,
125 g_nandc_info.clk_rate);
126 rknandc_irq_init();
127 ret = rkflash_dev_init(g_nandc_info.reg_base, FLASH_TYPE_NANDC_NAND, &nandc_nand_ops);
128
129 if (ret)
130 return ret;
131
132 return dma_set_mask(g_nandc_dev, DMA_BIT_MASK(32));
133 }
134
rknandc_suspend(struct device * dev)135 static int __maybe_unused rknandc_suspend(struct device *dev)
136 {
137 return rkflash_dev_suspend();
138 }
139
rknandc_resume(struct device * dev)140 static int __maybe_unused rknandc_resume(struct device *dev)
141 {
142 return rkflash_dev_resume(g_nandc_info.reg_base);
143 }
144
145 static SIMPLE_DEV_PM_OPS(rknandc_pmops,
146 rknandc_suspend,
147 rknandc_resume);
148
rknandc_shutdown(struct platform_device * pdev)149 static void rknandc_shutdown(struct platform_device *pdev)
150 {
151 rkflash_dev_shutdown();
152 }
153
154 #ifdef CONFIG_OF
155 static const struct of_device_id of_rknandc_match[] = {
156 {.compatible = "rockchip,rk-nandc"},
157 {.compatible = "rockchip,nandc"},
158 {}
159 };
160 #endif
161
162 static struct platform_driver rknandc_driver = {
163 .probe = rknandc_probe,
164 .shutdown = rknandc_shutdown,
165 .driver = {
166 .name = "rknandc",
167 #ifdef CONFIG_OF
168 .of_match_table = of_rknandc_match,
169 #endif
170 .pm = &rknandc_pmops,
171 },
172 };
173
rknandc_driver_exit(void)174 static void __exit rknandc_driver_exit(void)
175 {
176 rkflash_dev_exit();
177 rknandc_irq_deinit();
178 platform_driver_unregister(&rknandc_driver);
179 }
180
rknandc_driver_init(void)181 static int __init rknandc_driver_init(void)
182 {
183 int ret = 0;
184
185 pr_err("%s\n", RKNANDC_VERSION_AND_DATE);
186 ret = platform_driver_register(&rknandc_driver);
187 return ret;
188 }
189
190 module_init(rknandc_driver_init);
191 module_exit(rknandc_driver_exit);
192 MODULE_ALIAS("rknandc");
193