1*5d3b1067SCaesar Wang /* 2*5d3b1067SCaesar Wang * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*5d3b1067SCaesar Wang * 4*5d3b1067SCaesar Wang * Redistribution and use in source and binary forms, with or without 5*5d3b1067SCaesar Wang * modification, are permitted provided that the following conditions are met: 6*5d3b1067SCaesar Wang * 7*5d3b1067SCaesar Wang * Redistributions of source code must retain the above copyright notice, this 8*5d3b1067SCaesar Wang * list of conditions and the following disclaimer. 9*5d3b1067SCaesar Wang * 10*5d3b1067SCaesar Wang * Redistributions in binary form must reproduce the above copyright notice, 11*5d3b1067SCaesar Wang * this list of conditions and the following disclaimer in the documentation 12*5d3b1067SCaesar Wang * and/or other materials provided with the distribution. 13*5d3b1067SCaesar Wang * 14*5d3b1067SCaesar Wang * Neither the name of ARM nor the names of its contributors may be used 15*5d3b1067SCaesar Wang * to endorse or promote products derived from this software without specific 16*5d3b1067SCaesar Wang * prior written permission. 17*5d3b1067SCaesar Wang * 18*5d3b1067SCaesar Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*5d3b1067SCaesar Wang * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*5d3b1067SCaesar Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*5d3b1067SCaesar Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*5d3b1067SCaesar Wang * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*5d3b1067SCaesar Wang * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*5d3b1067SCaesar Wang * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*5d3b1067SCaesar Wang * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*5d3b1067SCaesar Wang * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*5d3b1067SCaesar Wang * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*5d3b1067SCaesar Wang * POSSIBILITY OF SUCH DAMAGE. 29*5d3b1067SCaesar Wang */ 30*5d3b1067SCaesar Wang 31*5d3b1067SCaesar Wang #include <plat_private.h> 32*5d3b1067SCaesar Wang #include <pmu.h> 33*5d3b1067SCaesar Wang #include <pwm.h> 34*5d3b1067SCaesar Wang #include <soc.h> 35*5d3b1067SCaesar Wang 36*5d3b1067SCaesar Wang #define PWM0_IOMUX_PWM_EN (1 << 0) 37*5d3b1067SCaesar Wang #define PWM1_IOMUX_PWM_EN (1 << 1) 38*5d3b1067SCaesar Wang #define PWM2_IOMUX_PWM_EN (1 << 2) 39*5d3b1067SCaesar Wang #define PWM3_IOMUX_PWM_EN (1 << 3) 40*5d3b1067SCaesar Wang 41*5d3b1067SCaesar Wang struct pwm_data_s { 42*5d3b1067SCaesar Wang uint32_t iomux_bitmask; 43*5d3b1067SCaesar Wang uint32_t enable_bitmask; 44*5d3b1067SCaesar Wang }; 45*5d3b1067SCaesar Wang 46*5d3b1067SCaesar Wang static struct pwm_data_s pwm_data; 47*5d3b1067SCaesar Wang 48*5d3b1067SCaesar Wang /* 49*5d3b1067SCaesar Wang * Disable the PWMs. 50*5d3b1067SCaesar Wang */ 51*5d3b1067SCaesar Wang void disable_pwms(void) 52*5d3b1067SCaesar Wang { 53*5d3b1067SCaesar Wang uint32_t i, val; 54*5d3b1067SCaesar Wang 55*5d3b1067SCaesar Wang pwm_data.iomux_bitmask = 0; 56*5d3b1067SCaesar Wang 57*5d3b1067SCaesar Wang /* Save PWMs pinmux and change PWMs pinmux to GPIOs */ 58*5d3b1067SCaesar Wang val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX); 59*5d3b1067SCaesar Wang if (((val >> GRF_GPIO4C2_IOMUX_SHIFT) & 60*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C2_IOMUX_PWM) { 61*5d3b1067SCaesar Wang pwm_data.iomux_bitmask |= PWM0_IOMUX_PWM_EN; 62*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 63*5d3b1067SCaesar Wang GRF_GPIO4C2_IOMUX_SHIFT); 64*5d3b1067SCaesar Wang mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 65*5d3b1067SCaesar Wang } 66*5d3b1067SCaesar Wang 67*5d3b1067SCaesar Wang val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX); 68*5d3b1067SCaesar Wang if (((val >> GRF_GPIO4C6_IOMUX_SHIFT) & 69*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C6_IOMUX_PWM) { 70*5d3b1067SCaesar Wang pwm_data.iomux_bitmask |= PWM1_IOMUX_PWM_EN; 71*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 72*5d3b1067SCaesar Wang GRF_GPIO4C6_IOMUX_SHIFT); 73*5d3b1067SCaesar Wang mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 74*5d3b1067SCaesar Wang } 75*5d3b1067SCaesar Wang 76*5d3b1067SCaesar Wang val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX); 77*5d3b1067SCaesar Wang if (((val >> PMUGRF_GPIO1C3_IOMUX_SHIFT) & 78*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO1C3_IOMUX_PWM) { 79*5d3b1067SCaesar Wang pwm_data.iomux_bitmask |= PWM2_IOMUX_PWM_EN; 80*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 81*5d3b1067SCaesar Wang PMUGRF_GPIO1C3_IOMUX_SHIFT); 82*5d3b1067SCaesar Wang mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val); 83*5d3b1067SCaesar Wang } 84*5d3b1067SCaesar Wang 85*5d3b1067SCaesar Wang val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX); 86*5d3b1067SCaesar Wang if (((val >> PMUGRF_GPIO0A6_IOMUX_SHIFT) & 87*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO0A6_IOMUX_PWM) { 88*5d3b1067SCaesar Wang pwm_data.iomux_bitmask |= PWM3_IOMUX_PWM_EN; 89*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK, 90*5d3b1067SCaesar Wang PMUGRF_GPIO0A6_IOMUX_SHIFT); 91*5d3b1067SCaesar Wang mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val); 92*5d3b1067SCaesar Wang } 93*5d3b1067SCaesar Wang 94*5d3b1067SCaesar Wang /* Disable the pwm channel */ 95*5d3b1067SCaesar Wang pwm_data.enable_bitmask = 0; 96*5d3b1067SCaesar Wang for (i = 0; i < 4; i++) { 97*5d3b1067SCaesar Wang val = mmio_read_32(PWM_BASE + PWM_CTRL(i)); 98*5d3b1067SCaesar Wang if ((val & PWM_ENABLE) != PWM_ENABLE) 99*5d3b1067SCaesar Wang continue; 100*5d3b1067SCaesar Wang pwm_data.enable_bitmask |= (1 << i); 101*5d3b1067SCaesar Wang mmio_write_32(PWM_BASE + PWM_CTRL(i), val & ~PWM_ENABLE); 102*5d3b1067SCaesar Wang } 103*5d3b1067SCaesar Wang } 104*5d3b1067SCaesar Wang 105*5d3b1067SCaesar Wang /* 106*5d3b1067SCaesar Wang * Enable the PWMs. 107*5d3b1067SCaesar Wang */ 108*5d3b1067SCaesar Wang void enable_pwms(void) 109*5d3b1067SCaesar Wang { 110*5d3b1067SCaesar Wang uint32_t i, val; 111*5d3b1067SCaesar Wang 112*5d3b1067SCaesar Wang for (i = 0; i < 4; i++) { 113*5d3b1067SCaesar Wang val = mmio_read_32(PWM_BASE + PWM_CTRL(i)); 114*5d3b1067SCaesar Wang if (!(pwm_data.enable_bitmask & (1 << i))) 115*5d3b1067SCaesar Wang continue; 116*5d3b1067SCaesar Wang mmio_write_32(PWM_BASE + PWM_CTRL(i), val | PWM_ENABLE); 117*5d3b1067SCaesar Wang } 118*5d3b1067SCaesar Wang 119*5d3b1067SCaesar Wang /* Restore all IOMUXes */ 120*5d3b1067SCaesar Wang if (pwm_data.iomux_bitmask & PWM3_IOMUX_PWM_EN) { 121*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(PMUGRF_GPIO0A6_IOMUX_PWM, 122*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK, 123*5d3b1067SCaesar Wang PMUGRF_GPIO0A6_IOMUX_SHIFT); 124*5d3b1067SCaesar Wang mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val); 125*5d3b1067SCaesar Wang } 126*5d3b1067SCaesar Wang 127*5d3b1067SCaesar Wang if (pwm_data.iomux_bitmask & PWM2_IOMUX_PWM_EN) { 128*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(PMUGRF_GPIO1C3_IOMUX_PWM, 129*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK, 130*5d3b1067SCaesar Wang PMUGRF_GPIO1C3_IOMUX_SHIFT); 131*5d3b1067SCaesar Wang mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val); 132*5d3b1067SCaesar Wang } 133*5d3b1067SCaesar Wang 134*5d3b1067SCaesar Wang if (pwm_data.iomux_bitmask & PWM1_IOMUX_PWM_EN) { 135*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(GRF_GPIO4C6_IOMUX_PWM, 136*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK, 137*5d3b1067SCaesar Wang GRF_GPIO4C6_IOMUX_SHIFT); 138*5d3b1067SCaesar Wang mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 139*5d3b1067SCaesar Wang } 140*5d3b1067SCaesar Wang 141*5d3b1067SCaesar Wang if (pwm_data.iomux_bitmask & PWM0_IOMUX_PWM_EN) { 142*5d3b1067SCaesar Wang val = BITS_WITH_WMASK(GRF_GPIO4C2_IOMUX_PWM, 143*5d3b1067SCaesar Wang GRF_IOMUX_2BIT_MASK, 144*5d3b1067SCaesar Wang GRF_GPIO4C2_IOMUX_SHIFT); 145*5d3b1067SCaesar Wang mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val); 146*5d3b1067SCaesar Wang } 147*5d3b1067SCaesar Wang } 148