linux/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
<<
>>
Prefs
   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 */
  56int 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 */
  80int 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 */
 149int 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 */
 255int 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 */
 281int 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 */
 343int 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 */
 376int 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
 414void 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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.