mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-27 00:20:58 +07:00
d81d188caf
The current code to support the DaVinci Power and Sleep Controller (PSC) assumes that there is only one controller. This assumption is no longer valid so expand the support to allow greater than one PSC. To accomplish this, put the base addresses for the PSCs in the SoC infrastructure so it can be referenced by the PSC code. This also requires adding an extra parameter to davinci_psc_config() to specify the PSC that is to be enabled/disabled. Signed-off-by: Mark A. Greer <mgreer@mvista.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
498 lines
11 KiB
C
498 lines
11 KiB
C
/*
|
|
* TI DaVinci DM644x chip specific setup
|
|
*
|
|
* Author: Kevin Hilman, Deep Root Systems, LLC
|
|
*
|
|
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
|
|
* the terms of the GNU General Public License version 2. This program
|
|
* is licensed "as is" without any warranty of any kind, whether express
|
|
* or implied.
|
|
*/
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <asm/mach/map.h>
|
|
|
|
#include <mach/dm646x.h>
|
|
#include <mach/clock.h>
|
|
#include <mach/cputype.h>
|
|
#include <mach/edma.h>
|
|
#include <mach/irqs.h>
|
|
#include <mach/psc.h>
|
|
#include <mach/mux.h>
|
|
#include <mach/common.h>
|
|
|
|
#include "clock.h"
|
|
#include "mux.h"
|
|
|
|
/*
|
|
* Device specific clocks
|
|
*/
|
|
#define DM646X_REF_FREQ 27000000
|
|
#define DM646X_AUX_FREQ 24000000
|
|
|
|
static struct pll_data pll1_data = {
|
|
.num = 1,
|
|
.phys_base = DAVINCI_PLL1_BASE,
|
|
};
|
|
|
|
static struct pll_data pll2_data = {
|
|
.num = 2,
|
|
.phys_base = DAVINCI_PLL2_BASE,
|
|
};
|
|
|
|
static struct clk ref_clk = {
|
|
.name = "ref_clk",
|
|
.rate = DM646X_REF_FREQ,
|
|
};
|
|
|
|
static struct clk aux_clkin = {
|
|
.name = "aux_clkin",
|
|
.rate = DM646X_AUX_FREQ,
|
|
};
|
|
|
|
static struct clk pll1_clk = {
|
|
.name = "pll1",
|
|
.parent = &ref_clk,
|
|
.pll_data = &pll1_data,
|
|
.flags = CLK_PLL,
|
|
};
|
|
|
|
static struct clk pll1_sysclk1 = {
|
|
.name = "pll1_sysclk1",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV1,
|
|
};
|
|
|
|
static struct clk pll1_sysclk2 = {
|
|
.name = "pll1_sysclk2",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV2,
|
|
};
|
|
|
|
static struct clk pll1_sysclk3 = {
|
|
.name = "pll1_sysclk3",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV3,
|
|
};
|
|
|
|
static struct clk pll1_sysclk4 = {
|
|
.name = "pll1_sysclk4",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV4,
|
|
};
|
|
|
|
static struct clk pll1_sysclk5 = {
|
|
.name = "pll1_sysclk5",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV5,
|
|
};
|
|
|
|
static struct clk pll1_sysclk6 = {
|
|
.name = "pll1_sysclk6",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV6,
|
|
};
|
|
|
|
static struct clk pll1_sysclk8 = {
|
|
.name = "pll1_sysclk8",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV8,
|
|
};
|
|
|
|
static struct clk pll1_sysclk9 = {
|
|
.name = "pll1_sysclk9",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV9,
|
|
};
|
|
|
|
static struct clk pll1_sysclkbp = {
|
|
.name = "pll1_sysclkbp",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL | PRE_PLL,
|
|
.div_reg = BPDIV,
|
|
};
|
|
|
|
static struct clk pll1_aux_clk = {
|
|
.name = "pll1_aux_clk",
|
|
.parent = &pll1_clk,
|
|
.flags = CLK_PLL | PRE_PLL,
|
|
};
|
|
|
|
static struct clk pll2_clk = {
|
|
.name = "pll2_clk",
|
|
.parent = &ref_clk,
|
|
.pll_data = &pll2_data,
|
|
.flags = CLK_PLL,
|
|
};
|
|
|
|
static struct clk pll2_sysclk1 = {
|
|
.name = "pll2_sysclk1",
|
|
.parent = &pll2_clk,
|
|
.flags = CLK_PLL,
|
|
.div_reg = PLLDIV1,
|
|
};
|
|
|
|
static struct clk dsp_clk = {
|
|
.name = "dsp",
|
|
.parent = &pll1_sysclk1,
|
|
.lpsc = DM646X_LPSC_C64X_CPU,
|
|
.flags = PSC_DSP,
|
|
.usecount = 1, /* REVISIT how to disable? */
|
|
};
|
|
|
|
static struct clk arm_clk = {
|
|
.name = "arm",
|
|
.parent = &pll1_sysclk2,
|
|
.lpsc = DM646X_LPSC_ARM,
|
|
.flags = ALWAYS_ENABLED,
|
|
};
|
|
|
|
static struct clk uart0_clk = {
|
|
.name = "uart0",
|
|
.parent = &aux_clkin,
|
|
.lpsc = DM646X_LPSC_UART0,
|
|
};
|
|
|
|
static struct clk uart1_clk = {
|
|
.name = "uart1",
|
|
.parent = &aux_clkin,
|
|
.lpsc = DM646X_LPSC_UART1,
|
|
};
|
|
|
|
static struct clk uart2_clk = {
|
|
.name = "uart2",
|
|
.parent = &aux_clkin,
|
|
.lpsc = DM646X_LPSC_UART2,
|
|
};
|
|
|
|
static struct clk i2c_clk = {
|
|
.name = "I2CCLK",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_I2C,
|
|
};
|
|
|
|
static struct clk gpio_clk = {
|
|
.name = "gpio",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_GPIO,
|
|
};
|
|
|
|
static struct clk aemif_clk = {
|
|
.name = "aemif",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_AEMIF,
|
|
.flags = ALWAYS_ENABLED,
|
|
};
|
|
|
|
static struct clk emac_clk = {
|
|
.name = "emac",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_EMAC,
|
|
};
|
|
|
|
static struct clk pwm0_clk = {
|
|
.name = "pwm0",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_PWM0,
|
|
.usecount = 1, /* REVIST: disabling hangs system */
|
|
};
|
|
|
|
static struct clk pwm1_clk = {
|
|
.name = "pwm1",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_PWM1,
|
|
.usecount = 1, /* REVIST: disabling hangs system */
|
|
};
|
|
|
|
static struct clk timer0_clk = {
|
|
.name = "timer0",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_TIMER0,
|
|
};
|
|
|
|
static struct clk timer1_clk = {
|
|
.name = "timer1",
|
|
.parent = &pll1_sysclk3,
|
|
.lpsc = DM646X_LPSC_TIMER1,
|
|
};
|
|
|
|
static struct clk timer2_clk = {
|
|
.name = "timer2",
|
|
.parent = &pll1_sysclk3,
|
|
.flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
|
|
};
|
|
|
|
static struct clk vpif0_clk = {
|
|
.name = "vpif0",
|
|
.parent = &ref_clk,
|
|
.lpsc = DM646X_LPSC_VPSSMSTR,
|
|
.flags = ALWAYS_ENABLED,
|
|
};
|
|
|
|
static struct clk vpif1_clk = {
|
|
.name = "vpif1",
|
|
.parent = &ref_clk,
|
|
.lpsc = DM646X_LPSC_VPSSSLV,
|
|
.flags = ALWAYS_ENABLED,
|
|
};
|
|
|
|
struct davinci_clk dm646x_clks[] = {
|
|
CLK(NULL, "ref", &ref_clk),
|
|
CLK(NULL, "aux", &aux_clkin),
|
|
CLK(NULL, "pll1", &pll1_clk),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
|
|
CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
|
|
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
|
CLK(NULL, "pll2", &pll2_clk),
|
|
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
|
|
CLK(NULL, "dsp", &dsp_clk),
|
|
CLK(NULL, "arm", &arm_clk),
|
|
CLK(NULL, "uart0", &uart0_clk),
|
|
CLK(NULL, "uart1", &uart1_clk),
|
|
CLK(NULL, "uart2", &uart2_clk),
|
|
CLK("i2c_davinci.1", NULL, &i2c_clk),
|
|
CLK(NULL, "gpio", &gpio_clk),
|
|
CLK(NULL, "aemif", &aemif_clk),
|
|
CLK("davinci_emac.1", NULL, &emac_clk),
|
|
CLK(NULL, "pwm0", &pwm0_clk),
|
|
CLK(NULL, "pwm1", &pwm1_clk),
|
|
CLK(NULL, "timer0", &timer0_clk),
|
|
CLK(NULL, "timer1", &timer1_clk),
|
|
CLK("watchdog", NULL, &timer2_clk),
|
|
CLK(NULL, "vpif0", &vpif0_clk),
|
|
CLK(NULL, "vpif1", &vpif1_clk),
|
|
CLK(NULL, NULL, NULL),
|
|
};
|
|
|
|
#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
|
|
static struct resource dm646x_emac_resources[] = {
|
|
{
|
|
.start = DM646X_EMAC_BASE,
|
|
.end = DM646X_EMAC_BASE + 0x47ff,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = IRQ_DM646X_EMACRXTHINT,
|
|
.end = IRQ_DM646X_EMACRXTHINT,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
{
|
|
.start = IRQ_DM646X_EMACRXINT,
|
|
.end = IRQ_DM646X_EMACRXINT,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
{
|
|
.start = IRQ_DM646X_EMACTXINT,
|
|
.end = IRQ_DM646X_EMACTXINT,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
{
|
|
.start = IRQ_DM646X_EMACMISCINT,
|
|
.end = IRQ_DM646X_EMACMISCINT,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
};
|
|
|
|
static struct platform_device dm646x_emac_device = {
|
|
.name = "davinci_emac",
|
|
.id = 1,
|
|
.num_resources = ARRAY_SIZE(dm646x_emac_resources),
|
|
.resource = dm646x_emac_resources,
|
|
};
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Device specific mux setup
|
|
*
|
|
* soc description mux mode mode mux dbg
|
|
* reg offset mask mode
|
|
*/
|
|
static const struct mux_config dm646x_pins[] = {
|
|
MUX_CFG(DM646X, ATAEN, 0, 0, 1, 1, true)
|
|
|
|
MUX_CFG(DM646X, AUDCK1, 0, 29, 1, 0, false)
|
|
|
|
MUX_CFG(DM646X, AUDCK0, 0, 28, 1, 0, false)
|
|
|
|
MUX_CFG(DM646X, CRGMUX, 0, 24, 7, 5, true)
|
|
|
|
MUX_CFG(DM646X, STSOMUX_DISABLE, 0, 22, 3, 0, true)
|
|
|
|
MUX_CFG(DM646X, STSIMUX_DISABLE, 0, 20, 3, 0, true)
|
|
|
|
MUX_CFG(DM646X, PTSOMUX_DISABLE, 0, 18, 3, 0, true)
|
|
|
|
MUX_CFG(DM646X, PTSIMUX_DISABLE, 0, 16, 3, 0, true)
|
|
|
|
MUX_CFG(DM646X, STSOMUX, 0, 22, 3, 2, true)
|
|
|
|
MUX_CFG(DM646X, STSIMUX, 0, 20, 3, 2, true)
|
|
|
|
MUX_CFG(DM646X, PTSOMUX_PARALLEL, 0, 18, 3, 2, true)
|
|
|
|
MUX_CFG(DM646X, PTSIMUX_PARALLEL, 0, 16, 3, 2, true)
|
|
|
|
MUX_CFG(DM646X, PTSOMUX_SERIAL, 0, 18, 3, 3, true)
|
|
|
|
MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true)
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
static const s8 dma_chan_dm646x_no_event[] = {
|
|
0, 1, 2, 3, 13,
|
|
14, 15, 24, 25, 26,
|
|
27, 30, 31, 54, 55,
|
|
56,
|
|
-1
|
|
};
|
|
|
|
static struct edma_soc_info dm646x_edma_info = {
|
|
.n_channel = 64,
|
|
.n_region = 6, /* 0-1, 4-7 */
|
|
.n_slot = 512,
|
|
.n_tc = 4,
|
|
.noevent = dma_chan_dm646x_no_event,
|
|
};
|
|
|
|
static struct resource edma_resources[] = {
|
|
{
|
|
.name = "edma_cc",
|
|
.start = 0x01c00000,
|
|
.end = 0x01c00000 + SZ_64K - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.name = "edma_tc0",
|
|
.start = 0x01c10000,
|
|
.end = 0x01c10000 + SZ_1K - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.name = "edma_tc1",
|
|
.start = 0x01c10400,
|
|
.end = 0x01c10400 + SZ_1K - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.name = "edma_tc2",
|
|
.start = 0x01c10800,
|
|
.end = 0x01c10800 + SZ_1K - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.name = "edma_tc3",
|
|
.start = 0x01c10c00,
|
|
.end = 0x01c10c00 + SZ_1K - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = IRQ_CCINT0,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
{
|
|
.start = IRQ_CCERRINT,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
/* not using TC*_ERR */
|
|
};
|
|
|
|
static struct platform_device dm646x_edma_device = {
|
|
.name = "edma",
|
|
.id = -1,
|
|
.dev.platform_data = &dm646x_edma_info,
|
|
.num_resources = ARRAY_SIZE(edma_resources),
|
|
.resource = edma_resources,
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
|
|
|
|
void dm646x_init_emac(struct emac_platform_data *pdata)
|
|
{
|
|
pdata->ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET;
|
|
pdata->ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET;
|
|
pdata->ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET;
|
|
pdata->mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET;
|
|
pdata->ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE;
|
|
pdata->version = EMAC_VERSION_2;
|
|
dm646x_emac_device.dev.platform_data = pdata;
|
|
platform_device_register(&dm646x_emac_device);
|
|
}
|
|
#else
|
|
|
|
void dm646x_init_emac(struct emac_platform_data *unused) {}
|
|
|
|
#endif
|
|
|
|
static struct map_desc dm646x_io_desc[] = {
|
|
{
|
|
.virtual = IO_VIRT,
|
|
.pfn = __phys_to_pfn(IO_PHYS),
|
|
.length = IO_SIZE,
|
|
.type = MT_DEVICE
|
|
},
|
|
};
|
|
|
|
/* Contents of JTAG ID register used to identify exact cpu type */
|
|
static struct davinci_id dm646x_ids[] = {
|
|
{
|
|
.variant = 0x0,
|
|
.part_no = 0xb770,
|
|
.manufacturer = 0x017,
|
|
.cpu_id = DAVINCI_CPU_ID_DM6467,
|
|
.name = "dm6467",
|
|
},
|
|
};
|
|
|
|
static void __iomem *dm646x_psc_bases[] = {
|
|
IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
|
|
};
|
|
|
|
static struct davinci_soc_info davinci_soc_info_dm646x = {
|
|
.io_desc = dm646x_io_desc,
|
|
.io_desc_num = ARRAY_SIZE(dm646x_io_desc),
|
|
.jtag_id_base = IO_ADDRESS(0x01c40028),
|
|
.ids = dm646x_ids,
|
|
.ids_num = ARRAY_SIZE(dm646x_ids),
|
|
.cpu_clks = dm646x_clks,
|
|
.psc_bases = dm646x_psc_bases,
|
|
.psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
|
|
};
|
|
|
|
void __init dm646x_init(void)
|
|
{
|
|
davinci_common_init(&davinci_soc_info_dm646x);
|
|
davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins));
|
|
}
|
|
|
|
static int __init dm646x_init_devices(void)
|
|
{
|
|
if (!cpu_is_davinci_dm646x())
|
|
return 0;
|
|
|
|
platform_device_register(&dm646x_edma_device);
|
|
return 0;
|
|
}
|
|
postcore_initcall(dm646x_init_devices);
|