1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <plat_private.h> 8*91f16700Schasinglulu #include <pmu.h> 9*91f16700Schasinglulu #include <pwm.h> 10*91f16700Schasinglulu #include <soc.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #define PWM0_IOMUX_PWM_EN (1 << 0) 13*91f16700Schasinglulu #define PWM1_IOMUX_PWM_EN (1 << 1) 14*91f16700Schasinglulu #define PWM2_IOMUX_PWM_EN (1 << 2) 15*91f16700Schasinglulu #define PWM3_IOMUX_PWM_EN (1 << 3) 16*91f16700Schasinglulu 17*91f16700Schasinglulu struct pwm_data_s { 18*91f16700Schasinglulu uint32_t iomux_bitmask; 19*91f16700Schasinglulu uint32_t enable_bitmask; 20*91f16700Schasinglulu }; 21*91f16700Schasinglulu 22*91f16700Schasinglulu static struct pwm_data_s pwm_data; 23*91f16700Schasinglulu 24*91f16700Schasinglulu /* 25*91f16700Schasinglulu * Disable the PWMs. 26*91f16700Schasinglulu */ 27*91f16700Schasinglulu void disable_pwms(void) 28*91f16700Schasinglulu { 29*91f16700Schasinglulu uint32_t i, val; 30*91f16700Schasinglulu 31*91f16700Schasinglulu pwm_data.iomux_bitmask = 0; 32*91f16700Schasinglulu 33*91f16700Schasinglulu /* Save PWMs pinmux and change PWMs pinmux to GPIOs */ 34*91f16700Schasinglulu val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX); 35*91f16700Schasinglulu if (((val >> GRF_GPIO4C2_IOMUX_SHIFT) & 36*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C2_IOMUX_PWM) { 37*91f16700Schasinglulu pwm_data.iomux_bitmask |= PWM0_IOMUX_PWM_EN; 38*91f16700Schasinglulu val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 39*91f16700Schasinglulu GRF_GPIO4C2_IOMUX_SHIFT); 40*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 41*91f16700Schasinglulu } 42*91f16700Schasinglulu 43*91f16700Schasinglulu val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX); 44*91f16700Schasinglulu if (((val >> GRF_GPIO4C6_IOMUX_SHIFT) & 45*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C6_IOMUX_PWM) { 46*91f16700Schasinglulu pwm_data.iomux_bitmask |= PWM1_IOMUX_PWM_EN; 47*91f16700Schasinglulu val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 48*91f16700Schasinglulu GRF_GPIO4C6_IOMUX_SHIFT); 49*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 50*91f16700Schasinglulu } 51*91f16700Schasinglulu 52*91f16700Schasinglulu val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX); 53*91f16700Schasinglulu if (((val >> PMUGRF_GPIO1C3_IOMUX_SHIFT) & 54*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO1C3_IOMUX_PWM) { 55*91f16700Schasinglulu pwm_data.iomux_bitmask |= PWM2_IOMUX_PWM_EN; 56*91f16700Schasinglulu val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 57*91f16700Schasinglulu PMUGRF_GPIO1C3_IOMUX_SHIFT); 58*91f16700Schasinglulu mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val); 59*91f16700Schasinglulu } 60*91f16700Schasinglulu 61*91f16700Schasinglulu val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX); 62*91f16700Schasinglulu if (((val >> PMUGRF_GPIO0A6_IOMUX_SHIFT) & 63*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO0A6_IOMUX_PWM) { 64*91f16700Schasinglulu pwm_data.iomux_bitmask |= PWM3_IOMUX_PWM_EN; 65*91f16700Schasinglulu val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 66*91f16700Schasinglulu PMUGRF_GPIO0A6_IOMUX_SHIFT); 67*91f16700Schasinglulu mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val); 68*91f16700Schasinglulu } 69*91f16700Schasinglulu 70*91f16700Schasinglulu /* Disable the pwm channel */ 71*91f16700Schasinglulu pwm_data.enable_bitmask = 0; 72*91f16700Schasinglulu for (i = 0; i < 4; i++) { 73*91f16700Schasinglulu val = mmio_read_32(PWM_BASE + PWM_CTRL(i)); 74*91f16700Schasinglulu if ((val & PWM_ENABLE) != PWM_ENABLE) 75*91f16700Schasinglulu continue; 76*91f16700Schasinglulu pwm_data.enable_bitmask |= (1 << i); 77*91f16700Schasinglulu mmio_write_32(PWM_BASE + PWM_CTRL(i), val & ~PWM_ENABLE); 78*91f16700Schasinglulu } 79*91f16700Schasinglulu } 80*91f16700Schasinglulu 81*91f16700Schasinglulu /* 82*91f16700Schasinglulu * Enable the PWMs. 83*91f16700Schasinglulu */ 84*91f16700Schasinglulu void enable_pwms(void) 85*91f16700Schasinglulu { 86*91f16700Schasinglulu uint32_t i, val; 87*91f16700Schasinglulu 88*91f16700Schasinglulu for (i = 0; i < 4; i++) { 89*91f16700Schasinglulu val = mmio_read_32(PWM_BASE + PWM_CTRL(i)); 90*91f16700Schasinglulu if (!(pwm_data.enable_bitmask & (1 << i))) 91*91f16700Schasinglulu continue; 92*91f16700Schasinglulu mmio_write_32(PWM_BASE + PWM_CTRL(i), val | PWM_ENABLE); 93*91f16700Schasinglulu } 94*91f16700Schasinglulu 95*91f16700Schasinglulu /* Restore all IOMUXes */ 96*91f16700Schasinglulu if (pwm_data.iomux_bitmask & PWM3_IOMUX_PWM_EN) { 97*91f16700Schasinglulu val = BITS_WITH_WMASK(PMUGRF_GPIO0A6_IOMUX_PWM, 98*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK, 99*91f16700Schasinglulu PMUGRF_GPIO0A6_IOMUX_SHIFT); 100*91f16700Schasinglulu mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val); 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu if (pwm_data.iomux_bitmask & PWM2_IOMUX_PWM_EN) { 104*91f16700Schasinglulu val = BITS_WITH_WMASK(PMUGRF_GPIO1C3_IOMUX_PWM, 105*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK, 106*91f16700Schasinglulu PMUGRF_GPIO1C3_IOMUX_SHIFT); 107*91f16700Schasinglulu mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val); 108*91f16700Schasinglulu } 109*91f16700Schasinglulu 110*91f16700Schasinglulu if (pwm_data.iomux_bitmask & PWM1_IOMUX_PWM_EN) { 111*91f16700Schasinglulu val = BITS_WITH_WMASK(GRF_GPIO4C6_IOMUX_PWM, 112*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK, 113*91f16700Schasinglulu GRF_GPIO4C6_IOMUX_SHIFT); 114*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 115*91f16700Schasinglulu } 116*91f16700Schasinglulu 117*91f16700Schasinglulu if (pwm_data.iomux_bitmask & PWM0_IOMUX_PWM_EN) { 118*91f16700Schasinglulu val = BITS_WITH_WMASK(GRF_GPIO4C2_IOMUX_PWM, 119*91f16700Schasinglulu GRF_IOMUX_2BIT_MASK, 120*91f16700Schasinglulu GRF_GPIO4C2_IOMUX_SHIFT); 121*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 122*91f16700Schasinglulu } 123*91f16700Schasinglulu } 124