root/arch/arm/mach-omap2/cm3xxx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _write_clktrctrl
  2. omap3xxx_cm_is_clkdm_in_hwsup
  3. omap3xxx_cm_clkdm_enable_hwsup
  4. omap3xxx_cm_clkdm_disable_hwsup
  5. omap3xxx_cm_clkdm_force_sleep
  6. omap3xxx_cm_clkdm_force_wakeup
  7. omap3xxx_cm_wait_module_ready
  8. omap3xxx_cm_split_idlest_reg
  9. omap3xxx_clkdm_add_sleepdep
  10. omap3xxx_clkdm_del_sleepdep
  11. omap3xxx_clkdm_read_sleepdep
  12. omap3xxx_clkdm_clear_all_sleepdeps
  13. omap3xxx_clkdm_sleep
  14. omap3xxx_clkdm_wakeup
  15. omap3xxx_clkdm_allow_idle
  16. omap3xxx_clkdm_deny_idle
  17. omap3xxx_clkdm_clk_enable
  18. omap3xxx_clkdm_clk_disable
  19. omap3_cm_save_context
  20. omap3_cm_restore_context
  21. omap3_cm_save_scratchpad_contents
  22. omap3xxx_cm_init
  23. omap3xxx_cm_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * OMAP3xxx CM module functions
   4  *
   5  * Copyright (C) 2009 Nokia Corporation
   6  * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
   7  * Paul Walmsley
   8  * Rajendra Nayak <rnayak@ti.com>
   9  */
  10 
  11 #include <linux/kernel.h>
  12 #include <linux/types.h>
  13 #include <linux/delay.h>
  14 #include <linux/errno.h>
  15 #include <linux/err.h>
  16 #include <linux/io.h>
  17 
  18 #include "prm2xxx_3xxx.h"
  19 #include "cm.h"
  20 #include "cm3xxx.h"
  21 #include "cm-regbits-34xx.h"
  22 #include "clockdomain.h"
  23 
  24 static const u8 omap3xxx_cm_idlest_offs[] = {
  25         CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
  26 };
  27 
  28 /*
  29  *
  30  */
  31 
  32 static void _write_clktrctrl(u8 c, s16 module, u32 mask)
  33 {
  34         u32 v;
  35 
  36         v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
  37         v &= ~mask;
  38         v |= c << __ffs(mask);
  39         omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
  40 }
  41 
  42 static bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
  43 {
  44         u32 v;
  45 
  46         v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
  47         v &= mask;
  48         v >>= __ffs(mask);
  49 
  50         return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
  51 }
  52 
  53 static void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
  54 {
  55         _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
  56 }
  57 
  58 static void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
  59 {
  60         _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
  61 }
  62 
  63 static void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
  64 {
  65         _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
  66 }
  67 
  68 static void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
  69 {
  70         _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
  71 }
  72 
  73 /*
  74  *
  75  */
  76 
  77 /**
  78  * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
  79  * @part: PRCM partition, ignored for OMAP3
  80  * @prcm_mod: PRCM module offset
  81  * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
  82  * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
  83  *
  84  * Wait for the PRCM to indicate that the module identified by
  85  * (@prcm_mod, @idlest_id, @idlest_shift) is clocked.  Return 0 upon
  86  * success or -EBUSY if the module doesn't enable in time.
  87  */
  88 static int omap3xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id,
  89                                          u8 idlest_shift)
  90 {
  91         int ena = 0, i = 0;
  92         u8 cm_idlest_reg;
  93         u32 mask;
  94 
  95         if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs)))
  96                 return -EINVAL;
  97 
  98         cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1];
  99 
 100         mask = 1 << idlest_shift;
 101         ena = 0;
 102 
 103         omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
 104                             mask) == ena), MAX_MODULE_READY_TIME, i);
 105 
 106         return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
 107 }
 108 
 109 /**
 110  * omap3xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components
 111  * @idlest_reg: CM_IDLEST* virtual address
 112  * @prcm_inst: pointer to an s16 to return the PRCM instance offset
 113  * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
 114  *
 115  * XXX This function is only needed until absolute register addresses are
 116  * removed from the OMAP struct clk records.
 117  */
 118 static int omap3xxx_cm_split_idlest_reg(struct clk_omap_reg *idlest_reg,
 119                                         s16 *prcm_inst,
 120                                         u8 *idlest_reg_id)
 121 {
 122         unsigned long offs;
 123         u8 idlest_offs;
 124         int i;
 125 
 126         idlest_offs = idlest_reg->offset & 0xff;
 127         for (i = 0; i < ARRAY_SIZE(omap3xxx_cm_idlest_offs); i++) {
 128                 if (idlest_offs == omap3xxx_cm_idlest_offs[i]) {
 129                         *idlest_reg_id = i + 1;
 130                         break;
 131                 }
 132         }
 133 
 134         if (i == ARRAY_SIZE(omap3xxx_cm_idlest_offs))
 135                 return -EINVAL;
 136 
 137         offs = idlest_reg->offset;
 138         offs &= 0xff00;
 139         *prcm_inst = offs;
 140 
 141         return 0;
 142 }
 143 
 144 /* Clockdomain low-level operations */
 145 
 146 static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1,
 147                                        struct clockdomain *clkdm2)
 148 {
 149         omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
 150                                   clkdm1->pwrdm.ptr->prcm_offs,
 151                                   OMAP3430_CM_SLEEPDEP);
 152         return 0;
 153 }
 154 
 155 static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1,
 156                                        struct clockdomain *clkdm2)
 157 {
 158         omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
 159                                     clkdm1->pwrdm.ptr->prcm_offs,
 160                                     OMAP3430_CM_SLEEPDEP);
 161         return 0;
 162 }
 163 
 164 static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
 165                                         struct clockdomain *clkdm2)
 166 {
 167         return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
 168                                             OMAP3430_CM_SLEEPDEP,
 169                                             (1 << clkdm2->dep_bit));
 170 }
 171 
 172 static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
 173 {
 174         struct clkdm_dep *cd;
 175         u32 mask = 0;
 176 
 177         for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
 178                 if (!cd->clkdm)
 179                         continue; /* only happens if data is erroneous */
 180 
 181                 mask |= 1 << cd->clkdm->dep_bit;
 182                 cd->sleepdep_usecount = 0;
 183         }
 184         omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
 185                                     OMAP3430_CM_SLEEPDEP);
 186         return 0;
 187 }
 188 
 189 static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
 190 {
 191         omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
 192                                       clkdm->clktrctrl_mask);
 193         return 0;
 194 }
 195 
 196 static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
 197 {
 198         omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
 199                                        clkdm->clktrctrl_mask);
 200         return 0;
 201 }
 202 
 203 static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
 204 {
 205         if (clkdm->usecount > 0)
 206                 clkdm_add_autodeps(clkdm);
 207 
 208         omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 209                                        clkdm->clktrctrl_mask);
 210 }
 211 
 212 static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
 213 {
 214         omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 215                                         clkdm->clktrctrl_mask);
 216 
 217         if (clkdm->usecount > 0)
 218                 clkdm_del_autodeps(clkdm);
 219 }
 220 
 221 static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 222 {
 223         bool hwsup = false;
 224 
 225         if (!clkdm->clktrctrl_mask)
 226                 return 0;
 227 
 228         /*
 229          * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
 230          * more details on the unpleasant problem this is working
 231          * around
 232          */
 233         if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
 234             (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
 235                 omap3xxx_clkdm_wakeup(clkdm);
 236                 return 0;
 237         }
 238 
 239         hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 240                                               clkdm->clktrctrl_mask);
 241 
 242         if (hwsup) {
 243                 /* Disable HW transitions when we are changing deps */
 244                 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 245                                                 clkdm->clktrctrl_mask);
 246                 clkdm_add_autodeps(clkdm);
 247                 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 248                                                clkdm->clktrctrl_mask);
 249         } else {
 250                 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
 251                         omap3xxx_clkdm_wakeup(clkdm);
 252         }
 253 
 254         return 0;
 255 }
 256 
 257 static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 258 {
 259         bool hwsup = false;
 260 
 261         if (!clkdm->clktrctrl_mask)
 262                 return 0;
 263 
 264         /*
 265          * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
 266          * more details on the unpleasant problem this is working
 267          * around
 268          */
 269         if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
 270             !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
 271                 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 272                                                clkdm->clktrctrl_mask);
 273                 return 0;
 274         }
 275 
 276         hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 277                                               clkdm->clktrctrl_mask);
 278 
 279         if (hwsup) {
 280                 /* Disable HW transitions when we are changing deps */
 281                 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 282                                                 clkdm->clktrctrl_mask);
 283                 clkdm_del_autodeps(clkdm);
 284                 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 285                                                clkdm->clktrctrl_mask);
 286         } else {
 287                 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
 288                         omap3xxx_clkdm_sleep(clkdm);
 289         }
 290 
 291         return 0;
 292 }
 293 
 294 struct clkdm_ops omap3_clkdm_operations = {
 295         .clkdm_add_wkdep        = omap2_clkdm_add_wkdep,
 296         .clkdm_del_wkdep        = omap2_clkdm_del_wkdep,
 297         .clkdm_read_wkdep       = omap2_clkdm_read_wkdep,
 298         .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
 299         .clkdm_add_sleepdep     = omap3xxx_clkdm_add_sleepdep,
 300         .clkdm_del_sleepdep     = omap3xxx_clkdm_del_sleepdep,
 301         .clkdm_read_sleepdep    = omap3xxx_clkdm_read_sleepdep,
 302         .clkdm_clear_all_sleepdeps      = omap3xxx_clkdm_clear_all_sleepdeps,
 303         .clkdm_sleep            = omap3xxx_clkdm_sleep,
 304         .clkdm_wakeup           = omap3xxx_clkdm_wakeup,
 305         .clkdm_allow_idle       = omap3xxx_clkdm_allow_idle,
 306         .clkdm_deny_idle        = omap3xxx_clkdm_deny_idle,
 307         .clkdm_clk_enable       = omap3xxx_clkdm_clk_enable,
 308         .clkdm_clk_disable      = omap3xxx_clkdm_clk_disable,
 309 };
 310 
 311 /*
 312  * Context save/restore code - OMAP3 only
 313  */
 314 struct omap3_cm_regs {
 315         u32 iva2_cm_clksel1;
 316         u32 iva2_cm_clksel2;
 317         u32 cm_sysconfig;
 318         u32 sgx_cm_clksel;
 319         u32 dss_cm_clksel;
 320         u32 cam_cm_clksel;
 321         u32 per_cm_clksel;
 322         u32 emu_cm_clksel;
 323         u32 emu_cm_clkstctrl;
 324         u32 pll_cm_autoidle;
 325         u32 pll_cm_autoidle2;
 326         u32 pll_cm_clksel4;
 327         u32 pll_cm_clksel5;
 328         u32 pll_cm_clken2;
 329         u32 cm_polctrl;
 330         u32 iva2_cm_fclken;
 331         u32 iva2_cm_clken_pll;
 332         u32 core_cm_fclken1;
 333         u32 core_cm_fclken3;
 334         u32 sgx_cm_fclken;
 335         u32 wkup_cm_fclken;
 336         u32 dss_cm_fclken;
 337         u32 cam_cm_fclken;
 338         u32 per_cm_fclken;
 339         u32 usbhost_cm_fclken;
 340         u32 core_cm_iclken1;
 341         u32 core_cm_iclken2;
 342         u32 core_cm_iclken3;
 343         u32 sgx_cm_iclken;
 344         u32 wkup_cm_iclken;
 345         u32 dss_cm_iclken;
 346         u32 cam_cm_iclken;
 347         u32 per_cm_iclken;
 348         u32 usbhost_cm_iclken;
 349         u32 iva2_cm_autoidle2;
 350         u32 mpu_cm_autoidle2;
 351         u32 iva2_cm_clkstctrl;
 352         u32 mpu_cm_clkstctrl;
 353         u32 core_cm_clkstctrl;
 354         u32 sgx_cm_clkstctrl;
 355         u32 dss_cm_clkstctrl;
 356         u32 cam_cm_clkstctrl;
 357         u32 per_cm_clkstctrl;
 358         u32 neon_cm_clkstctrl;
 359         u32 usbhost_cm_clkstctrl;
 360         u32 core_cm_autoidle1;
 361         u32 core_cm_autoidle2;
 362         u32 core_cm_autoidle3;
 363         u32 wkup_cm_autoidle;
 364         u32 dss_cm_autoidle;
 365         u32 cam_cm_autoidle;
 366         u32 per_cm_autoidle;
 367         u32 usbhost_cm_autoidle;
 368         u32 sgx_cm_sleepdep;
 369         u32 dss_cm_sleepdep;
 370         u32 cam_cm_sleepdep;
 371         u32 per_cm_sleepdep;
 372         u32 usbhost_cm_sleepdep;
 373         u32 cm_clkout_ctrl;
 374 };
 375 
 376 static struct omap3_cm_regs cm_context;
 377 
 378 void omap3_cm_save_context(void)
 379 {
 380         cm_context.iva2_cm_clksel1 =
 381                 omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
 382         cm_context.iva2_cm_clksel2 =
 383                 omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
 384         cm_context.cm_sysconfig =
 385                 omap2_cm_read_mod_reg(OCP_MOD, OMAP3430_CM_SYSCONFIG);
 386         cm_context.sgx_cm_clksel =
 387                 omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
 388         cm_context.dss_cm_clksel =
 389                 omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
 390         cm_context.cam_cm_clksel =
 391                 omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
 392         cm_context.per_cm_clksel =
 393                 omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
 394         cm_context.emu_cm_clksel =
 395                 omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
 396         cm_context.emu_cm_clkstctrl =
 397                 omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
 398         /*
 399          * As per erratum i671, ROM code does not respect the PER DPLL
 400          * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
 401          * In this case, even though this register has been saved in
 402          * scratchpad contents, we need to restore AUTO_PERIPH_DPLL
 403          * by ourselves. So, we need to save it anyway.
 404          */
 405         cm_context.pll_cm_autoidle =
 406                 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
 407         cm_context.pll_cm_autoidle2 =
 408                 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
 409         cm_context.pll_cm_clksel4 =
 410                 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
 411         cm_context.pll_cm_clksel5 =
 412                 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
 413         cm_context.pll_cm_clken2 =
 414                 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
 415         cm_context.cm_polctrl =
 416                 omap2_cm_read_mod_reg(OCP_MOD, OMAP3430_CM_POLCTRL);
 417         cm_context.iva2_cm_fclken =
 418                 omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
 419         cm_context.iva2_cm_clken_pll =
 420                 omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
 421         cm_context.core_cm_fclken1 =
 422                 omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
 423         cm_context.core_cm_fclken3 =
 424                 omap2_cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
 425         cm_context.sgx_cm_fclken =
 426                 omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
 427         cm_context.wkup_cm_fclken =
 428                 omap2_cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
 429         cm_context.dss_cm_fclken =
 430                 omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
 431         cm_context.cam_cm_fclken =
 432                 omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
 433         cm_context.per_cm_fclken =
 434                 omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
 435         cm_context.usbhost_cm_fclken =
 436                 omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
 437         cm_context.core_cm_iclken1 =
 438                 omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
 439         cm_context.core_cm_iclken2 =
 440                 omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
 441         cm_context.core_cm_iclken3 =
 442                 omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
 443         cm_context.sgx_cm_iclken =
 444                 omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
 445         cm_context.wkup_cm_iclken =
 446                 omap2_cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
 447         cm_context.dss_cm_iclken =
 448                 omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
 449         cm_context.cam_cm_iclken =
 450                 omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
 451         cm_context.per_cm_iclken =
 452                 omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
 453         cm_context.usbhost_cm_iclken =
 454                 omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
 455         cm_context.iva2_cm_autoidle2 =
 456                 omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
 457         cm_context.mpu_cm_autoidle2 =
 458                 omap2_cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
 459         cm_context.iva2_cm_clkstctrl =
 460                 omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
 461         cm_context.mpu_cm_clkstctrl =
 462                 omap2_cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
 463         cm_context.core_cm_clkstctrl =
 464                 omap2_cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
 465         cm_context.sgx_cm_clkstctrl =
 466                 omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL);
 467         cm_context.dss_cm_clkstctrl =
 468                 omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
 469         cm_context.cam_cm_clkstctrl =
 470                 omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
 471         cm_context.per_cm_clkstctrl =
 472                 omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
 473         cm_context.neon_cm_clkstctrl =
 474                 omap2_cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
 475         cm_context.usbhost_cm_clkstctrl =
 476                 omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
 477                                       OMAP2_CM_CLKSTCTRL);
 478         cm_context.core_cm_autoidle1 =
 479                 omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
 480         cm_context.core_cm_autoidle2 =
 481                 omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
 482         cm_context.core_cm_autoidle3 =
 483                 omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
 484         cm_context.wkup_cm_autoidle =
 485                 omap2_cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
 486         cm_context.dss_cm_autoidle =
 487                 omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
 488         cm_context.cam_cm_autoidle =
 489                 omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
 490         cm_context.per_cm_autoidle =
 491                 omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
 492         cm_context.usbhost_cm_autoidle =
 493                 omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
 494         cm_context.sgx_cm_sleepdep =
 495                 omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
 496                                       OMAP3430_CM_SLEEPDEP);
 497         cm_context.dss_cm_sleepdep =
 498                 omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
 499         cm_context.cam_cm_sleepdep =
 500                 omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
 501         cm_context.per_cm_sleepdep =
 502                 omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
 503         cm_context.usbhost_cm_sleepdep =
 504                 omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
 505                                       OMAP3430_CM_SLEEPDEP);
 506         cm_context.cm_clkout_ctrl =
 507                 omap2_cm_read_mod_reg(OMAP3430_CCR_MOD,
 508                                       OMAP3_CM_CLKOUT_CTRL_OFFSET);
 509 }
 510 
 511 void omap3_cm_restore_context(void)
 512 {
 513         omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
 514                                CM_CLKSEL1);
 515         omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
 516                                CM_CLKSEL2);
 517         omap2_cm_write_mod_reg(cm_context.cm_sysconfig, OCP_MOD,
 518                                OMAP3430_CM_SYSCONFIG);
 519         omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
 520                                CM_CLKSEL);
 521         omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
 522                                CM_CLKSEL);
 523         omap2_cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
 524                                CM_CLKSEL);
 525         omap2_cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD,
 526                                CM_CLKSEL);
 527         omap2_cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
 528                                CM_CLKSEL1);
 529         omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
 530                                OMAP2_CM_CLKSTCTRL);
 531         /*
 532          * As per erratum i671, ROM code does not respect the PER DPLL
 533          * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
 534          * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves.
 535          */
 536         omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD,
 537                                CM_AUTOIDLE);
 538         omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
 539                                CM_AUTOIDLE2);
 540         omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
 541                                OMAP3430ES2_CM_CLKSEL4);
 542         omap2_cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD,
 543                                OMAP3430ES2_CM_CLKSEL5);
 544         omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD,
 545                                OMAP3430ES2_CM_CLKEN2);
 546         omap2_cm_write_mod_reg(cm_context.cm_polctrl, OCP_MOD,
 547                                OMAP3430_CM_POLCTRL);
 548         omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
 549                                CM_FCLKEN);
 550         omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
 551                                OMAP3430_CM_CLKEN_PLL);
 552         omap2_cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD,
 553                                CM_FCLKEN1);
 554         omap2_cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD,
 555                                OMAP3430ES2_CM_FCLKEN3);
 556         omap2_cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
 557                                CM_FCLKEN);
 558         omap2_cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
 559         omap2_cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
 560                                CM_FCLKEN);
 561         omap2_cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
 562                                CM_FCLKEN);
 563         omap2_cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD,
 564                                CM_FCLKEN);
 565         omap2_cm_write_mod_reg(cm_context.usbhost_cm_fclken,
 566                                OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
 567         omap2_cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD,
 568                                CM_ICLKEN1);
 569         omap2_cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD,
 570                                CM_ICLKEN2);
 571         omap2_cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD,
 572                                CM_ICLKEN3);
 573         omap2_cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
 574                                CM_ICLKEN);
 575         omap2_cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
 576         omap2_cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
 577                                CM_ICLKEN);
 578         omap2_cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
 579                                CM_ICLKEN);
 580         omap2_cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD,
 581                                CM_ICLKEN);
 582         omap2_cm_write_mod_reg(cm_context.usbhost_cm_iclken,
 583                                OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
 584         omap2_cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD,
 585                                CM_AUTOIDLE2);
 586         omap2_cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD,
 587                                CM_AUTOIDLE2);
 588         omap2_cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
 589                                OMAP2_CM_CLKSTCTRL);
 590         omap2_cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD,
 591                                OMAP2_CM_CLKSTCTRL);
 592         omap2_cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD,
 593                                OMAP2_CM_CLKSTCTRL);
 594         omap2_cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
 595                                OMAP2_CM_CLKSTCTRL);
 596         omap2_cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
 597                                OMAP2_CM_CLKSTCTRL);
 598         omap2_cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
 599                                OMAP2_CM_CLKSTCTRL);
 600         omap2_cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
 601                                OMAP2_CM_CLKSTCTRL);
 602         omap2_cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
 603                                OMAP2_CM_CLKSTCTRL);
 604         omap2_cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl,
 605                                OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
 606         omap2_cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD,
 607                                CM_AUTOIDLE1);
 608         omap2_cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD,
 609                                CM_AUTOIDLE2);
 610         omap2_cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD,
 611                                CM_AUTOIDLE3);
 612         omap2_cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD,
 613                                CM_AUTOIDLE);
 614         omap2_cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
 615                                CM_AUTOIDLE);
 616         omap2_cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
 617                                CM_AUTOIDLE);
 618         omap2_cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD,
 619                                CM_AUTOIDLE);
 620         omap2_cm_write_mod_reg(cm_context.usbhost_cm_autoidle,
 621                                OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
 622         omap2_cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
 623                                OMAP3430_CM_SLEEPDEP);
 624         omap2_cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
 625                                OMAP3430_CM_SLEEPDEP);
 626         omap2_cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
 627                                OMAP3430_CM_SLEEPDEP);
 628         omap2_cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
 629                                OMAP3430_CM_SLEEPDEP);
 630         omap2_cm_write_mod_reg(cm_context.usbhost_cm_sleepdep,
 631                                OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
 632         omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
 633                                OMAP3_CM_CLKOUT_CTRL_OFFSET);
 634 }
 635 
 636 void omap3_cm_save_scratchpad_contents(u32 *ptr)
 637 {
 638         *ptr++ = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
 639         *ptr++ = omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
 640         *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
 641 
 642         /*
 643          * As per erratum i671, ROM code does not respect the PER DPLL
 644          * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
 645          * Then,  in any case, clear these bits to avoid extra latencies.
 646          */
 647         *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
 648                 ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
 649         *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
 650         *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
 651         *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
 652         *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
 653         *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
 654         *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
 655         *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
 656 }
 657 
 658 /*
 659  *
 660  */
 661 
 662 static const struct cm_ll_data omap3xxx_cm_ll_data = {
 663         .split_idlest_reg       = &omap3xxx_cm_split_idlest_reg,
 664         .wait_module_ready      = &omap3xxx_cm_wait_module_ready,
 665 };
 666 
 667 int __init omap3xxx_cm_init(const struct omap_prcm_init_data *data)
 668 {
 669         omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base.va +
 670                                        OMAP3430_IVA2_MOD);
 671         return cm_register(&omap3xxx_cm_ll_data);
 672 }
 673 
 674 static void __exit omap3xxx_cm_exit(void)
 675 {
 676         cm_unregister(&omap3xxx_cm_ll_data);
 677 }
 678 __exitcall(omap3xxx_cm_exit);

/* [<][>][^][v][top][bottom][index][help] */