181c2a044SGrzegorz Jaszczyk /*
281c2a044SGrzegorz Jaszczyk * Copyright (C) 2021 Marvell International Ltd.
381c2a044SGrzegorz Jaszczyk *
481c2a044SGrzegorz Jaszczyk * SPDX-License-Identifier: BSD-3-Clause
581c2a044SGrzegorz Jaszczyk * https://spdx.org/licenses
681c2a044SGrzegorz Jaszczyk */
781c2a044SGrzegorz Jaszczyk
881c2a044SGrzegorz Jaszczyk #include <common/debug.h>
981c2a044SGrzegorz Jaszczyk #include <lib/mmio.h>
1081c2a044SGrzegorz Jaszczyk #include "dfx.h"
1181c2a044SGrzegorz Jaszczyk #include <mvebu_def.h>
1281c2a044SGrzegorz Jaszczyk #include <mvebu.h>
1381c2a044SGrzegorz Jaszczyk #include <errno.h>
1481c2a044SGrzegorz Jaszczyk
1581c2a044SGrzegorz Jaszczyk /* #define DEBUG_DFX */
1681c2a044SGrzegorz Jaszczyk #ifdef DEBUG_DFX
1781c2a044SGrzegorz Jaszczyk #define debug(format...) NOTICE(format)
1881c2a044SGrzegorz Jaszczyk #else
1981c2a044SGrzegorz Jaszczyk #define debug(format, arg...)
2081c2a044SGrzegorz Jaszczyk #endif
2181c2a044SGrzegorz Jaszczyk
2281c2a044SGrzegorz Jaszczyk #define SAR_BASE (MVEBU_REGS_BASE + 0x6F8200)
2381c2a044SGrzegorz Jaszczyk #define SAR_SIZE 0x4
2481c2a044SGrzegorz Jaszczyk #define AP_DEV_ID_STATUS_REG (MVEBU_REGS_BASE + 0x6F8240)
2581c2a044SGrzegorz Jaszczyk #define JTAG_DEV_ID_STATUS_REG (MVEBU_REGS_BASE + 0x6F8244)
2681c2a044SGrzegorz Jaszczyk #define EFUSE_CTRL (MVEBU_REGS_BASE + 0x6F8008)
2781c2a044SGrzegorz Jaszczyk #define EFUSE_LD_BASE (MVEBU_REGS_BASE + 0x6F8F00)
2881c2a044SGrzegorz Jaszczyk #define EFUSE_LD_SIZE 0x1C
2981c2a044SGrzegorz Jaszczyk #define EFUSE_HD_BASE (MVEBU_REGS_BASE + 0x6F9000)
3081c2a044SGrzegorz Jaszczyk #define EFUSE_HD_SIZE 0x3F8
3181c2a044SGrzegorz Jaszczyk
32*667893adSGrzegorz Jaszczyk /* AP806 CPU DFS register mapping*/
33*667893adSGrzegorz Jaszczyk #define AP806_CA72MP2_0_PLL_CR_0_BASE (MVEBU_REGS_BASE + 0x6F8278)
34*667893adSGrzegorz Jaszczyk #define AP806_CA72MP2_0_PLL_CR_1_BASE (MVEBU_REGS_BASE + 0x6F8280)
35*667893adSGrzegorz Jaszczyk #define AP806_CA72MP2_0_PLL_CR_2_BASE (MVEBU_REGS_BASE + 0x6F8284)
36*667893adSGrzegorz Jaszczyk #define AP806_CA72MP2_0_PLL_SR_BASE (MVEBU_REGS_BASE + 0x6F8C94)
37*667893adSGrzegorz Jaszczyk
38*667893adSGrzegorz Jaszczyk /* AP807 CPU DFS register mapping */
39*667893adSGrzegorz Jaszczyk #define AP807_DEVICE_GENERAL_CR_10_BASE (MVEBU_REGS_BASE + 0x6F8278)
40*667893adSGrzegorz Jaszczyk #define AP807_DEVICE_GENERAL_CR_11_BASE (MVEBU_REGS_BASE + 0x6F827C)
41*667893adSGrzegorz Jaszczyk #define AP807_DEVICE_GENERAL_STATUS_6_BASE (MVEBU_REGS_BASE + 0x6F8C98)
42*667893adSGrzegorz Jaszczyk
43*667893adSGrzegorz Jaszczyk #ifdef MVEBU_SOC_AP807
44*667893adSGrzegorz Jaszczyk #define CLUSTER_OFFSET 0x8
45*667893adSGrzegorz Jaszczyk #define CLK_DIVIDER_REG AP807_DEVICE_GENERAL_CR_10_BASE
46*667893adSGrzegorz Jaszczyk #define CLK_FORCE_REG AP807_DEVICE_GENERAL_CR_11_BASE
47*667893adSGrzegorz Jaszczyk #define CLK_RATIO_REG AP807_DEVICE_GENERAL_CR_11_BASE
48*667893adSGrzegorz Jaszczyk #define CLK_RATIO_STATE_REG AP807_DEVICE_GENERAL_STATUS_6_BASE
49*667893adSGrzegorz Jaszczyk #else
50*667893adSGrzegorz Jaszczyk #define CLUSTER_OFFSET 0x14
51*667893adSGrzegorz Jaszczyk #define CLK_DIVIDER_REG AP806_CA72MP2_0_PLL_CR_0_BASE
52*667893adSGrzegorz Jaszczyk #define CLK_FORCE_REG AP806_CA72MP2_0_PLL_CR_1_BASE
53*667893adSGrzegorz Jaszczyk #define CLK_RATIO_REG AP806_CA72MP2_0_PLL_CR_2_BASE
54*667893adSGrzegorz Jaszczyk #define CLK_RATIO_STATE_REG AP806_CA72MP2_0_PLL_SR_BASE
55*667893adSGrzegorz Jaszczyk #endif /* MVEBU_SOC_AP807 */
56*667893adSGrzegorz Jaszczyk
is_valid(u_register_t addr)5781c2a044SGrzegorz Jaszczyk static _Bool is_valid(u_register_t addr)
5881c2a044SGrzegorz Jaszczyk {
5981c2a044SGrzegorz Jaszczyk switch (addr) {
6081c2a044SGrzegorz Jaszczyk case AP_DEV_ID_STATUS_REG:
6181c2a044SGrzegorz Jaszczyk case JTAG_DEV_ID_STATUS_REG:
6281c2a044SGrzegorz Jaszczyk case SAR_BASE ... (SAR_BASE + SAR_SIZE):
6381c2a044SGrzegorz Jaszczyk case EFUSE_LD_BASE ... (EFUSE_LD_BASE + EFUSE_LD_SIZE):
6481c2a044SGrzegorz Jaszczyk case EFUSE_HD_BASE ... (EFUSE_HD_BASE + EFUSE_HD_SIZE):
6581c2a044SGrzegorz Jaszczyk case EFUSE_CTRL:
66*667893adSGrzegorz Jaszczyk /* cpu-clk related registers */
67*667893adSGrzegorz Jaszczyk case CLK_DIVIDER_REG:
68*667893adSGrzegorz Jaszczyk case CLK_DIVIDER_REG + CLUSTER_OFFSET:
69*667893adSGrzegorz Jaszczyk case CLK_FORCE_REG:
70*667893adSGrzegorz Jaszczyk case CLK_FORCE_REG + CLUSTER_OFFSET:
71*667893adSGrzegorz Jaszczyk #ifndef MVEBU_SOC_AP807
72*667893adSGrzegorz Jaszczyk case CLK_RATIO_REG:
73*667893adSGrzegorz Jaszczyk case CLK_RATIO_REG + CLUSTER_OFFSET:
74*667893adSGrzegorz Jaszczyk #endif
75*667893adSGrzegorz Jaszczyk case CLK_RATIO_STATE_REG:
76*667893adSGrzegorz Jaszczyk case CLK_RATIO_STATE_REG + CLUSTER_OFFSET:
7781c2a044SGrzegorz Jaszczyk return true;
7881c2a044SGrzegorz Jaszczyk default:
7981c2a044SGrzegorz Jaszczyk return false;
8081c2a044SGrzegorz Jaszczyk }
8181c2a044SGrzegorz Jaszczyk }
8281c2a044SGrzegorz Jaszczyk
armada_dfx_sread(u_register_t * read,u_register_t addr)8381c2a044SGrzegorz Jaszczyk static int armada_dfx_sread(u_register_t *read, u_register_t addr)
8481c2a044SGrzegorz Jaszczyk {
8581c2a044SGrzegorz Jaszczyk if (!is_valid(addr))
8681c2a044SGrzegorz Jaszczyk return -EINVAL;
8781c2a044SGrzegorz Jaszczyk
8881c2a044SGrzegorz Jaszczyk *read = mmio_read_32(addr);
8981c2a044SGrzegorz Jaszczyk
9081c2a044SGrzegorz Jaszczyk return 0;
9181c2a044SGrzegorz Jaszczyk }
9281c2a044SGrzegorz Jaszczyk
armada_dfx_swrite(u_register_t addr,u_register_t val)9381c2a044SGrzegorz Jaszczyk static int armada_dfx_swrite(u_register_t addr, u_register_t val)
9481c2a044SGrzegorz Jaszczyk {
9581c2a044SGrzegorz Jaszczyk if (!is_valid(addr))
9681c2a044SGrzegorz Jaszczyk return -EINVAL;
9781c2a044SGrzegorz Jaszczyk
9881c2a044SGrzegorz Jaszczyk mmio_write_32(addr, val);
9981c2a044SGrzegorz Jaszczyk
10081c2a044SGrzegorz Jaszczyk return 0;
10181c2a044SGrzegorz Jaszczyk }
10281c2a044SGrzegorz Jaszczyk
mvebu_dfx_misc_handle(u_register_t func,u_register_t * read,u_register_t addr,u_register_t val)10381c2a044SGrzegorz Jaszczyk int mvebu_dfx_misc_handle(u_register_t func, u_register_t *read,
10481c2a044SGrzegorz Jaszczyk u_register_t addr, u_register_t val)
10581c2a044SGrzegorz Jaszczyk {
10681c2a044SGrzegorz Jaszczyk debug_enter();
10781c2a044SGrzegorz Jaszczyk
10881c2a044SGrzegorz Jaszczyk debug("func %ld, addr 0x%lx, val 0x%lx\n", func, addr, val);
10981c2a044SGrzegorz Jaszczyk
11081c2a044SGrzegorz Jaszczyk switch (func) {
11181c2a044SGrzegorz Jaszczyk case MV_SIP_DFX_SREAD:
11281c2a044SGrzegorz Jaszczyk return armada_dfx_sread(read, addr);
11381c2a044SGrzegorz Jaszczyk case MV_SIP_DFX_SWRITE:
11481c2a044SGrzegorz Jaszczyk return armada_dfx_swrite(addr, val);
11581c2a044SGrzegorz Jaszczyk default:
11681c2a044SGrzegorz Jaszczyk ERROR("unsupported dfx misc sub-func\n");
11781c2a044SGrzegorz Jaszczyk return -EINVAL;
11881c2a044SGrzegorz Jaszczyk }
11981c2a044SGrzegorz Jaszczyk
12081c2a044SGrzegorz Jaszczyk debug_exit();
12181c2a044SGrzegorz Jaszczyk
12281c2a044SGrzegorz Jaszczyk return 0;
12381c2a044SGrzegorz Jaszczyk }
124