GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / mtd / hyperbus / hbmc-am654.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
4 // Author: Vignesh Raghavendra <vigneshr@ti.com>
5
6 #include <linux/completion.h>
7 #include <linux/dma-direction.h>
8 #include <linux/dma-mapping.h>
9 #include <linux/dmaengine.h>
10 #include <linux/err.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/mtd/cfi.h>
14 #include <linux/mtd/hyperbus.h>
15 #include <linux/mtd/mtd.h>
16 #include <linux/mux/consumer.h>
17 #include <linux/of.h>
18 #include <linux/of_address.h>
19 #include <linux/platform_device.h>
20 #include <linux/sched/task_stack.h>
21 #include <linux/types.h>
22
23 #define AM654_HBMC_CALIB_COUNT 25
24
25 struct am654_hbmc_device_priv {
26         struct completion rx_dma_complete;
27         phys_addr_t device_base;
28         struct hyperbus_ctlr *ctlr;
29         struct dma_chan *rx_chan;
30 };
31
32 struct am654_hbmc_priv {
33         struct hyperbus_ctlr ctlr;
34         struct hyperbus_device hbdev;
35         struct mux_control *mux_ctrl;
36 };
37
38 static int am654_hbmc_calibrate(struct hyperbus_device *hbdev)
39 {
40         struct map_info *map = &hbdev->map;
41         struct cfi_private cfi;
42         int count = AM654_HBMC_CALIB_COUNT;
43         int pass_count = 0;
44         int ret;
45
46         cfi.interleave = 1;
47         cfi.device_type = CFI_DEVICETYPE_X16;
48         cfi_send_gen_cmd(0xF0, 0, 0, map, &cfi, cfi.device_type, NULL);
49         cfi_send_gen_cmd(0x98, 0x55, 0, map, &cfi, cfi.device_type, NULL);
50
51         while (count--) {
52                 ret = cfi_qry_present(map, 0, &cfi);
53                 if (ret)
54                         pass_count++;
55                 else
56                         pass_count = 0;
57                 if (pass_count == 5)
58                         break;
59         }
60
61         cfi_qry_mode_off(0, map, &cfi);
62
63         return ret;
64 }
65
66 static void am654_hbmc_dma_callback(void *param)
67 {
68         struct am654_hbmc_device_priv *priv = param;
69
70         complete(&priv->rx_dma_complete);
71 }
72
73 static int am654_hbmc_dma_read(struct am654_hbmc_device_priv *priv, void *to,
74                                unsigned long from, ssize_t len)
75
76 {
77         enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
78         struct dma_chan *rx_chan = priv->rx_chan;
79         struct dma_async_tx_descriptor *tx;
80         dma_addr_t dma_dst, dma_src;
81         dma_cookie_t cookie;
82         int ret;
83
84         if (!priv->rx_chan || !virt_addr_valid(to) || object_is_on_stack(to))
85                 return -EINVAL;
86
87         dma_dst = dma_map_single(rx_chan->device->dev, to, len, DMA_FROM_DEVICE);
88         if (dma_mapping_error(rx_chan->device->dev, dma_dst)) {
89                 dev_dbg(priv->ctlr->dev, "DMA mapping failed\n");
90                 return -EIO;
91         }
92
93         dma_src = priv->device_base + from;
94         tx = dmaengine_prep_dma_memcpy(rx_chan, dma_dst, dma_src, len, flags);
95         if (!tx) {
96                 dev_err(priv->ctlr->dev, "device_prep_dma_memcpy error\n");
97                 ret = -EIO;
98                 goto unmap_dma;
99         }
100
101         reinit_completion(&priv->rx_dma_complete);
102         tx->callback = am654_hbmc_dma_callback;
103         tx->callback_param = priv;
104         cookie = dmaengine_submit(tx);
105
106         ret = dma_submit_error(cookie);
107         if (ret) {
108                 dev_err(priv->ctlr->dev, "dma_submit_error %d\n", cookie);
109                 goto unmap_dma;
110         }
111
112         dma_async_issue_pending(rx_chan);
113         if (!wait_for_completion_timeout(&priv->rx_dma_complete,  msecs_to_jiffies(len + 1000))) {
114                 dmaengine_terminate_sync(rx_chan);
115                 dev_err(priv->ctlr->dev, "DMA wait_for_completion_timeout\n");
116                 ret = -ETIMEDOUT;
117         }
118
119 unmap_dma:
120         dma_unmap_single(rx_chan->device->dev, dma_dst, len, DMA_FROM_DEVICE);
121         return ret;
122 }
123
124 static void am654_hbmc_read(struct hyperbus_device *hbdev, void *to,
125                             unsigned long from, ssize_t len)
126 {
127         struct am654_hbmc_device_priv *priv = hbdev->priv;
128
129         if (len < SZ_1K || am654_hbmc_dma_read(priv, to, from, len))
130                 memcpy_fromio(to, hbdev->map.virt + from, len);
131 }
132
133 static const struct hyperbus_ops am654_hbmc_ops = {
134         .calibrate = am654_hbmc_calibrate,
135         .copy_from = am654_hbmc_read,
136 };
137
138 static int am654_hbmc_request_mmap_dma(struct am654_hbmc_device_priv *priv)
139 {
140         struct dma_chan *rx_chan;
141         dma_cap_mask_t mask;
142
143         dma_cap_zero(mask);
144         dma_cap_set(DMA_MEMCPY, mask);
145
146         rx_chan = dma_request_chan_by_mask(&mask);
147         if (IS_ERR(rx_chan)) {
148                 if (PTR_ERR(rx_chan) == -EPROBE_DEFER)
149                         return -EPROBE_DEFER;
150                 dev_dbg(priv->ctlr->dev, "No DMA channel available\n");
151                 return 0;
152         }
153         priv->rx_chan = rx_chan;
154         init_completion(&priv->rx_dma_complete);
155
156         return 0;
157 }
158
159 static int am654_hbmc_probe(struct platform_device *pdev)
160 {
161         struct device_node *np = pdev->dev.of_node;
162         struct am654_hbmc_device_priv *dev_priv;
163         struct device *dev = &pdev->dev;
164         struct am654_hbmc_priv *priv;
165         struct resource res;
166         int ret;
167
168         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
169         if (!priv)
170                 return -ENOMEM;
171
172         platform_set_drvdata(pdev, priv);
173
174         priv->hbdev.np = of_get_next_child(np, NULL);
175         ret = of_address_to_resource(priv->hbdev.np, 0, &res);
176         if (ret)
177                 return ret;
178
179         if (of_property_read_bool(dev->of_node, "mux-controls")) {
180                 struct mux_control *control = devm_mux_control_get(dev, NULL);
181
182                 if (IS_ERR(control))
183                         return PTR_ERR(control);
184
185                 ret = mux_control_select(control, 1);
186                 if (ret) {
187                         dev_err(dev, "Failed to select HBMC mux\n");
188                         return ret;
189                 }
190                 priv->mux_ctrl = control;
191         }
192
193         priv->hbdev.map.size = resource_size(&res);
194         priv->hbdev.map.virt = devm_ioremap_resource(dev, &res);
195         if (IS_ERR(priv->hbdev.map.virt))
196                 return PTR_ERR(priv->hbdev.map.virt);
197
198         priv->ctlr.dev = dev;
199         priv->ctlr.ops = &am654_hbmc_ops;
200         priv->hbdev.ctlr = &priv->ctlr;
201
202         dev_priv = devm_kzalloc(dev, sizeof(*dev_priv), GFP_KERNEL);
203         if (!dev_priv) {
204                 ret = -ENOMEM;
205                 goto disable_mux;
206         }
207
208         priv->hbdev.priv = dev_priv;
209         dev_priv->device_base = res.start;
210         dev_priv->ctlr = &priv->ctlr;
211
212         ret = am654_hbmc_request_mmap_dma(dev_priv);
213         if (ret)
214                 goto disable_mux;
215
216         ret = hyperbus_register_device(&priv->hbdev);
217         if (ret) {
218                 dev_err(dev, "failed to register controller\n");
219                 goto release_dma;
220         }
221
222         return 0;
223 release_dma:
224         if (dev_priv->rx_chan)
225                 dma_release_channel(dev_priv->rx_chan);
226 disable_mux:
227         if (priv->mux_ctrl)
228                 mux_control_deselect(priv->mux_ctrl);
229         return ret;
230 }
231
232 static int am654_hbmc_remove(struct platform_device *pdev)
233 {
234         struct am654_hbmc_priv *priv = platform_get_drvdata(pdev);
235         struct am654_hbmc_device_priv *dev_priv = priv->hbdev.priv;
236         int ret;
237
238         ret = hyperbus_unregister_device(&priv->hbdev);
239         if (priv->mux_ctrl)
240                 mux_control_deselect(priv->mux_ctrl);
241
242         if (dev_priv->rx_chan)
243                 dma_release_channel(dev_priv->rx_chan);
244
245         return ret;
246 }
247
248 static const struct of_device_id am654_hbmc_dt_ids[] = {
249         {
250                 .compatible = "ti,am654-hbmc",
251         },
252         { /* end of table */ }
253 };
254
255 MODULE_DEVICE_TABLE(of, am654_hbmc_dt_ids);
256
257 static struct platform_driver am654_hbmc_platform_driver = {
258         .probe = am654_hbmc_probe,
259         .remove = am654_hbmc_remove,
260         .driver = {
261                 .name = "hbmc-am654",
262                 .of_match_table = am654_hbmc_dt_ids,
263         },
264 };
265
266 module_platform_driver(am654_hbmc_platform_driver);
267
268 MODULE_DESCRIPTION("HBMC driver for AM654 SoC");
269 MODULE_LICENSE("GPL v2");
270 MODULE_ALIAS("platform:hbmc-am654");
271 MODULE_AUTHOR("Vignesh Raghavendra <vigneshr@ti.com>");