xref: /OK3568_Linux_fs/kernel/drivers/rkflash/rknandc_base.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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