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 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 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 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 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