1 /*
2 * tiomap_pwr.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Implementation of DSP wake/sleep routines.
7 *
8 * Copyright (C) 2007-2008 Texas Instruments, Inc.
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19 /* ----------------------------------- Host OS */
20 #include <dspbridge/host_os.h>
21
22 #include <plat/dsp.h>
23
24 /* ----------------------------------- DSP/BIOS Bridge */
25 #include <dspbridge/dbdefs.h>
26 #include <dspbridge/drv.h>
27 #include <dspbridge/io_sm.h>
28
29 /* ----------------------------------- Platform Manager */
30 #include <dspbridge/brddefs.h>
31 #include <dspbridge/dev.h>
32 #include <dspbridge/io.h>
33
34 /* ------------------------------------ Hardware Abstraction Layer */
35 #include <hw_defs.h>
36 #include <hw_mmu.h>
37
38 #include <dspbridge/pwr.h>
39
40 /* ----------------------------------- Bridge Driver */
41 #include <dspbridge/dspdeh.h>
42 #include <dspbridge/wdt.h>
43
44 /* ----------------------------------- specific to this file */
45 #include "_tiomap.h"
46 #include "_tiomap_pwr.h"
47 #include <mach-omap2/prm-regbits-34xx.h>
48 #include <mach-omap2/cm-regbits-34xx.h>
49
50 #define PWRSTST_TIMEOUT 200
51
52 /*
53 * ======== handle_constraints_set ========
54 * Sets new DSP constraint
55 */
handle_constraints_set(struct bridge_dev_context * dev_context,void * pargs)56 int handle_constraints_set(struct bridge_dev_context *dev_context,
57 void *pargs)
58 {
59 #ifdef CONFIG_TIDSPBRIDGE_DVFS
60 u32 *constraint_val;
61 struct omap_dsp_platform_data *pdata =
62 omap_dspbridge_dev->dev.platform_data;
63
64 constraint_val = (u32 *) (pargs);
65 /* Read the target value requested by DSP */
66 dev_dbg(bridge, "OPP: %s opp requested = 0x%x\n", __func__,
67 (u32) *(constraint_val + 1));
68
69 /* Set the new opp value */
70 if (pdata->dsp_set_min_opp)
71 (*pdata->dsp_set_min_opp) ((u32) *(constraint_val + 1));
72 #endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
73 return 0;
74 }
75
76 /*
77 * ======== handle_hibernation_from_dsp ========
78 * Handle Hibernation requested from DSP
79 */
handle_hibernation_from_dsp(struct bridge_dev_context * dev_context)80 int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context)
81 {
82 int status = 0;
83 #ifdef CONFIG_PM
84 u16 timeout = PWRSTST_TIMEOUT / 10;
85 u32 pwr_state;
86 #ifdef CONFIG_TIDSPBRIDGE_DVFS
87 u32 opplevel;
88 struct io_mgr *hio_mgr;
89 #endif
90 struct omap_dsp_platform_data *pdata =
91 omap_dspbridge_dev->dev.platform_data;
92
93 pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
94 OMAP_POWERSTATEST_MASK;
95 /* Wait for DSP to move into OFF state */
96 while ((pwr_state != PWRDM_POWER_OFF) && --timeout) {
97 if (msleep_interruptible(10)) {
98 pr_err("Waiting for DSP OFF mode interrupted\n");
99 return -EPERM;
100 }
101 pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
102 OMAP2_PM_PWSTST) & OMAP_POWERSTATEST_MASK;
103 }
104 if (timeout == 0) {
105 pr_err("%s: Timed out waiting for DSP off mode\n", __func__);
106 status = -ETIMEDOUT;
107 return status;
108 } else {
109
110 /* Save mailbox settings */
111 omap_mbox_save_ctx(dev_context->mbox);
112
113 /* Turn off DSP Peripheral clocks and DSP Load monitor timer */
114 status = dsp_clock_disable_all(dev_context->dsp_per_clks);
115
116 /* Disable wdt on hibernation. */
117 dsp_wdt_enable(false);
118
119 if (!status) {
120 /* Update the Bridger Driver state */
121 dev_context->brd_state = BRD_DSP_HIBERNATION;
122 #ifdef CONFIG_TIDSPBRIDGE_DVFS
123 status =
124 dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
125 if (!hio_mgr) {
126 status = DSP_EHANDLE;
127 return status;
128 }
129 io_sh_msetting(hio_mgr, SHM_GETOPP, &opplevel);
130
131 /*
132 * Set the OPP to low level before moving to OFF
133 * mode
134 */
135 if (pdata->dsp_set_min_opp)
136 (*pdata->dsp_set_min_opp) (VDD1_OPP1);
137 status = 0;
138 #endif /* CONFIG_TIDSPBRIDGE_DVFS */
139 }
140 }
141 #endif
142 return status;
143 }
144
145 /*
146 * ======== sleep_dsp ========
147 * Put DSP in low power consuming state.
148 */
sleep_dsp(struct bridge_dev_context * dev_context,u32 dw_cmd,void * pargs)149 int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
150 void *pargs)
151 {
152 int status = 0;
153 #ifdef CONFIG_PM
154 #ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
155 struct deh_mgr *hdeh_mgr;
156 #endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
157 u16 timeout = PWRSTST_TIMEOUT / 10;
158 u32 pwr_state, target_pwr_state;
159 struct omap_dsp_platform_data *pdata =
160 omap_dspbridge_dev->dev.platform_data;
161
162 /* Check if sleep code is valid */
163 if ((dw_cmd != PWR_DEEPSLEEP) && (dw_cmd != PWR_EMERGENCYDEEPSLEEP))
164 return -EINVAL;
165
166 switch (dev_context->brd_state) {
167 case BRD_RUNNING:
168 omap_mbox_save_ctx(dev_context->mbox);
169 if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
170 sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
171 dev_dbg(bridge, "PM: %s - sent hibernate cmd to DSP\n",
172 __func__);
173 target_pwr_state = PWRDM_POWER_OFF;
174 } else {
175 sm_interrupt_dsp(dev_context, MBX_PM_DSPRETENTION);
176 target_pwr_state = PWRDM_POWER_RET;
177 }
178 break;
179 case BRD_RETENTION:
180 omap_mbox_save_ctx(dev_context->mbox);
181 if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
182 sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
183 target_pwr_state = PWRDM_POWER_OFF;
184 } else
185 return 0;
186 break;
187 case BRD_HIBERNATION:
188 case BRD_DSP_HIBERNATION:
189 /* Already in Hibernation, so just return */
190 dev_dbg(bridge, "PM: %s - DSP already in hibernation\n",
191 __func__);
192 return 0;
193 case BRD_STOPPED:
194 dev_dbg(bridge, "PM: %s - Board in STOP state\n", __func__);
195 return 0;
196 default:
197 dev_dbg(bridge, "PM: %s - Bridge in Illegal state\n", __func__);
198 return -EPERM;
199 }
200
201 /* Get the PRCM DSP power domain status */
202 pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
203 OMAP_POWERSTATEST_MASK;
204
205 /* Wait for DSP to move into target power state */
206 while ((pwr_state != target_pwr_state) && --timeout) {
207 if (msleep_interruptible(10)) {
208 pr_err("Waiting for DSP to Suspend interrupted\n");
209 return -EPERM;
210 }
211 pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
212 OMAP2_PM_PWSTST) & OMAP_POWERSTATEST_MASK;
213 }
214
215 if (!timeout) {
216 pr_err("%s: Timed out waiting for DSP off mode, state %x\n",
217 __func__, pwr_state);
218 #ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
219 dev_get_deh_mgr(dev_context->dev_obj, &hdeh_mgr);
220 bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0);
221 #endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
222 return -ETIMEDOUT;
223 } else {
224 /* Update the Bridger Driver state */
225 if (dsp_test_sleepstate == PWRDM_POWER_OFF)
226 dev_context->brd_state = BRD_HIBERNATION;
227 else
228 dev_context->brd_state = BRD_RETENTION;
229
230 /* Disable wdt on hibernation. */
231 dsp_wdt_enable(false);
232
233 /* Turn off DSP Peripheral clocks */
234 status = dsp_clock_disable_all(dev_context->dsp_per_clks);
235 if (status)
236 return status;
237 #ifdef CONFIG_TIDSPBRIDGE_DVFS
238 else if (target_pwr_state == PWRDM_POWER_OFF) {
239 /*
240 * Set the OPP to low level before moving to OFF mode
241 */
242 if (pdata->dsp_set_min_opp)
243 (*pdata->dsp_set_min_opp) (VDD1_OPP1);
244 }
245 #endif /* CONFIG_TIDSPBRIDGE_DVFS */
246 }
247 #endif /* CONFIG_PM */
248 return status;
249 }
250
251 /*
252 * ======== wake_dsp ========
253 * Wake up DSP from sleep.
254 */
wake_dsp(struct bridge_dev_context * dev_context,void * pargs)255 int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
256 {
257 int status = 0;
258 #ifdef CONFIG_PM
259
260 /* Check the board state, if it is not 'SLEEP' then return */
261 if (dev_context->brd_state == BRD_RUNNING ||
262 dev_context->brd_state == BRD_STOPPED) {
263 /* The Device is in 'RET' or 'OFF' state and Bridge state is not
264 * 'SLEEP', this means state inconsistency, so return */
265 return 0;
266 }
267
268 /* Send a wakeup message to DSP */
269 sm_interrupt_dsp(dev_context, MBX_PM_DSPWAKEUP);
270
271 /* Set the device state to RUNNIG */
272 dev_context->brd_state = BRD_RUNNING;
273 #endif /* CONFIG_PM */
274 return status;
275 }
276
277 /*
278 * ======== dsp_peripheral_clk_ctrl ========
279 * Enable/Disable the DSP peripheral clocks as needed..
280 */
dsp_peripheral_clk_ctrl(struct bridge_dev_context * dev_context,void * pargs)281 int dsp_peripheral_clk_ctrl(struct bridge_dev_context *dev_context,
282 void *pargs)
283 {
284 u32 ext_clk = 0;
285 u32 ext_clk_id = 0;
286 u32 ext_clk_cmd = 0;
287 u32 clk_id_index = MBX_PM_MAX_RESOURCES;
288 u32 tmp_index;
289 u32 dsp_per_clks_before;
290 int status = 0;
291
292 dsp_per_clks_before = dev_context->dsp_per_clks;
293
294 ext_clk = (u32) *((u32 *) pargs);
295 ext_clk_id = ext_clk & MBX_PM_CLK_IDMASK;
296
297 /* process the power message -- TODO, keep it in a separate function */
298 for (tmp_index = 0; tmp_index < MBX_PM_MAX_RESOURCES; tmp_index++) {
299 if (ext_clk_id == bpwr_clkid[tmp_index]) {
300 clk_id_index = tmp_index;
301 break;
302 }
303 }
304 /* TODO -- Assert may be a too hard restriction here.. May be we should
305 * just return with failure when the CLK ID does not match */
306 /* DBC_ASSERT(clk_id_index < MBX_PM_MAX_RESOURCES); */
307 if (clk_id_index == MBX_PM_MAX_RESOURCES) {
308 /* return with a more meaningfull error code */
309 return -EPERM;
310 }
311 ext_clk_cmd = (ext_clk >> MBX_PM_CLK_CMDSHIFT) & MBX_PM_CLK_CMDMASK;
312 switch (ext_clk_cmd) {
313 case BPWR_DISABLE_CLOCK:
314 status = dsp_clk_disable(bpwr_clks[clk_id_index].clk);
315 dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id,
316 false);
317 if (!status) {
318 (dev_context->dsp_per_clks) &=
319 (~((u32) (1 << bpwr_clks[clk_id_index].clk)));
320 }
321 break;
322 case BPWR_ENABLE_CLOCK:
323 status = dsp_clk_enable(bpwr_clks[clk_id_index].clk);
324 dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id, true);
325 if (!status)
326 (dev_context->dsp_per_clks) |=
327 (1 << bpwr_clks[clk_id_index].clk);
328 break;
329 default:
330 dev_dbg(bridge, "%s: Unsupported CMD\n", __func__);
331 /* unsupported cmd */
332 /* TODO -- provide support for AUTOIDLE Enable/Disable
333 * commands */
334 }
335 return status;
336 }
337
338 /*
339 * ========pre_scale_dsp========
340 * Sends prescale notification to DSP
341 *
342 */
pre_scale_dsp(struct bridge_dev_context * dev_context,void * pargs)343 int pre_scale_dsp(struct bridge_dev_context *dev_context, void *pargs)
344 {
345 #ifdef CONFIG_TIDSPBRIDGE_DVFS
346 u32 level;
347 u32 voltage_domain;
348
349 voltage_domain = *((u32 *) pargs);
350 level = *((u32 *) pargs + 1);
351
352 dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
353 __func__, voltage_domain, level);
354 if ((dev_context->brd_state == BRD_HIBERNATION) ||
355 (dev_context->brd_state == BRD_RETENTION) ||
356 (dev_context->brd_state == BRD_DSP_HIBERNATION)) {
357 dev_dbg(bridge, "OPP: %s IVA in sleep. No message to DSP\n");
358 return 0;
359 } else if ((dev_context->brd_state == BRD_RUNNING)) {
360 /* Send a prenotificatio to DSP */
361 dev_dbg(bridge, "OPP: %s sent notification to DSP\n", __func__);
362 sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_PRENOTIFY);
363 return 0;
364 } else {
365 return -EPERM;
366 }
367 #endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
368 return 0;
369 }
370
371 /*
372 * ========post_scale_dsp========
373 * Sends postscale notification to DSP
374 *
375 */
post_scale_dsp(struct bridge_dev_context * dev_context,void * pargs)376 int post_scale_dsp(struct bridge_dev_context *dev_context,
377 void *pargs)
378 {
379 int status = 0;
380 #ifdef CONFIG_TIDSPBRIDGE_DVFS
381 u32 level;
382 u32 voltage_domain;
383 struct io_mgr *hio_mgr;
384
385 status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
386 if (!hio_mgr)
387 return -EFAULT;
388
389 voltage_domain = *((u32 *) pargs);
390 level = *((u32 *) pargs + 1);
391 dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
392 __func__, voltage_domain, level);
393 if ((dev_context->brd_state == BRD_HIBERNATION) ||
394 (dev_context->brd_state == BRD_RETENTION) ||
395 (dev_context->brd_state == BRD_DSP_HIBERNATION)) {
396 /* Update the OPP value in shared memory */
397 io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
398 dev_dbg(bridge, "OPP: %s IVA in sleep. Wrote to shm\n",
399 __func__);
400 } else if ((dev_context->brd_state == BRD_RUNNING)) {
401 /* Update the OPP value in shared memory */
402 io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
403 /* Send a post notification to DSP */
404 sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_POSTNOTIFY);
405 dev_dbg(bridge, "OPP: %s wrote to shm. Sent post notification "
406 "to DSP\n", __func__);
407 } else {
408 status = -EPERM;
409 }
410 #endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
411 return status;
412 }
413
dsp_clk_wakeup_event_ctrl(u32 clock_id,bool enable)414 void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable)
415 {
416 struct cfg_hostres *resources;
417 int status = 0;
418 u32 iva2_grpsel;
419 u32 mpu_grpsel;
420 struct dev_object *hdev_object = NULL;
421 struct bridge_dev_context *bridge_context = NULL;
422
423 hdev_object = (struct dev_object *)drv_get_first_dev_object();
424 if (!hdev_object)
425 return;
426
427 status = dev_get_bridge_context(hdev_object, &bridge_context);
428 if (!bridge_context)
429 return;
430
431 resources = bridge_context->resources;
432 if (!resources)
433 return;
434
435 switch (clock_id) {
436 case BPWR_GP_TIMER5:
437 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
438 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
439 if (enable) {
440 iva2_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
441 mpu_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
442 } else {
443 mpu_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
444 iva2_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
445 }
446 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
447 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
448 break;
449 case BPWR_GP_TIMER6:
450 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
451 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
452 if (enable) {
453 iva2_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
454 mpu_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
455 } else {
456 mpu_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
457 iva2_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
458 }
459 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
460 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
461 break;
462 case BPWR_GP_TIMER7:
463 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
464 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
465 if (enable) {
466 iva2_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
467 mpu_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
468 } else {
469 mpu_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
470 iva2_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
471 }
472 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
473 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
474 break;
475 case BPWR_GP_TIMER8:
476 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
477 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
478 if (enable) {
479 iva2_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
480 mpu_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
481 } else {
482 mpu_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
483 iva2_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
484 }
485 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
486 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
487 break;
488 case BPWR_MCBSP1:
489 iva2_grpsel = readl(resources->core_pm_base + 0xA8);
490 mpu_grpsel = readl(resources->core_pm_base + 0xA4);
491 if (enable) {
492 iva2_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
493 mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
494 } else {
495 mpu_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
496 iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
497 }
498 writel(iva2_grpsel, resources->core_pm_base + 0xA8);
499 writel(mpu_grpsel, resources->core_pm_base + 0xA4);
500 break;
501 case BPWR_MCBSP2:
502 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
503 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
504 if (enable) {
505 iva2_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
506 mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
507 } else {
508 mpu_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
509 iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
510 }
511 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
512 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
513 break;
514 case BPWR_MCBSP3:
515 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
516 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
517 if (enable) {
518 iva2_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
519 mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
520 } else {
521 mpu_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
522 iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
523 }
524 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
525 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
526 break;
527 case BPWR_MCBSP4:
528 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
529 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
530 if (enable) {
531 iva2_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
532 mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
533 } else {
534 mpu_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
535 iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
536 }
537 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
538 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
539 break;
540 case BPWR_MCBSP5:
541 iva2_grpsel = readl(resources->per_pm_base + 0xA8);
542 mpu_grpsel = readl(resources->per_pm_base + 0xA4);
543 if (enable) {
544 iva2_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
545 mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
546 } else {
547 mpu_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
548 iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
549 }
550 writel(iva2_grpsel, resources->per_pm_base + 0xA8);
551 writel(mpu_grpsel, resources->per_pm_base + 0xA4);
552 break;
553 }
554 }
555