Merge branch 'staging-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / tidspbridge / core / tiomap3430_pwr.c
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/iodefs.h>
33
34 /* ------------------------------------ Hardware Abstraction Layer */
35 #include <hw_defs.h>
36 #include <hw_mmu.h>
37
38 #include <dspbridge/pwr_sh.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  */
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  */
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->dw_brd_state = BRD_DSP_HIBERNATION;
122 #ifdef CONFIG_TIDSPBRIDGE_DVFS
123                         status =
124                             dev_get_io_mgr(dev_context->hdev_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  */
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->dw_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->hdev_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->dw_brd_state = BRD_HIBERNATION;
227                 else
228                         dev_context->dw_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  */
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->dw_brd_state == BRD_RUNNING ||
262             dev_context->dw_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->dw_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  */
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  */
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->dw_brd_state == BRD_HIBERNATION) ||
355             (dev_context->dw_brd_state == BRD_RETENTION) ||
356             (dev_context->dw_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->dw_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  */
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->hdev_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->dw_brd_state == BRD_HIBERNATION) ||
394             (dev_context->dw_brd_state == BRD_RETENTION) ||
395             (dev_context->dw_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->dw_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
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->dw_per_pm_base + 0xA8);
438                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
447                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
448                 break;
449         case BPWR_GP_TIMER6:
450                 iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
451                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
460                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
461                 break;
462         case BPWR_GP_TIMER7:
463                 iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
464                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
473                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
474                 break;
475         case BPWR_GP_TIMER8:
476                 iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
477                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
486                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
487                 break;
488         case BPWR_MCBSP1:
489                 iva2_grpsel = readl(resources->dw_core_pm_base + 0xA8);
490                 mpu_grpsel = readl(resources->dw_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->dw_core_pm_base + 0xA8);
499                 writel(mpu_grpsel, resources->dw_core_pm_base + 0xA4);
500                 break;
501         case BPWR_MCBSP2:
502                 iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
503                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
512                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
513                 break;
514         case BPWR_MCBSP3:
515                 iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
516                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
525                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
526                 break;
527         case BPWR_MCBSP4:
528                 iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
529                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
538                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
539                 break;
540         case BPWR_MCBSP5:
541                 iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8);
542                 mpu_grpsel = readl(resources->dw_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->dw_per_pm_base + 0xA8);
551                 writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4);
552                 break;
553         }
554 }