1 /*
2  * Copyright (C) 2021 Marvell International Ltd.
3  *
4  * SPDX-License-Identifier:     BSD-3-Clause
5  * https://spdx.org/licenses
6  */
7 
8 #include <common/debug.h>
9 #include <lib/mmio.h>
10 #include "dfx.h"
11 #include <mvebu_def.h>
12 #include <mvebu.h>
13 #include <errno.h>
14 
15 /* #define DEBUG_DFX */
16 #ifdef DEBUG_DFX
17 #define debug(format...) NOTICE(format)
18 #else
19 #define debug(format, arg...)
20 #endif
21 
22 #define SAR_BASE			(MVEBU_REGS_BASE + 0x6F8200)
23 #define SAR_SIZE			0x4
24 #define AP_DEV_ID_STATUS_REG		(MVEBU_REGS_BASE + 0x6F8240)
25 #define JTAG_DEV_ID_STATUS_REG		(MVEBU_REGS_BASE + 0x6F8244)
26 #define EFUSE_CTRL			(MVEBU_REGS_BASE + 0x6F8008)
27 #define EFUSE_LD_BASE			(MVEBU_REGS_BASE + 0x6F8F00)
28 #define EFUSE_LD_SIZE			0x1C
29 #define EFUSE_HD_BASE			(MVEBU_REGS_BASE + 0x6F9000)
30 #define EFUSE_HD_SIZE			0x3F8
31 
32 /* AP806 CPU DFS register mapping*/
33 #define AP806_CA72MP2_0_PLL_CR_0_BASE		(MVEBU_REGS_BASE + 0x6F8278)
34 #define AP806_CA72MP2_0_PLL_CR_1_BASE		(MVEBU_REGS_BASE + 0x6F8280)
35 #define AP806_CA72MP2_0_PLL_CR_2_BASE		(MVEBU_REGS_BASE + 0x6F8284)
36 #define AP806_CA72MP2_0_PLL_SR_BASE		(MVEBU_REGS_BASE + 0x6F8C94)
37 
38 /* AP807 CPU DFS register mapping */
39 #define AP807_DEVICE_GENERAL_CR_10_BASE		(MVEBU_REGS_BASE + 0x6F8278)
40 #define AP807_DEVICE_GENERAL_CR_11_BASE		(MVEBU_REGS_BASE + 0x6F827C)
41 #define AP807_DEVICE_GENERAL_STATUS_6_BASE	(MVEBU_REGS_BASE + 0x6F8C98)
42 
43 #ifdef MVEBU_SOC_AP807
44  #define CLUSTER_OFFSET		0x8
45  #define CLK_DIVIDER_REG	AP807_DEVICE_GENERAL_CR_10_BASE
46  #define CLK_FORCE_REG		AP807_DEVICE_GENERAL_CR_11_BASE
47  #define CLK_RATIO_REG		AP807_DEVICE_GENERAL_CR_11_BASE
48  #define CLK_RATIO_STATE_REG	AP807_DEVICE_GENERAL_STATUS_6_BASE
49 #else
50  #define CLUSTER_OFFSET		0x14
51  #define CLK_DIVIDER_REG		AP806_CA72MP2_0_PLL_CR_0_BASE
52  #define CLK_FORCE_REG		AP806_CA72MP2_0_PLL_CR_1_BASE
53  #define CLK_RATIO_REG		AP806_CA72MP2_0_PLL_CR_2_BASE
54  #define CLK_RATIO_STATE_REG	AP806_CA72MP2_0_PLL_SR_BASE
55 #endif /* MVEBU_SOC_AP807 */
56 
is_valid(u_register_t addr)57 static _Bool is_valid(u_register_t addr)
58 {
59 	switch (addr) {
60 	case AP_DEV_ID_STATUS_REG:
61 	case JTAG_DEV_ID_STATUS_REG:
62 	case SAR_BASE ... (SAR_BASE + SAR_SIZE):
63 	case EFUSE_LD_BASE ... (EFUSE_LD_BASE + EFUSE_LD_SIZE):
64 	case EFUSE_HD_BASE ... (EFUSE_HD_BASE + EFUSE_HD_SIZE):
65 	case EFUSE_CTRL:
66 	/* cpu-clk related registers */
67 	case CLK_DIVIDER_REG:
68 	case CLK_DIVIDER_REG + CLUSTER_OFFSET:
69 	case CLK_FORCE_REG:
70 	case CLK_FORCE_REG + CLUSTER_OFFSET:
71 #ifndef MVEBU_SOC_AP807
72 	case CLK_RATIO_REG:
73 	case CLK_RATIO_REG + CLUSTER_OFFSET:
74 #endif
75 	case CLK_RATIO_STATE_REG:
76 	case CLK_RATIO_STATE_REG + CLUSTER_OFFSET:
77 		return true;
78 	default:
79 		return false;
80 	}
81 }
82 
armada_dfx_sread(u_register_t * read,u_register_t addr)83 static int armada_dfx_sread(u_register_t *read, u_register_t addr)
84 {
85 	if (!is_valid(addr))
86 		return -EINVAL;
87 
88 	*read = mmio_read_32(addr);
89 
90 	return 0;
91 }
92 
armada_dfx_swrite(u_register_t addr,u_register_t val)93 static int armada_dfx_swrite(u_register_t addr, u_register_t val)
94 {
95 	if (!is_valid(addr))
96 		return -EINVAL;
97 
98 	mmio_write_32(addr, val);
99 
100 	return 0;
101 }
102 
mvebu_dfx_misc_handle(u_register_t func,u_register_t * read,u_register_t addr,u_register_t val)103 int mvebu_dfx_misc_handle(u_register_t func, u_register_t *read,
104 			  u_register_t addr, u_register_t val)
105 {
106 	debug_enter();
107 
108 	debug("func %ld, addr 0x%lx, val 0x%lx\n", func, addr, val);
109 
110 	switch (func) {
111 	case MV_SIP_DFX_SREAD:
112 		return armada_dfx_sread(read, addr);
113 	case MV_SIP_DFX_SWRITE:
114 		return armada_dfx_swrite(addr, val);
115 	default:
116 		ERROR("unsupported dfx misc sub-func\n");
117 		return -EINVAL;
118 	}
119 
120 	debug_exit();
121 
122 	return 0;
123 }
124