diff options
Diffstat (limited to 'drivers/memory/tegra/tegra234.c')
-rw-r--r-- | drivers/memory/tegra/tegra234.c | 574 |
1 files changed, 573 insertions, 1 deletions
diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c index 02dcc5748bba..8fb83b39f5f5 100644 --- a/drivers/memory/tegra/tegra234.c +++ b/drivers/memory/tegra/tegra234.c @@ -1,18 +1,47 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2021-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (C) 2022-2023, NVIDIA CORPORATION. All rights reserved. */ #include <soc/tegra/mc.h> #include <dt-bindings/memory/tegra234-mc.h> +#include <linux/interconnect.h> +#include <linux/tegra-icc.h> +#include <soc/tegra/bpmp.h> #include "mc.h" static const struct tegra_mc_client tegra234_mc_clients[] = { { + .id = TEGRA234_MEMORY_CLIENT_HDAR, + .name = "hdar", + .bpmp_id = TEGRA_ICC_BPMP_HDA, + .type = TEGRA_ICC_ISO_AUDIO, + .sid = TEGRA234_SID_HDA, + .regs = { + .sid = { + .override = 0xa8, + .security = 0xac, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_HDAW, + .name = "hdaw", + .bpmp_id = TEGRA_ICC_BPMP_HDA, + .type = TEGRA_ICC_ISO_AUDIO, + .sid = TEGRA234_SID_HDA, + .regs = { + .sid = { + .override = 0x1a8, + .security = 0x1ac, + }, + }, + }, { .id = TEGRA234_MEMORY_CLIENT_MGBEARD, .name = "mgbeard", + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_MGBE, .regs = { .sid = { @@ -23,6 +52,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_MGBEBRD, .name = "mgbebrd", + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_MGBE_VF1, .regs = { .sid = { @@ -33,6 +64,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_MGBECRD, .name = "mgbecrd", + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_MGBE_VF2, .regs = { .sid = { @@ -43,6 +76,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_MGBEDRD, .name = "mgbedrd", + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_MGBE_VF3, .regs = { .sid = { @@ -52,6 +87,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_MGBEAWR, + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .name = "mgbeawr", .sid = TEGRA234_SID_MGBE, .regs = { @@ -63,6 +100,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_MGBEBWR, .name = "mgbebwr", + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_MGBE_VF1, .regs = { .sid = { @@ -73,6 +112,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_MGBECWR, .name = "mgbecwr", + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_MGBE_VF2, .regs = { .sid = { @@ -83,6 +124,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_SDMMCRAB, .name = "sdmmcrab", + .bpmp_id = TEGRA_ICC_BPMP_SDMMC_4, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_SDMMC4, .regs = { .sid = { @@ -93,6 +136,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_MGBEDWR, .name = "mgbedwr", + .bpmp_id = TEGRA_ICC_BPMP_EQOS, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_MGBE_VF3, .regs = { .sid = { @@ -103,6 +148,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_SDMMCWAB, .name = "sdmmcwab", + .bpmp_id = TEGRA_ICC_BPMP_SDMMC_4, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_SDMMC4, .regs = { .sid = { @@ -111,6 +158,90 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, }, { + .id = TEGRA234_MEMORY_CLIENT_VI2W, + .name = "vi2w", + .bpmp_id = TEGRA_ICC_BPMP_VI2, + .type = TEGRA_ICC_ISO_VI, + .sid = TEGRA234_SID_ISO_VI2, + .regs = { + .sid = { + .override = 0x380, + .security = 0x384, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_VI2FALR, + .name = "vi2falr", + .bpmp_id = TEGRA_ICC_BPMP_VI2FAL, + .type = TEGRA_ICC_ISO_VIFAL, + .sid = TEGRA234_SID_ISO_VI2FALC, + .regs = { + .sid = { + .override = 0x388, + .security = 0x38c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_VI2FALW, + .name = "vi2falw", + .bpmp_id = TEGRA_ICC_BPMP_VI2FAL, + .type = TEGRA_ICC_ISO_VIFAL, + .sid = TEGRA234_SID_ISO_VI2FALC, + .regs = { + .sid = { + .override = 0x3e0, + .security = 0x3e4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_APER, + .name = "aper", + .bpmp_id = TEGRA_ICC_BPMP_APE, + .type = TEGRA_ICC_ISO_AUDIO, + .sid = TEGRA234_SID_APE, + .regs = { + .sid = { + .override = 0x3d0, + .security = 0x3d4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_APEW, + .name = "apew", + .bpmp_id = TEGRA_ICC_BPMP_APE, + .type = TEGRA_ICC_ISO_AUDIO, + .sid = TEGRA234_SID_APE, + .regs = { + .sid = { + .override = 0x3d8, + .security = 0x3dc, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_NVDISPLAYR, + .name = "nvdisplayr", + .bpmp_id = TEGRA_ICC_BPMP_DISPLAY, + .type = TEGRA_ICC_ISO_DISPLAY, + .sid = TEGRA234_SID_ISO_NVDISPLAY, + .regs = { + .sid = { + .override = 0x490, + .security = 0x494, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_NVDISPLAYR1, + .name = "nvdisplayr1", + .bpmp_id = TEGRA_ICC_BPMP_DISPLAY, + .type = TEGRA_ICC_ISO_DISPLAY, + .sid = TEGRA234_SID_ISO_NVDISPLAY, + .regs = { + .sid = { + .override = 0x508, + .security = 0x50c, + }, + }, + }, { .id = TEGRA234_MEMORY_CLIENT_BPMPR, .name = "bpmpr", .sid = TEGRA234_SID_BPMP, @@ -153,6 +284,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_APEDMAR, .name = "apedmar", + .bpmp_id = TEGRA_ICC_BPMP_APEDMA, + .type = TEGRA_ICC_ISO_AUDIO, .sid = TEGRA234_SID_APE, .regs = { .sid = { @@ -163,6 +296,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_APEDMAW, .name = "apedmaw", + .bpmp_id = TEGRA_ICC_BPMP_APEDMA, + .type = TEGRA_ICC_ISO_AUDIO, .sid = TEGRA234_SID_APE, .regs = { .sid = { @@ -330,9 +465,445 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { .security = 0x37c, }, }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE0R, + .name = "pcie0r", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_0, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE0, + .regs = { + .sid = { + .override = 0x6c0, + .security = 0x6c4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE0W, + .name = "pcie0w", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_0, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE0, + .regs = { + .sid = { + .override = 0x6c8, + .security = 0x6cc, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE1R, + .name = "pcie1r", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_1, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE1, + .regs = { + .sid = { + .override = 0x6d0, + .security = 0x6d4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE1W, + .name = "pcie1w", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_1, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE1, + .regs = { + .sid = { + .override = 0x6d8, + .security = 0x6dc, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE2AR, + .name = "pcie2ar", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_2, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE2, + .regs = { + .sid = { + .override = 0x6e0, + .security = 0x6e4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE2AW, + .name = "pcie2aw", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_2, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE2, + .regs = { + .sid = { + .override = 0x6e8, + .security = 0x6ec, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE3R, + .name = "pcie3r", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_3, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE3, + .regs = { + .sid = { + .override = 0x6f0, + .security = 0x6f4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE3W, + .name = "pcie3w", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_3, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE3, + .regs = { + .sid = { + .override = 0x6f8, + .security = 0x6fc, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE4R, + .name = "pcie4r", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_4, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE4, + .regs = { + .sid = { + .override = 0x700, + .security = 0x704, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE4W, + .name = "pcie4w", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_4, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE4, + .regs = { + .sid = { + .override = 0x708, + .security = 0x70c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE5R, + .name = "pcie5r", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_5, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE5, + .regs = { + .sid = { + .override = 0x710, + .security = 0x714, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE5W, + .name = "pcie5w", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_5, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE5, + .regs = { + .sid = { + .override = 0x718, + .security = 0x71c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE5R1, + .name = "pcie5r1", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_5, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE5, + .regs = { + .sid = { + .override = 0x778, + .security = 0x77c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE6AR, + .name = "pcie6ar", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_6, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE6, + .regs = { + .sid = { + .override = 0x140, + .security = 0x144, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE6AW, + .name = "pcie6aw", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_6, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE6, + .regs = { + .sid = { + .override = 0x148, + .security = 0x14c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE6AR1, + .name = "pcie6ar1", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_6, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE6, + .regs = { + .sid = { + .override = 0x1e8, + .security = 0x1ec, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE7AR, + .name = "pcie7ar", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_7, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE7, + .regs = { + .sid = { + .override = 0x150, + .security = 0x154, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE7AW, + .name = "pcie7aw", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_7, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE7, + .regs = { + .sid = { + .override = 0x180, + .security = 0x184, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE7AR1, + .name = "pcie7ar1", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_7, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE7, + .regs = { + .sid = { + .override = 0x248, + .security = 0x24c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE8AR, + .name = "pcie8ar", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_8, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE8, + .regs = { + .sid = { + .override = 0x190, + .security = 0x194, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE8AW, + .name = "pcie8aw", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_8, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE8, + .regs = { + .sid = { + .override = 0x1d8, + .security = 0x1dc, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE9AR, + .name = "pcie9ar", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_9, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE9, + .regs = { + .sid = { + .override = 0x1e0, + .security = 0x1e4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE9AW, + .name = "pcie9aw", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_9, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE9, + .regs = { + .sid = { + .override = 0x1f0, + .security = 0x1f4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE10AR, + .name = "pcie10ar", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_10, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE10, + .regs = { + .sid = { + .override = 0x1f8, + .security = 0x1fc, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE10AW, + .name = "pcie10aw", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_10, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE10, + .regs = { + .sid = { + .override = 0x200, + .security = 0x204, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_PCIE10AR1, + .name = "pcie10ar1", + .bpmp_id = TEGRA_ICC_BPMP_PCIE_10, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_PCIE10, + .regs = { + .sid = { + .override = 0x240, + .security = 0x244, + }, + }, + }, { + .id = TEGRA_ICC_MC_CPU_CLUSTER0, + .name = "sw_cluster0", + .bpmp_id = TEGRA_ICC_BPMP_CPU_CLUSTER0, + .type = TEGRA_ICC_NISO, + }, { + .id = TEGRA_ICC_MC_CPU_CLUSTER1, + .name = "sw_cluster1", + .bpmp_id = TEGRA_ICC_BPMP_CPU_CLUSTER1, + .type = TEGRA_ICC_NISO, + }, { + .id = TEGRA_ICC_MC_CPU_CLUSTER2, + .name = "sw_cluster2", + .bpmp_id = TEGRA_ICC_BPMP_CPU_CLUSTER2, + .type = TEGRA_ICC_NISO, }, }; +/* + * tegra234_mc_icc_set() - Pass MC client info to the BPMP-FW + * @src: ICC node for Memory Controller's (MC) Client + * @dst: ICC node for Memory Controller (MC) + * + * Passing the current request info from the MC to the BPMP-FW where + * LA and PTSA registers are accessed and the final EMC freq is set + * based on client_id, type, latency and bandwidth. + * icc_set_bw() makes set_bw calls for both MC and EMC providers in + * sequence. Both the calls are protected by 'mutex_lock(&icc_lock)'. + * So, the data passed won't be updated by concurrent set calls from + * other clients. + */ +static int tegra234_mc_icc_set(struct icc_node *src, struct icc_node *dst) +{ + struct tegra_mc *mc = icc_provider_to_tegra_mc(dst->provider); + struct mrq_bwmgr_int_request bwmgr_req = { 0 }; + struct mrq_bwmgr_int_response bwmgr_resp = { 0 }; + const struct tegra_mc_client *pclient = src->data; + struct tegra_bpmp_message msg; + int ret; + + /* + * Same Src and Dst node will happen during boot from icc_node_add(). + * This can be used to pre-initialize and set bandwidth for all clients + * before their drivers are loaded. We are skipping this case as for us, + * the pre-initialization already happened in Bootloader(MB2) and BPMP-FW. + */ + if (src->id == dst->id) + return 0; + + if (!mc->bwmgr_mrq_supported) + return 0; + + if (!mc->bpmp) { + dev_err(mc->dev, "BPMP reference NULL\n"); + return -ENOENT; + } + + if (pclient->type == TEGRA_ICC_NISO) + bwmgr_req.bwmgr_calc_set_req.niso_bw = src->avg_bw; + else + bwmgr_req.bwmgr_calc_set_req.iso_bw = src->avg_bw; + + bwmgr_req.bwmgr_calc_set_req.client_id = pclient->bpmp_id; + + bwmgr_req.cmd = CMD_BWMGR_INT_CALC_AND_SET; + bwmgr_req.bwmgr_calc_set_req.mc_floor = src->peak_bw; + bwmgr_req.bwmgr_calc_set_req.floor_unit = BWMGR_INT_UNIT_KBPS; + + memset(&msg, 0, sizeof(msg)); + msg.mrq = MRQ_BWMGR_INT; + msg.tx.data = &bwmgr_req; + msg.tx.size = sizeof(bwmgr_req); + msg.rx.data = &bwmgr_resp; + msg.rx.size = sizeof(bwmgr_resp); + + ret = tegra_bpmp_transfer(mc->bpmp, &msg); + if (ret < 0) { + dev_err(mc->dev, "BPMP transfer failed: %d\n", ret); + goto error; + } + if (msg.rx.ret < 0) { + pr_err("failed to set bandwidth for %u: %d\n", + bwmgr_req.bwmgr_calc_set_req.client_id, msg.rx.ret); + ret = -EINVAL; + } + +error: + return ret; +} + +static int tegra234_mc_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, + u32 peak_bw, u32 *agg_avg, u32 *agg_peak) +{ + struct icc_provider *p = node->provider; + struct tegra_mc *mc = icc_provider_to_tegra_mc(p); + + if (!mc->bwmgr_mrq_supported) + return 0; + + if (node->id == TEGRA_ICC_MC_CPU_CLUSTER0 || + node->id == TEGRA_ICC_MC_CPU_CLUSTER1 || + node->id == TEGRA_ICC_MC_CPU_CLUSTER2) { + if (mc) + peak_bw = peak_bw * mc->num_channels; + } + + *agg_avg += avg_bw; + *agg_peak = max(*agg_peak, peak_bw); + + return 0; +} + +static int tegra234_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak) +{ + *avg = 0; + *peak = 0; + + return 0; +} + +static const struct tegra_mc_icc_ops tegra234_mc_icc_ops = { + .xlate = tegra_mc_icc_xlate, + .aggregate = tegra234_mc_icc_aggregate, + .get_bw = tegra234_mc_icc_get_init_bw, + .set = tegra234_mc_icc_set, +}; + const struct tegra_mc_soc tegra234_mc_soc = { .num_clients = ARRAY_SIZE(tegra234_mc_clients), .clients = tegra234_mc_clients, @@ -345,6 +916,7 @@ const struct tegra_mc_soc tegra234_mc_soc = { MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, .has_addr_hi_reg = true, .ops = &tegra186_mc_ops, + .icc_ops = &tegra234_mc_icc_ops, .ch_intmask = 0x0000ff00, .global_intstatus_channel_shift = 8, /* |