blob: 3d4e42573950490a571181e4cb471e056960eb65 [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/**
* \file edma.c
*
* \brief Platform related APIs for EDMA
*/
/*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
* 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 Texas Instruments Incorporated 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
* OWNER 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 <ethdrivers/plat/hw/hw_control_AM335x.h>
#include <ethdrivers/plat/hw/soc_AM335x.h>
#include <ethdrivers/plat/hw/hw_cm_per.h>
#include <ethdrivers/plat/hw/hw_types.h>
/**
* \brief This function maps the crossbar events.
*
* \param baseAdd It is the Control Module Address.
*
* \param crossBarEvent It is the crossBar event number.
*
* \param Channel It is the channel number to which cross bar
* event needs to be mapped.
*/
unsigned int EDMA3CrossBarChannelMap(unsigned int baseAdd, unsigned int crossBarEvent,
unsigned int Channel)
{
unsigned int offset;
unsigned int select;
unsigned int n = 0;
/* offset of the TPCC_MUX to be configured */
offset = Channel / 4;
/*
** Each TPCC_MUX register has four event mux which can be used for
** cross bar mapping.Thus "select" variable is used to select,
** which of the event mux out of four,for a given TPCC_MUX register
** to be used.
*/
select = Channel - offset * 4;
switch (select) {
case 0:
n = 0;
break;
case 1:
n = 8;
break;
case 2:
n = 16;
break;
case 3:
n = 24;
break;
default:
break;
}
/* 'n' specifies the offset of the event mux */
HWREG(baseAdd + TPCC_MUX(offset)) &= ~(crossBarEvent << n);
HWREG(baseAdd + TPCC_MUX(offset)) |= crossBarEvent << n;
return 0;
}
/**
* \brief This API returns a unique number which identifies itself
* with the EDMA IP in AM335x SoC.
* \param None
* \return This returns a number '2' which is unique to EDMA IP in AM335x.
*/
unsigned int EDMAVersionGet(void)
{
return 2;
}
/*
** This function enables the system L3 clocks.
** This also enables the clocks for EDMA instance.
*/
void EDMAModuleClkConfig(void)
{
/* Configuring L3 Interface Clocks. */
/* Writing to MODULEMODE field of CM_PER_L3_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) |=
CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while (CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) &
CM_PER_L3_CLKCTRL_MODULEMODE));
/* Writing to MODULEMODE field of CM_PER_L3_INSTR_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) |=
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while (CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) &
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE));
/* Writing to CLKTRCTRL field of CM_PER_L3_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) |=
CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
/* Waiting for CLKTRCTRL field to reflect the written value. */
while (CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKTRCTRL));
/* Writing to CLKTRCTRL field of CM_PER_OCPWP_L3_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) |=
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
/*Waiting for CLKTRCTRL field to reflect the written value. */
while (CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL));
/* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) |=
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
/*Waiting for CLKTRCTRL field to reflect the written value. */
while (CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL));
/* Checking fields for necessary values. */
/* Waiting for IDLEST field in CM_PER_L3_CLKCTRL register to be set to 0x0. */
while ((CM_PER_L3_CLKCTRL_IDLEST_FUNC << CM_PER_L3_CLKCTRL_IDLEST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) &
CM_PER_L3_CLKCTRL_IDLEST));
/*
** Waiting for IDLEST field in CM_PER_L3_INSTR_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_L3_INSTR_CLKCTRL_IDLEST_FUNC <<
CM_PER_L3_INSTR_CLKCTRL_IDLEST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) &
CM_PER_L3_INSTR_CLKCTRL_IDLEST));
/*
** Waiting for CLKACTIVITY_L3_GCLK field in CM_PER_L3_CLKSTCTRL register to
** attain the desired value.
*/
while (CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK));
/*
** Waiting for CLKACTIVITY_OCPWP_L3_GCLK field in CM_PER_OCPWP_L3_CLKSTCTRL
** register to attain the desired value.
*/
while (CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK));
/*
** Waiting for CLKACTIVITY_L3S_GCLK field in CM_PER_L3S_CLKSTCTRL register
** to attain the desired value.
*/
while (CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK));
/* Configuring clocks for EDMA3 TPCC and TPTCs. */
/* Writing to MODULEMODE field of CM_PER_TPCC_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_TPCC_CLKCTRL) |=
CM_PER_TPCC_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while (CM_PER_TPCC_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPCC_CLKCTRL) &
CM_PER_TPCC_CLKCTRL_MODULEMODE));
/* Writing to MODULEMODE field of CM_PER_TPTC0_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_TPTC0_CLKCTRL) |=
CM_PER_TPTC0_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while (CM_PER_TPTC0_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC0_CLKCTRL) &
CM_PER_TPTC0_CLKCTRL_MODULEMODE));
/* Writing to MODULEMODE field of CM_PER_TPTC1_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_TPTC1_CLKCTRL) |=
CM_PER_TPTC1_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while (CM_PER_TPTC1_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC1_CLKCTRL) &
CM_PER_TPTC1_CLKCTRL_MODULEMODE));
/* Writing to MODULEMODE field of CM_PER_TPTC2_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_TPTC2_CLKCTRL) |=
CM_PER_TPTC2_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while (CM_PER_TPTC2_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC2_CLKCTRL) &
CM_PER_TPTC2_CLKCTRL_MODULEMODE));
/*
** Waiting for IDLEST field in CM_PER_TPCC_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_TPCC_CLKCTRL_IDLEST_FUNC <<
CM_PER_TPCC_CLKCTRL_IDLEST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPCC_CLKCTRL) &
CM_PER_TPCC_CLKCTRL_IDLEST));
/*
** Waiting for IDLEST field in CM_PER_TPTC0_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_TPTC0_CLKCTRL_IDLEST_FUNC <<
CM_PER_TPTC0_CLKCTRL_IDLEST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC0_CLKCTRL) &
CM_PER_TPTC0_CLKCTRL_IDLEST));
/*
** Waiting for STBYST field in CM_PER_TPTC0_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_TPTC0_CLKCTRL_STBYST_FUNC <<
CM_PER_TPTC0_CLKCTRL_STBYST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC0_CLKCTRL) &
CM_PER_TPTC0_CLKCTRL_STBYST));
/*
** Waiting for IDLEST field in CM_PER_TPTC1_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_TPTC1_CLKCTRL_IDLEST_FUNC <<
CM_PER_TPTC1_CLKCTRL_IDLEST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC1_CLKCTRL) &
CM_PER_TPTC1_CLKCTRL_IDLEST));
/*
** Waiting for STBYST field in CM_PER_TPTC1_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_TPTC1_CLKCTRL_STBYST_FUNC <<
CM_PER_TPTC1_CLKCTRL_STBYST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC1_CLKCTRL) &
CM_PER_TPTC1_CLKCTRL_STBYST));
/*
** Waiting for IDLEST field in CM_PER_TPTC2_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_TPTC2_CLKCTRL_IDLEST_FUNC <<
CM_PER_TPTC2_CLKCTRL_IDLEST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC2_CLKCTRL) &
CM_PER_TPTC2_CLKCTRL_IDLEST));
/*
** Waiting for STBYST field in CM_PER_TPTC2_CLKCTRL register to attain the
** desired value.
*/
while ((CM_PER_TPTC2_CLKCTRL_STBYST_FUNC <<
CM_PER_TPTC2_CLKCTRL_STBYST_SHIFT) !=
(HWREG(SOC_CM_PER_REGS + CM_PER_TPTC2_CLKCTRL) &
CM_PER_TPTC2_CLKCTRL_STBYST));
}