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