linux/drivers/interconnect/qcom/msm8916.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2018-2020 Linaro Ltd
   4 * Author: Georgi Djakov <georgi.djakov@linaro.org>
   5 */
   6
   7#include <linux/clk.h>
   8#include <linux/device.h>
   9#include <linux/interconnect-provider.h>
  10#include <linux/io.h>
  11#include <linux/module.h>
  12#include <linux/platform_device.h>
  13#include <linux/of_device.h>
  14
  15#include <dt-bindings/interconnect/qcom,msm8916.h>
  16
  17#include "smd-rpm.h"
  18
  19#define RPM_BUS_MASTER_REQ      0x73616d62
  20#define RPM_BUS_SLAVE_REQ       0x766c7362
  21
  22enum {
  23        MSM8916_BIMC_SNOC_MAS = 1,
  24        MSM8916_BIMC_SNOC_SLV,
  25        MSM8916_MASTER_AMPSS_M0,
  26        MSM8916_MASTER_LPASS,
  27        MSM8916_MASTER_BLSP_1,
  28        MSM8916_MASTER_DEHR,
  29        MSM8916_MASTER_GRAPHICS_3D,
  30        MSM8916_MASTER_JPEG,
  31        MSM8916_MASTER_MDP_PORT0,
  32        MSM8916_MASTER_CRYPTO_CORE0,
  33        MSM8916_MASTER_SDCC_1,
  34        MSM8916_MASTER_SDCC_2,
  35        MSM8916_MASTER_QDSS_BAM,
  36        MSM8916_MASTER_QDSS_ETR,
  37        MSM8916_MASTER_SNOC_CFG,
  38        MSM8916_MASTER_SPDM,
  39        MSM8916_MASTER_TCU0,
  40        MSM8916_MASTER_TCU1,
  41        MSM8916_MASTER_USB_HS,
  42        MSM8916_MASTER_VFE,
  43        MSM8916_MASTER_VIDEO_P0,
  44        MSM8916_SNOC_MM_INT_0,
  45        MSM8916_SNOC_MM_INT_1,
  46        MSM8916_SNOC_MM_INT_2,
  47        MSM8916_SNOC_MM_INT_BIMC,
  48        MSM8916_PNOC_INT_0,
  49        MSM8916_PNOC_INT_1,
  50        MSM8916_PNOC_MAS_0,
  51        MSM8916_PNOC_MAS_1,
  52        MSM8916_PNOC_SLV_0,
  53        MSM8916_PNOC_SLV_1,
  54        MSM8916_PNOC_SLV_2,
  55        MSM8916_PNOC_SLV_3,
  56        MSM8916_PNOC_SLV_4,
  57        MSM8916_PNOC_SLV_8,
  58        MSM8916_PNOC_SLV_9,
  59        MSM8916_PNOC_SNOC_MAS,
  60        MSM8916_PNOC_SNOC_SLV,
  61        MSM8916_SNOC_QDSS_INT,
  62        MSM8916_SLAVE_AMPSS_L2,
  63        MSM8916_SLAVE_APSS,
  64        MSM8916_SLAVE_LPASS,
  65        MSM8916_SLAVE_BIMC_CFG,
  66        MSM8916_SLAVE_BLSP_1,
  67        MSM8916_SLAVE_BOOT_ROM,
  68        MSM8916_SLAVE_CAMERA_CFG,
  69        MSM8916_SLAVE_CATS_128,
  70        MSM8916_SLAVE_OCMEM_64,
  71        MSM8916_SLAVE_CLK_CTL,
  72        MSM8916_SLAVE_CRYPTO_0_CFG,
  73        MSM8916_SLAVE_DEHR_CFG,
  74        MSM8916_SLAVE_DISPLAY_CFG,
  75        MSM8916_SLAVE_EBI_CH0,
  76        MSM8916_SLAVE_GRAPHICS_3D_CFG,
  77        MSM8916_SLAVE_IMEM_CFG,
  78        MSM8916_SLAVE_IMEM,
  79        MSM8916_SLAVE_MPM,
  80        MSM8916_SLAVE_MSG_RAM,
  81        MSM8916_SLAVE_MSS,
  82        MSM8916_SLAVE_PDM,
  83        MSM8916_SLAVE_PMIC_ARB,
  84        MSM8916_SLAVE_PNOC_CFG,
  85        MSM8916_SLAVE_PRNG,
  86        MSM8916_SLAVE_QDSS_CFG,
  87        MSM8916_SLAVE_QDSS_STM,
  88        MSM8916_SLAVE_RBCPR_CFG,
  89        MSM8916_SLAVE_SDCC_1,
  90        MSM8916_SLAVE_SDCC_2,
  91        MSM8916_SLAVE_SECURITY,
  92        MSM8916_SLAVE_SNOC_CFG,
  93        MSM8916_SLAVE_SPDM,
  94        MSM8916_SLAVE_SRVC_SNOC,
  95        MSM8916_SLAVE_TCSR,
  96        MSM8916_SLAVE_TLMM,
  97        MSM8916_SLAVE_USB_HS,
  98        MSM8916_SLAVE_VENUS_CFG,
  99        MSM8916_SNOC_BIMC_0_MAS,
 100        MSM8916_SNOC_BIMC_0_SLV,
 101        MSM8916_SNOC_BIMC_1_MAS,
 102        MSM8916_SNOC_BIMC_1_SLV,
 103        MSM8916_SNOC_INT_0,
 104        MSM8916_SNOC_INT_1,
 105        MSM8916_SNOC_INT_BIMC,
 106        MSM8916_SNOC_PNOC_MAS,
 107        MSM8916_SNOC_PNOC_SLV,
 108};
 109
 110#define to_msm8916_provider(_provider) \
 111        container_of(_provider, struct msm8916_icc_provider, provider)
 112
 113static const struct clk_bulk_data msm8916_bus_clocks[] = {
 114        { .id = "bus" },
 115        { .id = "bus_a" },
 116};
 117
 118/**
 119 * struct msm8916_icc_provider - Qualcomm specific interconnect provider
 120 * @provider: generic interconnect provider
 121 * @bus_clks: the clk_bulk_data table of bus clocks
 122 * @num_clks: the total number of clk_bulk_data entries
 123 */
 124struct msm8916_icc_provider {
 125        struct icc_provider provider;
 126        struct clk_bulk_data *bus_clks;
 127        int num_clks;
 128};
 129
 130#define MSM8916_MAX_LINKS       8
 131
 132/**
 133 * struct msm8916_icc_node - Qualcomm specific interconnect nodes
 134 * @name: the node name used in debugfs
 135 * @id: a unique node identifier
 136 * @links: an array of nodes where we can go next while traversing
 137 * @num_links: the total number of @links
 138 * @buswidth: width of the interconnect between a node and the bus (bytes)
 139 * @mas_rpm_id: RPM ID for devices that are bus masters
 140 * @slv_rpm_id: RPM ID for devices that are bus slaves
 141 * @rate: current bus clock rate in Hz
 142 */
 143struct msm8916_icc_node {
 144        unsigned char *name;
 145        u16 id;
 146        u16 links[MSM8916_MAX_LINKS];
 147        u16 num_links;
 148        u16 buswidth;
 149        int mas_rpm_id;
 150        int slv_rpm_id;
 151        u64 rate;
 152};
 153
 154struct msm8916_icc_desc {
 155        struct msm8916_icc_node **nodes;
 156        size_t num_nodes;
 157};
 158
 159#define DEFINE_QNODE(_name, _id, _buswidth, _mas_rpm_id, _slv_rpm_id,   \
 160                                        ...)                            \
 161                static struct msm8916_icc_node _name = {                \
 162                .name = #_name,                                         \
 163                .id = _id,                                              \
 164                .buswidth = _buswidth,                                  \
 165                .mas_rpm_id = _mas_rpm_id,                              \
 166                .slv_rpm_id = _slv_rpm_id,                              \
 167                .num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),      \
 168                .links = { __VA_ARGS__ },                               \
 169        }
 170
 171DEFINE_QNODE(bimc_snoc_mas, MSM8916_BIMC_SNOC_MAS, 8, -1, -1, MSM8916_BIMC_SNOC_SLV);
 172DEFINE_QNODE(bimc_snoc_slv, MSM8916_BIMC_SNOC_SLV, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_1);
 173DEFINE_QNODE(mas_apss, MSM8916_MASTER_AMPSS_M0, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2);
 174DEFINE_QNODE(mas_audio, MSM8916_MASTER_LPASS, 4, -1, -1, MSM8916_PNOC_MAS_0);
 175DEFINE_QNODE(mas_blsp_1, MSM8916_MASTER_BLSP_1, 4, -1, -1, MSM8916_PNOC_MAS_1);
 176DEFINE_QNODE(mas_dehr, MSM8916_MASTER_DEHR, 4, -1, -1, MSM8916_PNOC_MAS_0);
 177DEFINE_QNODE(mas_gfx, MSM8916_MASTER_GRAPHICS_3D, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2);
 178DEFINE_QNODE(mas_jpeg, MSM8916_MASTER_JPEG, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2);
 179DEFINE_QNODE(mas_mdp, MSM8916_MASTER_MDP_PORT0, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2);
 180DEFINE_QNODE(mas_pcnoc_crypto_0, MSM8916_MASTER_CRYPTO_CORE0, 8, -1, -1, MSM8916_PNOC_INT_1);
 181DEFINE_QNODE(mas_pcnoc_sdcc_1, MSM8916_MASTER_SDCC_1, 8, -1, -1, MSM8916_PNOC_INT_1);
 182DEFINE_QNODE(mas_pcnoc_sdcc_2, MSM8916_MASTER_SDCC_2, 8, -1, -1, MSM8916_PNOC_INT_1);
 183DEFINE_QNODE(mas_qdss_bam, MSM8916_MASTER_QDSS_BAM, 8, -1, -1, MSM8916_SNOC_QDSS_INT);
 184DEFINE_QNODE(mas_qdss_etr, MSM8916_MASTER_QDSS_ETR, 8, -1, -1, MSM8916_SNOC_QDSS_INT);
 185DEFINE_QNODE(mas_snoc_cfg, MSM8916_MASTER_SNOC_CFG, 4, -1, -1, MSM8916_SNOC_QDSS_INT);
 186DEFINE_QNODE(mas_spdm, MSM8916_MASTER_SPDM, 4, -1, -1, MSM8916_PNOC_MAS_0);
 187DEFINE_QNODE(mas_tcu0, MSM8916_MASTER_TCU0, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2);
 188DEFINE_QNODE(mas_tcu1, MSM8916_MASTER_TCU1, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2);
 189DEFINE_QNODE(mas_usb_hs, MSM8916_MASTER_USB_HS, 4, -1, -1, MSM8916_PNOC_MAS_1);
 190DEFINE_QNODE(mas_vfe, MSM8916_MASTER_VFE, 16, -1, -1, MSM8916_SNOC_MM_INT_1, MSM8916_SNOC_MM_INT_2);
 191DEFINE_QNODE(mas_video, MSM8916_MASTER_VIDEO_P0, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2);
 192DEFINE_QNODE(mm_int_0, MSM8916_SNOC_MM_INT_0, 16, -1, -1, MSM8916_SNOC_MM_INT_BIMC);
 193DEFINE_QNODE(mm_int_1, MSM8916_SNOC_MM_INT_1, 16, -1, -1, MSM8916_SNOC_MM_INT_BIMC);
 194DEFINE_QNODE(mm_int_2, MSM8916_SNOC_MM_INT_2, 16, -1, -1, MSM8916_SNOC_INT_0);
 195DEFINE_QNODE(mm_int_bimc, MSM8916_SNOC_MM_INT_BIMC, 16, -1, -1, MSM8916_SNOC_BIMC_1_MAS);
 196DEFINE_QNODE(pcnoc_int_0, MSM8916_PNOC_INT_0, 8, -1, -1, MSM8916_PNOC_SNOC_MAS, MSM8916_PNOC_SLV_0, MSM8916_PNOC_SLV_1, MSM8916_PNOC_SLV_2, MSM8916_PNOC_SLV_3, MSM8916_PNOC_SLV_4, MSM8916_PNOC_SLV_8, MSM8916_PNOC_SLV_9);
 197DEFINE_QNODE(pcnoc_int_1, MSM8916_PNOC_INT_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS);
 198DEFINE_QNODE(pcnoc_m_0, MSM8916_PNOC_MAS_0, 8, -1, -1, MSM8916_PNOC_INT_0);
 199DEFINE_QNODE(pcnoc_m_1, MSM8916_PNOC_MAS_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS);
 200DEFINE_QNODE(pcnoc_s_0, MSM8916_PNOC_SLV_0, 4, -1, -1, MSM8916_SLAVE_CLK_CTL, MSM8916_SLAVE_TLMM, MSM8916_SLAVE_TCSR, MSM8916_SLAVE_SECURITY, MSM8916_SLAVE_MSS);
 201DEFINE_QNODE(pcnoc_s_1, MSM8916_PNOC_SLV_1, 4, -1, -1, MSM8916_SLAVE_IMEM_CFG, MSM8916_SLAVE_CRYPTO_0_CFG, MSM8916_SLAVE_MSG_RAM, MSM8916_SLAVE_PDM, MSM8916_SLAVE_PRNG);
 202DEFINE_QNODE(pcnoc_s_2, MSM8916_PNOC_SLV_2, 4, -1, -1, MSM8916_SLAVE_SPDM, MSM8916_SLAVE_BOOT_ROM, MSM8916_SLAVE_BIMC_CFG, MSM8916_SLAVE_PNOC_CFG, MSM8916_SLAVE_PMIC_ARB);
 203DEFINE_QNODE(pcnoc_s_3, MSM8916_PNOC_SLV_3, 4, -1, -1, MSM8916_SLAVE_MPM, MSM8916_SLAVE_SNOC_CFG, MSM8916_SLAVE_RBCPR_CFG, MSM8916_SLAVE_QDSS_CFG, MSM8916_SLAVE_DEHR_CFG);
 204DEFINE_QNODE(pcnoc_s_4, MSM8916_PNOC_SLV_4, 4, -1, -1, MSM8916_SLAVE_VENUS_CFG, MSM8916_SLAVE_CAMERA_CFG, MSM8916_SLAVE_DISPLAY_CFG);
 205DEFINE_QNODE(pcnoc_s_8, MSM8916_PNOC_SLV_8, 4, -1, -1, MSM8916_SLAVE_USB_HS, MSM8916_SLAVE_SDCC_1, MSM8916_SLAVE_BLSP_1);
 206DEFINE_QNODE(pcnoc_s_9, MSM8916_PNOC_SLV_9, 4, -1, -1, MSM8916_SLAVE_SDCC_2, MSM8916_SLAVE_LPASS, MSM8916_SLAVE_GRAPHICS_3D_CFG);
 207DEFINE_QNODE(pcnoc_snoc_mas, MSM8916_PNOC_SNOC_MAS, 8, 29, -1, MSM8916_PNOC_SNOC_SLV);
 208DEFINE_QNODE(pcnoc_snoc_slv, MSM8916_PNOC_SNOC_SLV, 8, -1, 45, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC, MSM8916_SNOC_INT_1);
 209DEFINE_QNODE(qdss_int, MSM8916_SNOC_QDSS_INT, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC);
 210DEFINE_QNODE(slv_apps_l2, MSM8916_SLAVE_AMPSS_L2, 8, -1, -1, 0);
 211DEFINE_QNODE(slv_apss, MSM8916_SLAVE_APSS, 4, -1, -1, 0);
 212DEFINE_QNODE(slv_audio, MSM8916_SLAVE_LPASS, 4, -1, -1, 0);
 213DEFINE_QNODE(slv_bimc_cfg, MSM8916_SLAVE_BIMC_CFG, 4, -1, -1, 0);
 214DEFINE_QNODE(slv_blsp_1, MSM8916_SLAVE_BLSP_1, 4, -1, -1, 0);
 215DEFINE_QNODE(slv_boot_rom, MSM8916_SLAVE_BOOT_ROM, 4, -1, -1, 0);
 216DEFINE_QNODE(slv_camera_cfg, MSM8916_SLAVE_CAMERA_CFG, 4, -1, -1, 0);
 217DEFINE_QNODE(slv_cats_0, MSM8916_SLAVE_CATS_128, 16, -1, -1, 0);
 218DEFINE_QNODE(slv_cats_1, MSM8916_SLAVE_OCMEM_64, 8, -1, -1, 0);
 219DEFINE_QNODE(slv_clk_ctl, MSM8916_SLAVE_CLK_CTL, 4, -1, -1, 0);
 220DEFINE_QNODE(slv_crypto_0_cfg, MSM8916_SLAVE_CRYPTO_0_CFG, 4, -1, -1, 0);
 221DEFINE_QNODE(slv_dehr_cfg, MSM8916_SLAVE_DEHR_CFG, 4, -1, -1, 0);
 222DEFINE_QNODE(slv_display_cfg, MSM8916_SLAVE_DISPLAY_CFG, 4, -1, -1, 0);
 223DEFINE_QNODE(slv_ebi_ch0, MSM8916_SLAVE_EBI_CH0, 8, -1, 0, 0);
 224DEFINE_QNODE(slv_gfx_cfg, MSM8916_SLAVE_GRAPHICS_3D_CFG, 4, -1, -1, 0);
 225DEFINE_QNODE(slv_imem_cfg, MSM8916_SLAVE_IMEM_CFG, 4, -1, -1, 0);
 226DEFINE_QNODE(slv_imem, MSM8916_SLAVE_IMEM, 8, -1, 26, 0);
 227DEFINE_QNODE(slv_mpm, MSM8916_SLAVE_MPM, 4, -1, -1, 0);
 228DEFINE_QNODE(slv_msg_ram, MSM8916_SLAVE_MSG_RAM, 4, -1, -1, 0);
 229DEFINE_QNODE(slv_mss, MSM8916_SLAVE_MSS, 4, -1, -1, 0);
 230DEFINE_QNODE(slv_pdm, MSM8916_SLAVE_PDM, 4, -1, -1, 0);
 231DEFINE_QNODE(slv_pmic_arb, MSM8916_SLAVE_PMIC_ARB, 4, -1, -1, 0);
 232DEFINE_QNODE(slv_pcnoc_cfg, MSM8916_SLAVE_PNOC_CFG, 4, -1, -1, 0);
 233DEFINE_QNODE(slv_prng, MSM8916_SLAVE_PRNG, 4, -1, -1, 0);
 234DEFINE_QNODE(slv_qdss_cfg, MSM8916_SLAVE_QDSS_CFG, 4, -1, -1, 0);
 235DEFINE_QNODE(slv_qdss_stm, MSM8916_SLAVE_QDSS_STM, 4, -1, 30, 0);
 236DEFINE_QNODE(slv_rbcpr_cfg, MSM8916_SLAVE_RBCPR_CFG, 4, -1, -1, 0);
 237DEFINE_QNODE(slv_sdcc_1, MSM8916_SLAVE_SDCC_1, 4, -1, -1, 0);
 238DEFINE_QNODE(slv_sdcc_2, MSM8916_SLAVE_SDCC_2, 4, -1, -1, 0);
 239DEFINE_QNODE(slv_security, MSM8916_SLAVE_SECURITY, 4, -1, -1, 0);
 240DEFINE_QNODE(slv_snoc_cfg, MSM8916_SLAVE_SNOC_CFG, 4, -1, -1, 0);
 241DEFINE_QNODE(slv_spdm, MSM8916_SLAVE_SPDM, 4, -1, -1, 0);
 242DEFINE_QNODE(slv_srvc_snoc, MSM8916_SLAVE_SRVC_SNOC, 8, -1, -1, 0);
 243DEFINE_QNODE(slv_tcsr, MSM8916_SLAVE_TCSR, 4, -1, -1, 0);
 244DEFINE_QNODE(slv_tlmm, MSM8916_SLAVE_TLMM, 4, -1, -1, 0);
 245DEFINE_QNODE(slv_usb_hs, MSM8916_SLAVE_USB_HS, 4, -1, -1, 0);
 246DEFINE_QNODE(slv_venus_cfg, MSM8916_SLAVE_VENUS_CFG, 4, -1, -1, 0);
 247DEFINE_QNODE(snoc_bimc_0_mas, MSM8916_SNOC_BIMC_0_MAS, 8, 3, -1, MSM8916_SNOC_BIMC_0_SLV);
 248DEFINE_QNODE(snoc_bimc_0_slv, MSM8916_SNOC_BIMC_0_SLV, 8, -1, 24, MSM8916_SLAVE_EBI_CH0);
 249DEFINE_QNODE(snoc_bimc_1_mas, MSM8916_SNOC_BIMC_1_MAS, 16, -1, -1, MSM8916_SNOC_BIMC_1_SLV);
 250DEFINE_QNODE(snoc_bimc_1_slv, MSM8916_SNOC_BIMC_1_SLV, 8, -1, -1, MSM8916_SLAVE_EBI_CH0);
 251DEFINE_QNODE(snoc_int_0, MSM8916_SNOC_INT_0, 8, 99, 130, MSM8916_SLAVE_QDSS_STM, MSM8916_SLAVE_IMEM, MSM8916_SNOC_PNOC_MAS);
 252DEFINE_QNODE(snoc_int_1, MSM8916_SNOC_INT_1, 8, -1, -1, MSM8916_SLAVE_APSS, MSM8916_SLAVE_CATS_128, MSM8916_SLAVE_OCMEM_64);
 253DEFINE_QNODE(snoc_int_bimc, MSM8916_SNOC_INT_BIMC, 8, 101, 132, MSM8916_SNOC_BIMC_0_MAS);
 254DEFINE_QNODE(snoc_pcnoc_mas, MSM8916_SNOC_PNOC_MAS, 8, -1, -1, MSM8916_SNOC_PNOC_SLV);
 255DEFINE_QNODE(snoc_pcnoc_slv, MSM8916_SNOC_PNOC_SLV, 8, -1, -1, MSM8916_PNOC_INT_0);
 256
 257static struct msm8916_icc_node *msm8916_snoc_nodes[] = {
 258        [BIMC_SNOC_SLV] = &bimc_snoc_slv,
 259        [MASTER_JPEG] = &mas_jpeg,
 260        [MASTER_MDP_PORT0] = &mas_mdp,
 261        [MASTER_QDSS_BAM] = &mas_qdss_bam,
 262        [MASTER_QDSS_ETR] = &mas_qdss_etr,
 263        [MASTER_SNOC_CFG] = &mas_snoc_cfg,
 264        [MASTER_VFE] = &mas_vfe,
 265        [MASTER_VIDEO_P0] = &mas_video,
 266        [SNOC_MM_INT_0] = &mm_int_0,
 267        [SNOC_MM_INT_1] = &mm_int_1,
 268        [SNOC_MM_INT_2] = &mm_int_2,
 269        [SNOC_MM_INT_BIMC] = &mm_int_bimc,
 270        [PCNOC_SNOC_SLV] = &pcnoc_snoc_slv,
 271        [SLAVE_APSS] = &slv_apss,
 272        [SLAVE_CATS_128] = &slv_cats_0,
 273        [SLAVE_OCMEM_64] = &slv_cats_1,
 274        [SLAVE_IMEM] = &slv_imem,
 275        [SLAVE_QDSS_STM] = &slv_qdss_stm,
 276        [SLAVE_SRVC_SNOC] = &slv_srvc_snoc,
 277        [SNOC_BIMC_0_MAS] = &snoc_bimc_0_mas,
 278        [SNOC_BIMC_1_MAS] = &snoc_bimc_1_mas,
 279        [SNOC_INT_0] = &snoc_int_0,
 280        [SNOC_INT_1] = &snoc_int_1,
 281        [SNOC_INT_BIMC] = &snoc_int_bimc,
 282        [SNOC_PCNOC_MAS] = &snoc_pcnoc_mas,
 283        [SNOC_QDSS_INT] = &qdss_int,
 284};
 285
 286static struct msm8916_icc_desc msm8916_snoc = {
 287        .nodes = msm8916_snoc_nodes,
 288        .num_nodes = ARRAY_SIZE(msm8916_snoc_nodes),
 289};
 290
 291static struct msm8916_icc_node *msm8916_bimc_nodes[] = {
 292        [BIMC_SNOC_MAS] = &bimc_snoc_mas,
 293        [MASTER_AMPSS_M0] = &mas_apss,
 294        [MASTER_GRAPHICS_3D] = &mas_gfx,
 295        [MASTER_TCU0] = &mas_tcu0,
 296        [MASTER_TCU1] = &mas_tcu1,
 297        [SLAVE_AMPSS_L2] = &slv_apps_l2,
 298        [SLAVE_EBI_CH0] = &slv_ebi_ch0,
 299        [SNOC_BIMC_0_SLV] = &snoc_bimc_0_slv,
 300        [SNOC_BIMC_1_SLV] = &snoc_bimc_1_slv,
 301};
 302
 303static struct msm8916_icc_desc msm8916_bimc = {
 304        .nodes = msm8916_bimc_nodes,
 305        .num_nodes = ARRAY_SIZE(msm8916_bimc_nodes),
 306};
 307
 308static struct msm8916_icc_node *msm8916_pcnoc_nodes[] = {
 309        [MASTER_BLSP_1] = &mas_blsp_1,
 310        [MASTER_DEHR] = &mas_dehr,
 311        [MASTER_LPASS] = &mas_audio,
 312        [MASTER_CRYPTO_CORE0] = &mas_pcnoc_crypto_0,
 313        [MASTER_SDCC_1] = &mas_pcnoc_sdcc_1,
 314        [MASTER_SDCC_2] = &mas_pcnoc_sdcc_2,
 315        [MASTER_SPDM] = &mas_spdm,
 316        [MASTER_USB_HS] = &mas_usb_hs,
 317        [PCNOC_INT_0] = &pcnoc_int_0,
 318        [PCNOC_INT_1] = &pcnoc_int_1,
 319        [PCNOC_MAS_0] = &pcnoc_m_0,
 320        [PCNOC_MAS_1] = &pcnoc_m_1,
 321        [PCNOC_SLV_0] = &pcnoc_s_0,
 322        [PCNOC_SLV_1] = &pcnoc_s_1,
 323        [PCNOC_SLV_2] = &pcnoc_s_2,
 324        [PCNOC_SLV_3] = &pcnoc_s_3,
 325        [PCNOC_SLV_4] = &pcnoc_s_4,
 326        [PCNOC_SLV_8] = &pcnoc_s_8,
 327        [PCNOC_SLV_9] = &pcnoc_s_9,
 328        [PCNOC_SNOC_MAS] = &pcnoc_snoc_mas,
 329        [SLAVE_BIMC_CFG] = &slv_bimc_cfg,
 330        [SLAVE_BLSP_1] = &slv_blsp_1,
 331        [SLAVE_BOOT_ROM] = &slv_boot_rom,
 332        [SLAVE_CAMERA_CFG] = &slv_camera_cfg,
 333        [SLAVE_CLK_CTL] = &slv_clk_ctl,
 334        [SLAVE_CRYPTO_0_CFG] = &slv_crypto_0_cfg,
 335        [SLAVE_DEHR_CFG] = &slv_dehr_cfg,
 336        [SLAVE_DISPLAY_CFG] = &slv_display_cfg,
 337        [SLAVE_GRAPHICS_3D_CFG] = &slv_gfx_cfg,
 338        [SLAVE_IMEM_CFG] = &slv_imem_cfg,
 339        [SLAVE_LPASS] = &slv_audio,
 340        [SLAVE_MPM] = &slv_mpm,
 341        [SLAVE_MSG_RAM] = &slv_msg_ram,
 342        [SLAVE_MSS] = &slv_mss,
 343        [SLAVE_PDM] = &slv_pdm,
 344        [SLAVE_PMIC_ARB] = &slv_pmic_arb,
 345        [SLAVE_PCNOC_CFG] = &slv_pcnoc_cfg,
 346        [SLAVE_PRNG] = &slv_prng,
 347        [SLAVE_QDSS_CFG] = &slv_qdss_cfg,
 348        [SLAVE_RBCPR_CFG] = &slv_rbcpr_cfg,
 349        [SLAVE_SDCC_1] = &slv_sdcc_1,
 350        [SLAVE_SDCC_2] = &slv_sdcc_2,
 351        [SLAVE_SECURITY] = &slv_security,
 352        [SLAVE_SNOC_CFG] = &slv_snoc_cfg,
 353        [SLAVE_SPDM] = &slv_spdm,
 354        [SLAVE_TCSR] = &slv_tcsr,
 355        [SLAVE_TLMM] = &slv_tlmm,
 356        [SLAVE_USB_HS] = &slv_usb_hs,
 357        [SLAVE_VENUS_CFG] = &slv_venus_cfg,
 358        [SNOC_PCNOC_SLV] = &snoc_pcnoc_slv,
 359};
 360
 361static struct msm8916_icc_desc msm8916_pcnoc = {
 362        .nodes = msm8916_pcnoc_nodes,
 363        .num_nodes = ARRAY_SIZE(msm8916_pcnoc_nodes),
 364};
 365
 366static int msm8916_icc_set(struct icc_node *src, struct icc_node *dst)
 367{
 368        struct msm8916_icc_provider *qp;
 369        struct msm8916_icc_node *qn;
 370        u64 sum_bw, max_peak_bw, rate;
 371        u32 agg_avg = 0, agg_peak = 0;
 372        struct icc_provider *provider;
 373        struct icc_node *n;
 374        int ret, i;
 375
 376        qn = src->data;
 377        provider = src->provider;
 378        qp = to_msm8916_provider(provider);
 379
 380        list_for_each_entry(n, &provider->nodes, node_list)
 381                provider->aggregate(n, 0, n->avg_bw, n->peak_bw,
 382                                    &agg_avg, &agg_peak);
 383
 384        sum_bw = icc_units_to_bps(agg_avg);
 385        max_peak_bw = icc_units_to_bps(agg_peak);
 386
 387        /* send bandwidth request message to the RPM processor */
 388        if (qn->mas_rpm_id != -1) {
 389                ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
 390                                            RPM_BUS_MASTER_REQ,
 391                                            qn->mas_rpm_id,
 392                                            sum_bw);
 393                if (ret) {
 394                        pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
 395                               qn->mas_rpm_id, ret);
 396                        return ret;
 397                }
 398        }
 399
 400        if (qn->slv_rpm_id != -1) {
 401                ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
 402                                            RPM_BUS_SLAVE_REQ,
 403                                            qn->slv_rpm_id,
 404                                            sum_bw);
 405                if (ret) {
 406                        pr_err("qcom_icc_rpm_smd_send slv error %d\n",
 407                               ret);
 408                        return ret;
 409                }
 410        }
 411
 412        rate = max(sum_bw, max_peak_bw);
 413
 414        do_div(rate, qn->buswidth);
 415
 416        if (qn->rate == rate)
 417                return 0;
 418
 419        for (i = 0; i < qp->num_clks; i++) {
 420                ret = clk_set_rate(qp->bus_clks[i].clk, rate);
 421                if (ret) {
 422                        pr_err("%s clk_set_rate error: %d\n",
 423                               qp->bus_clks[i].id, ret);
 424                        return ret;
 425                }
 426        }
 427
 428        qn->rate = rate;
 429
 430        return 0;
 431}
 432
 433static int msm8916_qnoc_probe(struct platform_device *pdev)
 434{
 435        const struct msm8916_icc_desc *desc;
 436        struct msm8916_icc_node **qnodes;
 437        struct msm8916_icc_provider *qp;
 438        struct device *dev = &pdev->dev;
 439        struct icc_onecell_data *data;
 440        struct icc_provider *provider;
 441        struct icc_node *node;
 442        size_t num_nodes, i;
 443        int ret;
 444
 445        /* wait for the RPM proxy */
 446        if (!qcom_icc_rpm_smd_available())
 447                return -EPROBE_DEFER;
 448
 449        desc = of_device_get_match_data(dev);
 450        if (!desc)
 451                return -EINVAL;
 452
 453        qnodes = desc->nodes;
 454        num_nodes = desc->num_nodes;
 455
 456        qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL);
 457        if (!qp)
 458                return -ENOMEM;
 459
 460        data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
 461                            GFP_KERNEL);
 462        if (!data)
 463                return -ENOMEM;
 464
 465        qp->bus_clks = devm_kmemdup(dev, msm8916_bus_clocks,
 466                                    sizeof(msm8916_bus_clocks), GFP_KERNEL);
 467        if (!qp->bus_clks)
 468                return -ENOMEM;
 469
 470        qp->num_clks = ARRAY_SIZE(msm8916_bus_clocks);
 471        ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
 472        if (ret)
 473                return ret;
 474
 475        ret = clk_bulk_prepare_enable(qp->num_clks, qp->bus_clks);
 476        if (ret)
 477                return ret;
 478
 479        provider = &qp->provider;
 480        INIT_LIST_HEAD(&provider->nodes);
 481        provider->dev = dev;
 482        provider->set = msm8916_icc_set;
 483        provider->aggregate = icc_std_aggregate;
 484        provider->xlate = of_icc_xlate_onecell;
 485        provider->data = data;
 486
 487        ret = icc_provider_add(provider);
 488        if (ret) {
 489                dev_err(dev, "error adding interconnect provider: %d\n", ret);
 490                clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
 491                return ret;
 492        }
 493
 494        for (i = 0; i < num_nodes; i++) {
 495                size_t j;
 496
 497                node = icc_node_create(qnodes[i]->id);
 498                if (IS_ERR(node)) {
 499                        ret = PTR_ERR(node);
 500                        goto err;
 501                }
 502
 503                node->name = qnodes[i]->name;
 504                node->data = qnodes[i];
 505                icc_node_add(node, provider);
 506
 507                for (j = 0; j < qnodes[i]->num_links; j++)
 508                        icc_link_create(node, qnodes[i]->links[j]);
 509
 510                data->nodes[i] = node;
 511        }
 512        data->num_nodes = num_nodes;
 513
 514        platform_set_drvdata(pdev, qp);
 515
 516        return 0;
 517
 518err:
 519        icc_nodes_remove(provider);
 520        icc_provider_del(provider);
 521        clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
 522
 523        return ret;
 524}
 525
 526static int msm8916_qnoc_remove(struct platform_device *pdev)
 527{
 528        struct msm8916_icc_provider *qp = platform_get_drvdata(pdev);
 529
 530        icc_nodes_remove(&qp->provider);
 531        clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
 532        return icc_provider_del(&qp->provider);
 533}
 534
 535static const struct of_device_id msm8916_noc_of_match[] = {
 536        { .compatible = "qcom,msm8916-bimc", .data = &msm8916_bimc },
 537        { .compatible = "qcom,msm8916-pcnoc", .data = &msm8916_pcnoc },
 538        { .compatible = "qcom,msm8916-snoc", .data = &msm8916_snoc },
 539        { }
 540};
 541MODULE_DEVICE_TABLE(of, msm8916_noc_of_match);
 542
 543static struct platform_driver msm8916_noc_driver = {
 544        .probe = msm8916_qnoc_probe,
 545        .remove = msm8916_qnoc_remove,
 546        .driver = {
 547                .name = "qnoc-msm8916",
 548                .of_match_table = msm8916_noc_of_match,
 549        },
 550};
 551module_platform_driver(msm8916_noc_driver);
 552MODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>");
 553MODULE_DESCRIPTION("Qualcomm MSM8916 NoC driver");
 554MODULE_LICENSE("GPL v2");
 555