/*
 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <plat_private.h>
#include <pmu.h>
#include <pwm.h>
#include <soc.h>

#define PWM0_IOMUX_PWM_EN		(1 << 0)
#define PWM1_IOMUX_PWM_EN		(1 << 1)
#define PWM2_IOMUX_PWM_EN		(1 << 2)
#define PWM3_IOMUX_PWM_EN		(1 << 3)

struct pwm_data_s {
	uint32_t iomux_bitmask;
	uint32_t enable_bitmask;
};

static struct pwm_data_s pwm_data;

/*
 * Disable the PWMs.
 */
void disable_pwms(void)
{
	uint32_t i, val;

	pwm_data.iomux_bitmask = 0;

	/* Save PWMs pinmux and change PWMs pinmux to GPIOs */
	val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX);
	if (((val >> GRF_GPIO4C2_IOMUX_SHIFT) &
		GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C2_IOMUX_PWM) {
		pwm_data.iomux_bitmask |= PWM0_IOMUX_PWM_EN;
		val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
				    GRF_GPIO4C2_IOMUX_SHIFT);
		mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
	}

	val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX);
	if (((val >> GRF_GPIO4C6_IOMUX_SHIFT) &
		GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C6_IOMUX_PWM) {
		pwm_data.iomux_bitmask |= PWM1_IOMUX_PWM_EN;
		val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
				    GRF_GPIO4C6_IOMUX_SHIFT);
		mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
	}

	val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX);
	if (((val >> PMUGRF_GPIO1C3_IOMUX_SHIFT) &
		GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO1C3_IOMUX_PWM) {
		pwm_data.iomux_bitmask |= PWM2_IOMUX_PWM_EN;
		val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
				    PMUGRF_GPIO1C3_IOMUX_SHIFT);
		mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val);
	}

	val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX);
	if (((val >> PMUGRF_GPIO0A6_IOMUX_SHIFT) &
		GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO0A6_IOMUX_PWM) {
		pwm_data.iomux_bitmask |= PWM3_IOMUX_PWM_EN;
		val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
				    PMUGRF_GPIO0A6_IOMUX_SHIFT);
		mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val);
	}

	/* Disable the pwm channel */
	pwm_data.enable_bitmask = 0;
	for (i = 0; i < 4; i++) {
		val = mmio_read_32(PWM_BASE + PWM_CTRL(i));
		if ((val & PWM_ENABLE) != PWM_ENABLE)
			continue;
		pwm_data.enable_bitmask |= (1 << i);
		mmio_write_32(PWM_BASE + PWM_CTRL(i), val & ~PWM_ENABLE);
	}
}

/*
 * Enable the PWMs.
 */
void enable_pwms(void)
{
	uint32_t i, val;

	for (i = 0; i < 4; i++) {
		val = mmio_read_32(PWM_BASE + PWM_CTRL(i));
		if (!(pwm_data.enable_bitmask & (1 << i)))
			continue;
		mmio_write_32(PWM_BASE + PWM_CTRL(i), val | PWM_ENABLE);
	}

	/* Restore all IOMUXes */
	if (pwm_data.iomux_bitmask & PWM3_IOMUX_PWM_EN) {
		val = BITS_WITH_WMASK(PMUGRF_GPIO0A6_IOMUX_PWM,
				    GRF_IOMUX_2BIT_MASK,
				    PMUGRF_GPIO0A6_IOMUX_SHIFT);
		mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val);
	}

	if (pwm_data.iomux_bitmask & PWM2_IOMUX_PWM_EN) {
		val = BITS_WITH_WMASK(PMUGRF_GPIO1C3_IOMUX_PWM,
				    GRF_IOMUX_2BIT_MASK,
				    PMUGRF_GPIO1C3_IOMUX_SHIFT);
		mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val);
	}

	if (pwm_data.iomux_bitmask & PWM1_IOMUX_PWM_EN) {
		val = BITS_WITH_WMASK(GRF_GPIO4C6_IOMUX_PWM,
				    GRF_IOMUX_2BIT_MASK,
				    GRF_GPIO4C6_IOMUX_SHIFT);
		mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
	}

	if (pwm_data.iomux_bitmask & PWM0_IOMUX_PWM_EN) {
		val = BITS_WITH_WMASK(GRF_GPIO4C2_IOMUX_PWM,
				    GRF_IOMUX_2BIT_MASK,
				    GRF_GPIO4C2_IOMUX_SHIFT);
		mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
	}
}
