Merge remote-tracking branches 'asoc/fix/adsp', 'asoc/fix/arizona', 'asoc/fix/atmel...
[linux-drm-fsl-dcu.git] / drivers / misc / mic / host / mic_boot.c
1 /*
2  * Intel MIC Platform Software Stack (MPSS)
3  *
4  * Copyright(c) 2013 Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License, version 2, as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * The full GNU General Public License is included in this distribution in
16  * the file called "COPYING".
17  *
18  * Intel MIC Host driver.
19  *
20  */
21 #include <linux/delay.h>
22 #include <linux/firmware.h>
23 #include <linux/pci.h>
24
25 #include <linux/mic_common.h>
26 #include "../common/mic_dev.h"
27 #include "mic_device.h"
28 #include "mic_smpt.h"
29 #include "mic_virtio.h"
30
31 /**
32  * mic_reset - Reset the MIC device.
33  * @mdev: pointer to mic_device instance
34  */
35 static void mic_reset(struct mic_device *mdev)
36 {
37         int i;
38
39 #define MIC_RESET_TO (45)
40
41         reinit_completion(&mdev->reset_wait);
42         mdev->ops->reset_fw_ready(mdev);
43         mdev->ops->reset(mdev);
44
45         for (i = 0; i < MIC_RESET_TO; i++) {
46                 if (mdev->ops->is_fw_ready(mdev))
47                         goto done;
48                 /*
49                  * Resets typically take 10s of seconds to complete.
50                  * Since an MMIO read is required to check if the
51                  * firmware is ready or not, a 1 second delay works nicely.
52                  */
53                 msleep(1000);
54         }
55         mic_set_state(mdev, MIC_RESET_FAILED);
56 done:
57         complete_all(&mdev->reset_wait);
58 }
59
60 /* Initialize the MIC bootparams */
61 void mic_bootparam_init(struct mic_device *mdev)
62 {
63         struct mic_bootparam *bootparam = mdev->dp;
64
65         bootparam->magic = cpu_to_le32(MIC_MAGIC);
66         bootparam->c2h_shutdown_db = mdev->shutdown_db;
67         bootparam->h2c_shutdown_db = -1;
68         bootparam->h2c_config_db = -1;
69         bootparam->shutdown_status = 0;
70         bootparam->shutdown_card = 0;
71 }
72
73 /**
74  * mic_start - Start the MIC.
75  * @mdev: pointer to mic_device instance
76  * @buf: buffer containing boot string including firmware/ramdisk path.
77  *
78  * This function prepares an MIC for boot and initiates boot.
79  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
80  */
81 int mic_start(struct mic_device *mdev, const char *buf)
82 {
83         int rc;
84         mutex_lock(&mdev->mic_mutex);
85 retry:
86         if (MIC_OFFLINE != mdev->state) {
87                 rc = -EINVAL;
88                 goto unlock_ret;
89         }
90         if (!mdev->ops->is_fw_ready(mdev)) {
91                 mic_reset(mdev);
92                 /*
93                  * The state will either be MIC_OFFLINE if the reset succeeded
94                  * or MIC_RESET_FAILED if the firmware reset failed.
95                  */
96                 goto retry;
97         }
98         rc = mdev->ops->load_mic_fw(mdev, buf);
99         if (rc)
100                 goto unlock_ret;
101         mic_smpt_restore(mdev);
102         mic_intr_restore(mdev);
103         mdev->intr_ops->enable_interrupts(mdev);
104         mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
105         mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
106         mdev->ops->send_firmware_intr(mdev);
107         mic_set_state(mdev, MIC_ONLINE);
108 unlock_ret:
109         mutex_unlock(&mdev->mic_mutex);
110         return rc;
111 }
112
113 /**
114  * mic_stop - Prepare the MIC for reset and trigger reset.
115  * @mdev: pointer to mic_device instance
116  * @force: force a MIC to reset even if it is already offline.
117  *
118  * RETURNS: None.
119  */
120 void mic_stop(struct mic_device *mdev, bool force)
121 {
122         mutex_lock(&mdev->mic_mutex);
123         if (MIC_OFFLINE != mdev->state || force) {
124                 mic_virtio_reset_devices(mdev);
125                 mic_bootparam_init(mdev);
126                 mic_reset(mdev);
127                 if (MIC_RESET_FAILED == mdev->state)
128                         goto unlock;
129                 mic_set_shutdown_status(mdev, MIC_NOP);
130                 if (MIC_SUSPENDED != mdev->state)
131                         mic_set_state(mdev, MIC_OFFLINE);
132         }
133 unlock:
134         mutex_unlock(&mdev->mic_mutex);
135 }
136
137 /**
138  * mic_shutdown - Initiate MIC shutdown.
139  * @mdev: pointer to mic_device instance
140  *
141  * RETURNS: None.
142  */
143 void mic_shutdown(struct mic_device *mdev)
144 {
145         struct mic_bootparam *bootparam = mdev->dp;
146         s8 db = bootparam->h2c_shutdown_db;
147
148         mutex_lock(&mdev->mic_mutex);
149         if (MIC_ONLINE == mdev->state && db != -1) {
150                 bootparam->shutdown_card = 1;
151                 mdev->ops->send_intr(mdev, db);
152                 mic_set_state(mdev, MIC_SHUTTING_DOWN);
153         }
154         mutex_unlock(&mdev->mic_mutex);
155 }
156
157 /**
158  * mic_shutdown_work - Handle shutdown interrupt from MIC.
159  * @work: The work structure.
160  *
161  * This work is scheduled whenever the host has received a shutdown
162  * interrupt from the MIC.
163  */
164 void mic_shutdown_work(struct work_struct *work)
165 {
166         struct mic_device *mdev = container_of(work, struct mic_device,
167                         shutdown_work);
168         struct mic_bootparam *bootparam = mdev->dp;
169
170         mutex_lock(&mdev->mic_mutex);
171         mic_set_shutdown_status(mdev, bootparam->shutdown_status);
172         bootparam->shutdown_status = 0;
173
174         /*
175          * if state is MIC_SUSPENDED, OSPM suspend is in progress. We do not
176          * change the state here so as to prevent users from booting the card
177          * during and after the suspend operation.
178          */
179         if (MIC_SHUTTING_DOWN != mdev->state &&
180             MIC_SUSPENDED != mdev->state)
181                 mic_set_state(mdev, MIC_SHUTTING_DOWN);
182         mutex_unlock(&mdev->mic_mutex);
183 }
184
185 /**
186  * mic_reset_trigger_work - Trigger MIC reset.
187  * @work: The work structure.
188  *
189  * This work is scheduled whenever the host wants to reset the MIC.
190  */
191 void mic_reset_trigger_work(struct work_struct *work)
192 {
193         struct mic_device *mdev = container_of(work, struct mic_device,
194                         reset_trigger_work);
195
196         mic_stop(mdev, false);
197 }
198
199 /**
200  * mic_complete_resume - Complete MIC Resume after an OSPM suspend/hibernate
201  * event.
202  * @mdev: pointer to mic_device instance
203  *
204  * RETURNS: None.
205  */
206 void mic_complete_resume(struct mic_device *mdev)
207 {
208         if (mdev->state != MIC_SUSPENDED) {
209                 dev_warn(mdev->sdev->parent, "state %d should be %d\n",
210                          mdev->state, MIC_SUSPENDED);
211                 return;
212         }
213
214         /* Make sure firmware is ready */
215         if (!mdev->ops->is_fw_ready(mdev))
216                 mic_stop(mdev, true);
217
218         mutex_lock(&mdev->mic_mutex);
219         mic_set_state(mdev, MIC_OFFLINE);
220         mutex_unlock(&mdev->mic_mutex);
221 }
222
223 /**
224  * mic_prepare_suspend - Handle suspend notification for the MIC device.
225  * @mdev: pointer to mic_device instance
226  *
227  * RETURNS: None.
228  */
229 void mic_prepare_suspend(struct mic_device *mdev)
230 {
231         int rc;
232
233 #define MIC_SUSPEND_TIMEOUT (60 * HZ)
234
235         mutex_lock(&mdev->mic_mutex);
236         switch (mdev->state) {
237         case MIC_OFFLINE:
238                 /*
239                  * Card is already offline. Set state to MIC_SUSPENDED
240                  * to prevent users from booting the card.
241                  */
242                 mic_set_state(mdev, MIC_SUSPENDED);
243                 mutex_unlock(&mdev->mic_mutex);
244                 break;
245         case MIC_ONLINE:
246                 /*
247                  * Card is online. Set state to MIC_SUSPENDING and notify
248                  * MIC user space daemon which will issue card
249                  * shutdown and reset.
250                  */
251                 mic_set_state(mdev, MIC_SUSPENDING);
252                 mutex_unlock(&mdev->mic_mutex);
253                 rc = wait_for_completion_timeout(&mdev->reset_wait,
254                                                 MIC_SUSPEND_TIMEOUT);
255                 /* Force reset the card if the shutdown completion timed out */
256                 if (!rc) {
257                         mutex_lock(&mdev->mic_mutex);
258                         mic_set_state(mdev, MIC_SUSPENDED);
259                         mutex_unlock(&mdev->mic_mutex);
260                         mic_stop(mdev, true);
261                 }
262                 break;
263         case MIC_SHUTTING_DOWN:
264                 /*
265                  * Card is shutting down. Set state to MIC_SUSPENDED
266                  * to prevent further boot of the card.
267                  */
268                 mic_set_state(mdev, MIC_SUSPENDED);
269                 mutex_unlock(&mdev->mic_mutex);
270                 rc = wait_for_completion_timeout(&mdev->reset_wait,
271                                                 MIC_SUSPEND_TIMEOUT);
272                 /* Force reset the card if the shutdown completion timed out */
273                 if (!rc)
274                         mic_stop(mdev, true);
275                 break;
276         default:
277                 mutex_unlock(&mdev->mic_mutex);
278                 break;
279         }
280 }
281
282 /**
283  * mic_suspend - Initiate MIC suspend. Suspend merely issues card shutdown.
284  * @mdev: pointer to mic_device instance
285  *
286  * RETURNS: None.
287  */
288 void mic_suspend(struct mic_device *mdev)
289 {
290         struct mic_bootparam *bootparam = mdev->dp;
291         s8 db = bootparam->h2c_shutdown_db;
292
293         mutex_lock(&mdev->mic_mutex);
294         if (MIC_SUSPENDING == mdev->state && db != -1) {
295                 bootparam->shutdown_card = 1;
296                 mdev->ops->send_intr(mdev, db);
297                 mic_set_state(mdev, MIC_SUSPENDED);
298         }
299         mutex_unlock(&mdev->mic_mutex);
300 }