Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * OMAP3xxx clockdomains
0004  *
0005  * Copyright (C) 2008-2011 Texas Instruments, Inc.
0006  * Copyright (C) 2008-2010 Nokia Corporation
0007  *
0008  * Paul Walmsley, Jouni Högander
0009  *
0010  * This file contains clockdomains and clockdomain wakeup/sleep
0011  * dependencies for the OMAP3xxx chips.  Some notes:
0012  *
0013  * A useful validation rule for struct clockdomain: Any clockdomain
0014  * referenced by a wkdep_srcs or sleepdep_srcs array must have a
0015  * dep_bit assigned.  So wkdep_srcs/sleepdep_srcs are really just
0016  * software-controllable dependencies.  Non-software-controllable
0017  * dependencies do exist, but they are not encoded below (yet).
0018  *
0019  * The overly-specific dep_bit names are due to a bit name collision
0020  * with CM_FCLKEN_{DSP,IVA2}.  The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
0021  * value are the same for all powerdomains: 2
0022  *
0023  * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
0024  * sanity check?
0025  * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
0026  */
0027 
0028 /*
0029  * To-Do List
0030  * -> Port the Sleep/Wakeup dependencies for the domains
0031  *    from the Power domain framework
0032  */
0033 
0034 #include <linux/kernel.h>
0035 #include <linux/io.h>
0036 
0037 #include "soc.h"
0038 #include "clockdomain.h"
0039 #include "prm2xxx_3xxx.h"
0040 #include "cm2xxx_3xxx.h"
0041 #include "cm-regbits-34xx.h"
0042 #include "prm-regbits-34xx.h"
0043 
0044 /*
0045  * Clockdomain dependencies for wkdeps/sleepdeps
0046  *
0047  * XXX Hardware dependencies (e.g., dependencies that cannot be
0048  * changed in software) are not included here yet, but should be.
0049  */
0050 
0051 /* OMAP3-specific possible dependencies */
0052 
0053 /*
0054  * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
0055  * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
0056  */
0057 static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
0058     { .clkdm_name = "iva2_clkdm" },
0059     { .clkdm_name = "mpu_clkdm" },
0060     { .clkdm_name = "wkup_clkdm" },
0061     { NULL },
0062 };
0063 
0064 static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
0065     { .clkdm_name = "mpu_clkdm" },
0066     { .clkdm_name = "wkup_clkdm" },
0067     { NULL },
0068 };
0069 
0070 /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
0071 static struct clkdm_dep per_wkdeps[] = {
0072     { .clkdm_name = "core_l3_clkdm" },
0073     { .clkdm_name = "core_l4_clkdm" },
0074     { .clkdm_name = "iva2_clkdm" },
0075     { .clkdm_name = "mpu_clkdm" },
0076     { .clkdm_name = "wkup_clkdm" },
0077     { NULL },
0078 };
0079 
0080 static struct clkdm_dep per_am35x_wkdeps[] = {
0081     { .clkdm_name = "core_l3_clkdm" },
0082     { .clkdm_name = "core_l4_clkdm" },
0083     { .clkdm_name = "mpu_clkdm" },
0084     { .clkdm_name = "wkup_clkdm" },
0085     { NULL },
0086 };
0087 
0088 /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
0089 static struct clkdm_dep usbhost_wkdeps[] = {
0090     { .clkdm_name = "core_l3_clkdm" },
0091     { .clkdm_name = "core_l4_clkdm" },
0092     { .clkdm_name = "iva2_clkdm" },
0093     { .clkdm_name = "mpu_clkdm" },
0094     { .clkdm_name = "wkup_clkdm" },
0095     { NULL },
0096 };
0097 
0098 static struct clkdm_dep usbhost_am35x_wkdeps[] = {
0099     { .clkdm_name = "core_l3_clkdm" },
0100     { .clkdm_name = "core_l4_clkdm" },
0101     { .clkdm_name = "mpu_clkdm" },
0102     { .clkdm_name = "wkup_clkdm" },
0103     { NULL },
0104 };
0105 
0106 /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
0107 static struct clkdm_dep mpu_3xxx_wkdeps[] = {
0108     { .clkdm_name = "core_l3_clkdm" },
0109     { .clkdm_name = "core_l4_clkdm" },
0110     { .clkdm_name = "iva2_clkdm" },
0111     { .clkdm_name = "dss_clkdm" },
0112     { .clkdm_name = "per_clkdm" },
0113     { NULL },
0114 };
0115 
0116 static struct clkdm_dep mpu_am35x_wkdeps[] = {
0117     { .clkdm_name = "core_l3_clkdm" },
0118     { .clkdm_name = "core_l4_clkdm" },
0119     { .clkdm_name = "dss_clkdm" },
0120     { .clkdm_name = "per_clkdm" },
0121     { NULL },
0122 };
0123 
0124 /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
0125 static struct clkdm_dep iva2_wkdeps[] = {
0126     { .clkdm_name = "core_l3_clkdm" },
0127     { .clkdm_name = "core_l4_clkdm" },
0128     { .clkdm_name = "mpu_clkdm" },
0129     { .clkdm_name = "wkup_clkdm" },
0130     { .clkdm_name = "dss_clkdm" },
0131     { .clkdm_name = "per_clkdm" },
0132     { NULL },
0133 };
0134 
0135 /* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
0136 static struct clkdm_dep cam_wkdeps[] = {
0137     { .clkdm_name = "iva2_clkdm" },
0138     { .clkdm_name = "mpu_clkdm" },
0139     { .clkdm_name = "wkup_clkdm" },
0140     { NULL },
0141 };
0142 
0143 /* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
0144 static struct clkdm_dep dss_wkdeps[] = {
0145     { .clkdm_name = "iva2_clkdm" },
0146     { .clkdm_name = "mpu_clkdm" },
0147     { .clkdm_name = "wkup_clkdm" },
0148     { NULL },
0149 };
0150 
0151 static struct clkdm_dep dss_am35x_wkdeps[] = {
0152     { .clkdm_name = "mpu_clkdm" },
0153     { .clkdm_name = "wkup_clkdm" },
0154     { NULL },
0155 };
0156 
0157 /* 3430: PM_WKDEP_NEON: MPU */
0158 static struct clkdm_dep neon_wkdeps[] = {
0159     { .clkdm_name = "mpu_clkdm" },
0160     { NULL },
0161 };
0162 
0163 /* Sleep dependency source arrays for OMAP3-specific clkdms */
0164 
0165 /* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
0166 static struct clkdm_dep dss_sleepdeps[] = {
0167     { .clkdm_name = "mpu_clkdm" },
0168     { .clkdm_name = "iva2_clkdm" },
0169     { NULL },
0170 };
0171 
0172 static struct clkdm_dep dss_am35x_sleepdeps[] = {
0173     { .clkdm_name = "mpu_clkdm" },
0174     { NULL },
0175 };
0176 
0177 /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
0178 static struct clkdm_dep per_sleepdeps[] = {
0179     { .clkdm_name = "mpu_clkdm" },
0180     { .clkdm_name = "iva2_clkdm" },
0181     { NULL },
0182 };
0183 
0184 static struct clkdm_dep per_am35x_sleepdeps[] = {
0185     { .clkdm_name = "mpu_clkdm" },
0186     { NULL },
0187 };
0188 
0189 /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
0190 static struct clkdm_dep usbhost_sleepdeps[] = {
0191     { .clkdm_name = "mpu_clkdm" },
0192     { .clkdm_name = "iva2_clkdm" },
0193     { NULL },
0194 };
0195 
0196 static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
0197     { .clkdm_name = "mpu_clkdm" },
0198     { NULL },
0199 };
0200 
0201 /* 3430: CM_SLEEPDEP_CAM: MPU */
0202 static struct clkdm_dep cam_sleepdeps[] = {
0203     { .clkdm_name = "mpu_clkdm" },
0204     { NULL },
0205 };
0206 
0207 /*
0208  * 3430ES1: CM_SLEEPDEP_GFX: MPU
0209  * 3430ES2: CM_SLEEPDEP_SGX: MPU
0210  * These can share data since they will never be present simultaneously
0211  * on the same device.
0212  */
0213 static struct clkdm_dep gfx_sgx_sleepdeps[] = {
0214     { .clkdm_name = "mpu_clkdm" },
0215     { NULL },
0216 };
0217 
0218 /*
0219  * OMAP3 clockdomains
0220  */
0221 
0222 static struct clockdomain mpu_3xxx_clkdm = {
0223     .name       = "mpu_clkdm",
0224     .pwrdm      = { .name = "mpu_pwrdm" },
0225     .flags      = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
0226     .dep_bit    = OMAP3430_EN_MPU_SHIFT,
0227     .wkdep_srcs = mpu_3xxx_wkdeps,
0228     .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
0229 };
0230 
0231 static struct clockdomain mpu_am35x_clkdm = {
0232     .name       = "mpu_clkdm",
0233     .pwrdm      = { .name = "mpu_pwrdm" },
0234     .flags      = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
0235     .dep_bit    = OMAP3430_EN_MPU_SHIFT,
0236     .wkdep_srcs = mpu_am35x_wkdeps,
0237     .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
0238 };
0239 
0240 static struct clockdomain neon_clkdm = {
0241     .name       = "neon_clkdm",
0242     .pwrdm      = { .name = "neon_pwrdm" },
0243     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0244     .wkdep_srcs = neon_wkdeps,
0245     .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
0246 };
0247 
0248 static struct clockdomain iva2_clkdm = {
0249     .name       = "iva2_clkdm",
0250     .pwrdm      = { .name = "iva2_pwrdm" },
0251     .flags      = CLKDM_CAN_SWSUP,
0252     .dep_bit    = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
0253     .wkdep_srcs = iva2_wkdeps,
0254     .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
0255 };
0256 
0257 static struct clockdomain gfx_3430es1_clkdm = {
0258     .name       = "gfx_clkdm",
0259     .pwrdm      = { .name = "gfx_pwrdm" },
0260     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0261     .wkdep_srcs = gfx_sgx_3xxx_wkdeps,
0262     .sleepdep_srcs  = gfx_sgx_sleepdeps,
0263     .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
0264 };
0265 
0266 static struct clockdomain sgx_clkdm = {
0267     .name       = "sgx_clkdm",
0268     .pwrdm      = { .name = "sgx_pwrdm" },
0269     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0270     .wkdep_srcs = gfx_sgx_3xxx_wkdeps,
0271     .sleepdep_srcs  = gfx_sgx_sleepdeps,
0272     .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
0273 };
0274 
0275 static struct clockdomain sgx_am35x_clkdm = {
0276     .name       = "sgx_clkdm",
0277     .pwrdm      = { .name = "sgx_pwrdm" },
0278     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0279     .wkdep_srcs = gfx_sgx_am35x_wkdeps,
0280     .sleepdep_srcs  = gfx_sgx_sleepdeps,
0281     .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
0282 };
0283 
0284 /*
0285  * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
0286  * then that information was removed from the 34xx ES2+ TRM.  It is
0287  * unclear whether the core is still there, but the clockdomain logic
0288  * is there, and must be programmed to an appropriate state if the
0289  * CORE clockdomain is to become inactive.
0290  */
0291 static struct clockdomain d2d_clkdm = {
0292     .name       = "d2d_clkdm",
0293     .pwrdm      = { .name = "core_pwrdm" },
0294     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0295     .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
0296 };
0297 
0298 /*
0299  * XXX add usecounting for clkdm dependencies, otherwise the presence
0300  * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
0301  * could cause trouble
0302  */
0303 static struct clockdomain core_l3_3xxx_clkdm = {
0304     .name       = "core_l3_clkdm",
0305     .pwrdm      = { .name = "core_pwrdm" },
0306     .flags      = CLKDM_CAN_HWSUP,
0307     .dep_bit    = OMAP3430_EN_CORE_SHIFT,
0308     .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
0309 };
0310 
0311 /*
0312  * XXX add usecounting for clkdm dependencies, otherwise the presence
0313  * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
0314  * could cause trouble
0315  */
0316 static struct clockdomain core_l4_3xxx_clkdm = {
0317     .name       = "core_l4_clkdm",
0318     .pwrdm      = { .name = "core_pwrdm" },
0319     .flags      = CLKDM_CAN_HWSUP,
0320     .dep_bit    = OMAP3430_EN_CORE_SHIFT,
0321     .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
0322 };
0323 
0324 /* Another case of bit name collisions between several registers: EN_DSS */
0325 static struct clockdomain dss_3xxx_clkdm = {
0326     .name       = "dss_clkdm",
0327     .pwrdm      = { .name = "dss_pwrdm" },
0328     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0329     .dep_bit    = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
0330     .wkdep_srcs = dss_wkdeps,
0331     .sleepdep_srcs  = dss_sleepdeps,
0332     .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
0333 };
0334 
0335 static struct clockdomain dss_am35x_clkdm = {
0336     .name       = "dss_clkdm",
0337     .pwrdm      = { .name = "dss_pwrdm" },
0338     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0339     .dep_bit    = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
0340     .wkdep_srcs = dss_am35x_wkdeps,
0341     .sleepdep_srcs  = dss_am35x_sleepdeps,
0342     .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
0343 };
0344 
0345 static struct clockdomain cam_clkdm = {
0346     .name       = "cam_clkdm",
0347     .pwrdm      = { .name = "cam_pwrdm" },
0348     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0349     .wkdep_srcs = cam_wkdeps,
0350     .sleepdep_srcs  = cam_sleepdeps,
0351     .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
0352 };
0353 
0354 static struct clockdomain usbhost_clkdm = {
0355     .name       = "usbhost_clkdm",
0356     .pwrdm      = { .name = "usbhost_pwrdm" },
0357     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0358     .wkdep_srcs = usbhost_wkdeps,
0359     .sleepdep_srcs  = usbhost_sleepdeps,
0360     .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
0361 };
0362 
0363 static struct clockdomain usbhost_am35x_clkdm = {
0364     .name       = "usbhost_clkdm",
0365     .pwrdm      = { .name = "core_pwrdm" },
0366     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0367     .wkdep_srcs = usbhost_am35x_wkdeps,
0368     .sleepdep_srcs  = usbhost_am35x_sleepdeps,
0369     .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
0370 };
0371 
0372 static struct clockdomain per_clkdm = {
0373     .name       = "per_clkdm",
0374     .pwrdm      = { .name = "per_pwrdm" },
0375     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0376     .dep_bit    = OMAP3430_EN_PER_SHIFT,
0377     .wkdep_srcs = per_wkdeps,
0378     .sleepdep_srcs  = per_sleepdeps,
0379     .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
0380 };
0381 
0382 static struct clockdomain per_am35x_clkdm = {
0383     .name       = "per_clkdm",
0384     .pwrdm      = { .name = "per_pwrdm" },
0385     .flags      = CLKDM_CAN_HWSUP_SWSUP,
0386     .dep_bit    = OMAP3430_EN_PER_SHIFT,
0387     .wkdep_srcs = per_am35x_wkdeps,
0388     .sleepdep_srcs  = per_am35x_sleepdeps,
0389     .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
0390 };
0391 
0392 static struct clockdomain emu_clkdm = {
0393     .name       = "emu_clkdm",
0394     .pwrdm      = { .name = "emu_pwrdm" },
0395     .flags      = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
0396                CLKDM_MISSING_IDLE_REPORTING),
0397     .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
0398 };
0399 
0400 static struct clockdomain dpll1_clkdm = {
0401     .name       = "dpll1_clkdm",
0402     .pwrdm      = { .name = "dpll1_pwrdm" },
0403 };
0404 
0405 static struct clockdomain dpll2_clkdm = {
0406     .name       = "dpll2_clkdm",
0407     .pwrdm      = { .name = "dpll2_pwrdm" },
0408 };
0409 
0410 static struct clockdomain dpll3_clkdm = {
0411     .name       = "dpll3_clkdm",
0412     .pwrdm      = { .name = "dpll3_pwrdm" },
0413 };
0414 
0415 static struct clockdomain dpll4_clkdm = {
0416     .name       = "dpll4_clkdm",
0417     .pwrdm      = { .name = "dpll4_pwrdm" },
0418 };
0419 
0420 static struct clockdomain dpll5_clkdm = {
0421     .name       = "dpll5_clkdm",
0422     .pwrdm      = { .name = "dpll5_pwrdm" },
0423 };
0424 
0425 /*
0426  * Clockdomain hwsup dependencies
0427  */
0428 
0429 static struct clkdm_autodep clkdm_autodeps[] = {
0430     {
0431         .clkdm = { .name = "mpu_clkdm" },
0432     },
0433     {
0434         .clkdm = { .name = "iva2_clkdm" },
0435     },
0436     {
0437         .clkdm = { .name = NULL },
0438     }
0439 };
0440 
0441 static struct clkdm_autodep clkdm_am35x_autodeps[] = {
0442     {
0443         .clkdm = { .name = "mpu_clkdm" },
0444     },
0445     {
0446         .clkdm = { .name = NULL },
0447     }
0448 };
0449 
0450 /*
0451  *
0452  */
0453 
0454 static struct clockdomain *clockdomains_common[] __initdata = {
0455     &wkup_common_clkdm,
0456     &neon_clkdm,
0457     &core_l3_3xxx_clkdm,
0458     &core_l4_3xxx_clkdm,
0459     &emu_clkdm,
0460     &dpll1_clkdm,
0461     &dpll3_clkdm,
0462     &dpll4_clkdm,
0463     NULL
0464 };
0465 
0466 static struct clockdomain *clockdomains_omap3430[] __initdata = {
0467     &mpu_3xxx_clkdm,
0468     &iva2_clkdm,
0469     &d2d_clkdm,
0470     &dss_3xxx_clkdm,
0471     &cam_clkdm,
0472     &per_clkdm,
0473     &dpll2_clkdm,
0474     NULL
0475 };
0476 
0477 static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
0478     &gfx_3430es1_clkdm,
0479     NULL,
0480 };
0481 
0482 static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
0483     &sgx_clkdm,
0484     &dpll5_clkdm,
0485     &usbhost_clkdm,
0486     NULL,
0487 };
0488 
0489 static struct clockdomain *clockdomains_am35x[] __initdata = {
0490     &mpu_am35x_clkdm,
0491     &sgx_am35x_clkdm,
0492     &dss_am35x_clkdm,
0493     &per_am35x_clkdm,
0494     &usbhost_am35x_clkdm,
0495     &dpll5_clkdm,
0496     NULL
0497 };
0498 
0499 void __init omap3xxx_clockdomains_init(void)
0500 {
0501     struct clockdomain **sc;
0502     unsigned int rev;
0503 
0504     if (!cpu_is_omap34xx())
0505         return;
0506 
0507     clkdm_register_platform_funcs(&omap3_clkdm_operations);
0508     clkdm_register_clkdms(clockdomains_common);
0509 
0510     rev = omap_rev();
0511 
0512     if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
0513         clkdm_register_clkdms(clockdomains_am35x);
0514         clkdm_register_autodeps(clkdm_am35x_autodeps);
0515     } else {
0516         clkdm_register_clkdms(clockdomains_omap3430);
0517 
0518         sc = (rev == OMAP3430_REV_ES1_0) ?
0519             clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
0520 
0521         clkdm_register_clkdms(sc);
0522         clkdm_register_autodeps(clkdm_autodeps);
0523     }
0524 
0525     clkdm_complete_init();
0526 }