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