uboot/arch/arm/mach-keystone/psc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Keystone: PSC configuration module
   4 *
   5 * (C) Copyright 2012-2014
   6 *     Texas Instruments Incorporated, <www.ti.com>
   7 */
   8
   9#include <common.h>
  10#include <linux/delay.h>
  11#include <linux/errno.h>
  12#include <asm/io.h>
  13#include <asm/processor.h>
  14#include <asm/arch/psc_defs.h>
  15
  16/**
  17 * psc_delay() - delay for psc
  18 *
  19 * Return: 10
  20 */
  21int psc_delay(void)
  22{
  23        udelay(10);
  24        return 10;
  25}
  26
  27/**
  28 * psc_wait() - Wait for end of transitional state
  29 * @domain_num: GPSC domain number
  30 *
  31 * Polls pstat for the selected domain and waits for transitions to be complete.
  32 * Since this is boot loader code it is *ASSUMED* that interrupts are disabled
  33 * and no other core is mucking around with the psc at the same time.
  34 *
  35 * Return: 0 when the domain is free. Returns -1 if a timeout occurred waiting
  36 * for the completion.
  37 */
  38int psc_wait(u32 domain_num)
  39{
  40        u32 retry;
  41        u32 ptstat;
  42
  43        /*
  44         * Do nothing if the power domain is in transition. This should never
  45         * happen since the boot code is the only software accesses psc.
  46         * It's still remotely possible that the hardware state machines
  47         * initiate transitions.
  48         * Don't trap if the domain (or a module in this domain) is
  49         * stuck in transition.
  50         */
  51        retry = 0;
  52
  53        do {
  54                ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT);
  55                ptstat = ptstat & (1 << domain_num);
  56        } while ((ptstat != 0) && ((retry += psc_delay()) <
  57                 PSC_PTSTAT_TIMEOUT_LIMIT));
  58
  59        if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
  60                return -1;
  61
  62        return 0;
  63}
  64
  65/**
  66 * psc_get_domain_num() - Get the domain number
  67 * @mod_num:    LPSC module number
  68 */
  69u32 psc_get_domain_num(u32 mod_num)
  70{
  71        u32 domain_num;
  72
  73        /* Get the power domain associated with the module number */
  74        domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
  75        domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
  76
  77        return domain_num;
  78}
  79
  80/**
  81 * psc_set_state() - powers up/down a module
  82 * @mod_num:    LPSC module number
  83 * @state:      1 to enable, 0 to disable.
  84 *
  85 * Powers up/down the requested module and the associated power domain if
  86 * required. No action is taken it the module is already powered up/down.
  87 * This only controls modules. The domain in which the module resides will
  88 * be left in the power on state. Multiple modules can exist in a power
  89 * domain, so powering down the domain based on a single module is not done.
  90 *
  91 * Return: 0 on success, -1 if the module can't be powered up, or if there is a
  92 * timeout waiting for the transition.
  93 */
  94int psc_set_state(u32 mod_num, u32 state)
  95{
  96        u32 domain_num;
  97        u32 pdctl;
  98        u32 mdctl;
  99        u32 ptcmd;
 100        u32 reset_iso;
 101        u32 v;
 102
 103        /*
 104         * Get the power domain associated with the module number, and reset
 105         * isolation functionality
 106         */
 107        v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
 108        domain_num = PSC_REG_MDCFG_GET_PD(v);
 109        reset_iso  = PSC_REG_MDCFG_GET_RESET_ISO(v);
 110
 111        /* Wait for the status of the domain/module to be non-transitional */
 112        if (psc_wait(domain_num) != 0)
 113                return -1;
 114
 115        /*
 116         * Perform configuration even if the current status matches the
 117         * existing state
 118         *
 119         * Set the next state of the power domain to on. It's OK if the domain
 120         * is always on. This code will not ever power down a domain, so no
 121         * change is made if the new state is power down.
 122         */
 123        if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
 124                pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
 125                pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
 126                                               PSC_REG_VAL_PDCTL_NEXT_ON);
 127                __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
 128        }
 129
 130        /* Set the next state for the module to enabled/disabled */
 131        mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 132        mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
 133        mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
 134        __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 135
 136        /* Trigger the enable */
 137        ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
 138        ptcmd |= (u32)(1<<domain_num);
 139        __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
 140
 141        /* Wait on the complete */
 142        return psc_wait(domain_num);
 143}
 144
 145/**
 146 * psc_enable_module() - power up a module
 147 * @mod_num:    LPSC module number
 148 *
 149 * Powers up the requested module and the associated power domain
 150 * if required. No action is taken it the module is already powered up.
 151 *
 152 * Return: 0 on success, -1 if the module can't be powered up, or
 153 * if there is a timeout waiting for the transition.
 154 *
 155 */
 156int psc_enable_module(u32 mod_num)
 157{
 158        u32 mdctl;
 159
 160        /* Set the bit to apply reset */
 161        mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 162        if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
 163                return 0;
 164
 165        return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
 166}
 167
 168/**
 169 * psc_disable_module() - Power down a module
 170 * @mod_num:    LPSC module number
 171 *
 172 * Return: 0 on success, -1 on failure or timeout.
 173 */
 174int psc_disable_module(u32 mod_num)
 175{
 176        u32 mdctl;
 177
 178        /* Set the bit to apply reset */
 179        mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 180        if ((mdctl & 0x3f) == 0)
 181                return 0;
 182        mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
 183        __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 184
 185        return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
 186}
 187
 188/**
 189 * psc_set_reset_iso() - Set the reset isolation bit in mdctl
 190 * @mod_num:    LPSC module number
 191 *
 192 * The reset isolation enable bit is set. The state of the module is not
 193 * changed.
 194 *
 195 * Return: 0 if the module config showed that reset isolation is supported.
 196 * Returns 1 otherwise. This is not an error, but setting the bit in mdctl
 197 * has no effect.
 198 */
 199int psc_set_reset_iso(u32 mod_num)
 200{
 201        u32 v;
 202        u32 mdctl;
 203
 204        /* Set the reset isolation bit */
 205        mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 206        mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
 207        __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 208
 209        v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
 210        if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
 211                return 0;
 212
 213        return 1;
 214}
 215
 216/**
 217 * psc_disable_domain() - Disable a power domain
 218 * @domain_num: GPSC domain number
 219 */
 220int psc_disable_domain(u32 domain_num)
 221{
 222        u32 pdctl;
 223        u32 ptcmd;
 224
 225        pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
 226        pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
 227        pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
 228        __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
 229
 230        ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
 231        ptcmd |= (u32)(1 << domain_num);
 232        __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
 233
 234        return psc_wait(domain_num);
 235}
 236
 237/**
 238 * psc_module_keep_in_reset_enabled() - Keep module in enabled,in-reset state
 239 * @mod_num:    LPSC module number
 240 * @gate_clocks: Can the clocks be gated on this module?
 241 *
 242 * Enable the module, but do not release the module from local reset. This is
 243 * necessary for many processor systems on keystone SoCs to allow for system
 244 * initialization from a master processor prior to releasing the processor
 245 * from reset.
 246 */
 247int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks)
 248{
 249        u32 mdctl, ptcmd, mdstat;
 250        u32 next_state;
 251        int domain_num = psc_get_domain_num(mod_num);
 252        int timeout = 100000;
 253
 254        /* Wait for any previous transitions to complete */
 255        psc_wait(domain_num);
 256        mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 257        /* Should be set 0 to assert Local reset */
 258        if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1))) {
 259                mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
 260                __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 261                /* Wait for transition to take place */
 262                psc_wait(domain_num);
 263        }
 264
 265        /* Clear Module reset */
 266        mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 267        next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF :
 268                        PSC_REG_VAL_MDCTL_NEXT_ON;
 269        mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, next_state);
 270        __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 271        /* Trigger PD transition */
 272        ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
 273        ptcmd |= (u32)(1 << domain_num);
 274        __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
 275        psc_wait(domain_num);
 276
 277        mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
 278        while (timeout) {
 279                mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
 280
 281                if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
 282                    PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
 283                    PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
 284                        break;
 285                timeout--;
 286        }
 287
 288        if (!timeout) {
 289                printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
 290                       __func__, mdstat);
 291                return -ETIMEDOUT;
 292        }
 293        return 0;
 294}
 295
 296/**
 297 * psc_module_release_from_reset() - Release the module from reset
 298 * @mod_num:    LPSC module number
 299 *
 300 * This is the follow through for the command 'psc_module_keep_in_reset_enabled'
 301 * Allowing the module to be released from reset once all required inits are
 302 * complete for the module. Typically, this allows the processor module to start
 303 * execution.
 304 */
 305int psc_module_release_from_reset(u32 mod_num)
 306{
 307        u32 mdctl, mdstat;
 308        int domain_num = psc_get_domain_num(mod_num);
 309        int timeout = 100000;
 310
 311        /* Wait for any previous transitions to complete */
 312        psc_wait(domain_num);
 313        mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 314        /* Should be set to 1 to de-assert Local reset */
 315        if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0))) {
 316                mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1);
 317                __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
 318                /* Wait for transition to take place */
 319                psc_wait(domain_num);
 320        }
 321        mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
 322        while (timeout) {
 323                mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
 324
 325                if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
 326                    PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
 327                    PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
 328                        break;
 329                timeout--;
 330        }
 331
 332        if (!timeout) {
 333                printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
 334                       __func__, mdstat);
 335                return -ETIMEDOUT;
 336        }
 337
 338        return 0;
 339}
 340