blob: d57651466fb0dacfb5cb172299263071ad55ed41 [file] [log] [blame]
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +03001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +03008#include <arch_helpers.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <common/debug.h>
10#include <drivers/marvell/cache_llc.h>
11#include <lib/mmio.h>
12#include <plat/common/platform.h>
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +030013
14#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264)
15#define MVEBU_IO_AFFINITY (0xF00)
Grzegorz Jaszczyk785ab752019-01-23 15:47:57 +010016#define MVEBU_SF_REG (MVEBU_REGS_BASE + 0x40)
17#define MVEBU_SF_EN BIT(8)
Stefan Chulski44dad222019-06-24 19:13:38 +030018#define MVEBU_DFX_REG(cluster_id) (MVEBU_REGS_BASE + 0x6F82A0 + \
19 (cluster_id) * 0x4)
20#define MVEBU_DFX_CLK_EN_POS 0x3
21#define MVEBU_DFX_CL0_CLK_OFFS 16
22#define MVEBU_DFX_CL0_CLK_MASK (0xF << MVEBU_DFX_CL0_CLK_OFFS)
23#define MVEBU_DFX_CL1_CLK_OFFS 8
24#define MVEBU_DFX_CL1_CLK_MASK (0xF << MVEBU_DFX_CL1_CLK_OFFS)
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +030025
Grzegorz Jaszczyk785ab752019-01-23 15:47:57 +010026#ifdef MVEBU_SOC_AP807
27static void plat_enable_snoop_filter(void)
28{
29 int cpu_id = plat_my_core_pos();
30
31 /* Snoop filter needs to be enabled once per cluster */
32 if (cpu_id % 2)
33 return;
34
35 mmio_setbits_32(MVEBU_SF_REG, MVEBU_SF_EN);
36}
37#endif
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +030038
Stefan Chulski44dad222019-06-24 19:13:38 +030039#ifndef MVEBU_SOC_AP807
40static void plat_config_dfx_clock(void)
41{
42 int cluster_id = plat_my_core_pos();
43 uint32_t val;
44
45 /* DFX clock needs to be configured once per cluster */
46 if ((cluster_id % PLAT_MAX_CPUS_PER_CLUSTER) != 0) {
47 return;
48 }
49
50 val = mmio_read_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER));
51 if (cluster_id == 0) {
52 val &= ~MVEBU_DFX_CL0_CLK_MASK;
53 val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL0_CLK_OFFS);
54 } else {
55 val &= ~MVEBU_DFX_CL1_CLK_MASK;
56 val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL1_CLK_OFFS);
57 }
58 mmio_write_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER), val);
59}
60#endif
61
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +030062static void plat_enable_affinity(void)
63{
64 int cluster_id;
65 int affinity;
66
67 /* set CPU Affinity */
68 cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT;
69 affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id));
70 mmio_write_32(CCU_HTC_ASET, affinity);
71
72 /* set barier */
73 isb();
74}
75
76void marvell_psci_arch_init(int die_index)
77{
78#if LLC_ENABLE
79 /* check if LLC is in exclusive mode
80 * as L2 is configured to UniqueClean eviction
81 * (in a8k reset handler)
82 */
83 if (llc_is_exclusive(0) == 0)
84 ERROR("LLC should be configured to exclusice mode\n");
85#endif
86
87 /* Enable Affinity */
88 plat_enable_affinity();
Grzegorz Jaszczyk785ab752019-01-23 15:47:57 +010089
90#ifdef MVEBU_SOC_AP807
91 plat_enable_snoop_filter();
Stefan Chulski44dad222019-06-24 19:13:38 +030092#else
93 plat_config_dfx_clock();
Grzegorz Jaszczyk785ab752019-01-23 15:47:57 +010094#endif
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +030095}