uboot/drivers/misc/imx8/scu_api.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright 2018 NXP
   4 *
   5 * Peng Fan <peng.fan@nxp.com>
   6 */
   7
   8#include <common.h>
   9#include <asm/io.h>
  10#include <dm.h>
  11#include <asm/arch/sci/sci.h>
  12#include <misc.h>
  13
  14DECLARE_GLOBAL_DATA_PTR;
  15
  16/* CLK and PM */
  17int sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
  18                         sc_pm_clock_rate_t *rate)
  19{
  20        struct udevice *dev = gd->arch.scu_dev;
  21        int size = sizeof(struct sc_rpc_msg_s);
  22        struct sc_rpc_msg_s msg;
  23        int ret;
  24
  25        RPC_VER(&msg) = SC_RPC_VERSION;
  26        RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
  27        RPC_FUNC(&msg) = (u8)PM_FUNC_SET_CLOCK_RATE;
  28        RPC_U32(&msg, 0U) = *(u32 *)rate;
  29        RPC_U16(&msg, 4U) = (u16)resource;
  30        RPC_U8(&msg, 6U) = (u8)clk;
  31        RPC_SIZE(&msg) = 3U;
  32
  33        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  34        if (ret)
  35                printf("%s: rate:%u resource:%u: clk:%u res:%d\n",
  36                       __func__, *rate, resource, clk, RPC_R8(&msg));
  37
  38        *rate = RPC_U32(&msg, 0U);
  39
  40        return ret;
  41}
  42
  43int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
  44                         sc_pm_clock_rate_t *rate)
  45{
  46        struct udevice *dev = gd->arch.scu_dev;
  47        int size = sizeof(struct sc_rpc_msg_s);
  48        struct sc_rpc_msg_s msg;
  49        int ret;
  50
  51        RPC_VER(&msg) = SC_RPC_VERSION;
  52        RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
  53        RPC_FUNC(&msg) = (u8)PM_FUNC_GET_CLOCK_RATE;
  54        RPC_U16(&msg, 0U) = (u16)resource;
  55        RPC_U8(&msg, 2U) = (u8)clk;
  56        RPC_SIZE(&msg) = 2U;
  57
  58        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  59        if (ret) {
  60                printf("%s: resource:%d clk:%d: res:%d\n",
  61                       __func__, resource, clk, RPC_R8(&msg));
  62                return ret;
  63        }
  64
  65        if (rate)
  66                *rate = RPC_U32(&msg, 0U);
  67
  68        return 0;
  69}
  70
  71int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
  72                       sc_bool_t enable, sc_bool_t autog)
  73{
  74        struct udevice *dev = gd->arch.scu_dev;
  75        int size = sizeof(struct sc_rpc_msg_s);
  76        struct sc_rpc_msg_s msg;
  77        int ret;
  78
  79        RPC_VER(&msg) = SC_RPC_VERSION;
  80        RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
  81        RPC_FUNC(&msg) = (u8)PM_FUNC_CLOCK_ENABLE;
  82        RPC_U16(&msg, 0U) = (u16)resource;
  83        RPC_U8(&msg, 2U) = (u8)clk;
  84        RPC_U8(&msg, 3U) = (u8)enable;
  85        RPC_U8(&msg, 4U) = (u8)autog;
  86        RPC_SIZE(&msg) = 3U;
  87
  88        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  89        if (ret)
  90                printf("%s: resource:%d clk:%d: enable:%d autog: %d, res:%d\n",
  91                       __func__, resource, clk, enable, autog, RPC_R8(&msg));
  92
  93        return ret;
  94}
  95
  96int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
  97                                  sc_pm_power_mode_t mode)
  98{
  99        struct udevice *dev = gd->arch.scu_dev;
 100        int size = sizeof(struct sc_rpc_msg_s);
 101        struct sc_rpc_msg_s msg;
 102        int ret;
 103
 104        if (!dev)
 105                hang();
 106
 107        RPC_VER(&msg) = SC_RPC_VERSION;
 108        RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
 109        RPC_FUNC(&msg) = (u8)PM_FUNC_SET_RESOURCE_POWER_MODE;
 110        RPC_U16(&msg, 0U) = (u16)resource;
 111        RPC_U8(&msg, 2U) = (u8)mode;
 112        RPC_SIZE(&msg) = 2U;
 113
 114        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 115        if (ret)
 116                printf("%s: resource:%d mode:%d: res:%d\n",
 117                       __func__, resource, mode, RPC_R8(&msg));
 118
 119        return ret;
 120}
 121
 122/* PAD */
 123int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
 124{
 125        struct udevice *dev = gd->arch.scu_dev;
 126        int size = sizeof(struct sc_rpc_msg_s);
 127        struct sc_rpc_msg_s msg;
 128        int ret;
 129
 130        if (!dev)
 131                hang();
 132
 133        RPC_VER(&msg) = SC_RPC_VERSION;
 134        RPC_SVC(&msg) = (u8)SC_RPC_SVC_PAD;
 135        RPC_FUNC(&msg) = (u8)PAD_FUNC_SET;
 136        RPC_U32(&msg, 0U) = (u32)val;
 137        RPC_U16(&msg, 4U) = (u16)pad;
 138        RPC_SIZE(&msg) = 3U;
 139
 140        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 141        if (ret)
 142                printf("%s: val:%d pad:%d: res:%d\n",
 143                       __func__, val, pad, RPC_R8(&msg));
 144
 145        return ret;
 146}
 147
 148/* MISC */
 149int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
 150                        u32 *val)
 151{
 152        struct udevice *dev = gd->arch.scu_dev;
 153        int size = sizeof(struct sc_rpc_msg_s);
 154        struct sc_rpc_msg_s msg;
 155        int ret;
 156
 157        if (!dev)
 158                hang();
 159
 160        RPC_VER(&msg) = SC_RPC_VERSION;
 161        RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
 162        RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_CONTROL;
 163        RPC_U32(&msg, 0U) = (u32)ctrl;
 164        RPC_U16(&msg, 4U) = (u16)resource;
 165        RPC_SIZE(&msg) = 3U;
 166
 167        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 168        if (ret)
 169                printf("%s: ctrl:%d resource:%d: res:%d\n",
 170                       __func__, ctrl, resource, RPC_R8(&msg));
 171
 172        if (val)
 173                *val = RPC_U32(&msg, 0U);
 174
 175        return ret;
 176}
 177
 178void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev)
 179{
 180        struct udevice *dev = gd->arch.scu_dev;
 181        int size = sizeof(struct sc_rpc_msg_s);
 182        struct sc_rpc_msg_s msg;
 183        int ret;
 184
 185        if (!dev)
 186                hang();
 187
 188        RPC_VER(&msg) = SC_RPC_VERSION;
 189        RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
 190        RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_DEV;
 191        RPC_SIZE(&msg) = 1U;
 192
 193        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 194        if (ret)
 195                printf("%s: res:%d\n", __func__, RPC_R8(&msg));
 196
 197        if (boot_dev)
 198                *boot_dev = RPC_U16(&msg, 0U);
 199}
 200
 201void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
 202{
 203        struct udevice *dev = gd->arch.scu_dev;
 204        int size = sizeof(struct sc_rpc_msg_s);
 205        struct sc_rpc_msg_s msg;
 206        int ret;
 207
 208        if (!dev)
 209                hang();
 210
 211        RPC_VER(&msg) = SC_RPC_VERSION;
 212        RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
 213        RPC_FUNC(&msg) = (u8)MISC_FUNC_BOOT_STATUS;
 214        RPC_U8(&msg, 0U) = (u8)status;
 215        RPC_SIZE(&msg) = 2U;
 216
 217        ret = misc_call(dev, SC_TRUE, &msg, size, &msg, size);
 218        if (ret)
 219                printf("%s: status:%d res:%d\n",
 220                       __func__, status, RPC_R8(&msg));
 221}
 222
 223void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit)
 224{
 225        struct udevice *dev = gd->arch.scu_dev;
 226        int size = sizeof(struct sc_rpc_msg_s);
 227        struct sc_rpc_msg_s msg;
 228        int ret;
 229
 230        if (!dev)
 231                hang();
 232
 233        RPC_VER(&msg) = SC_RPC_VERSION;
 234        RPC_SVC(&msg) = SC_RPC_SVC_MISC;
 235        RPC_FUNC(&msg) = MISC_FUNC_BUILD_INFO;
 236        RPC_SIZE(&msg) = 1;
 237
 238        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 239        if (ret < 0) {
 240                printf("%s: err: %d\n", __func__, ret);
 241                return;
 242        }
 243
 244        if (build)
 245                *build = RPC_U32(&msg, 0);
 246        if (commit)
 247                *commit = RPC_U32(&msg, 4);
 248}
 249
 250int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val)
 251{
 252        struct udevice *dev = gd->arch.scu_dev;
 253        int size = sizeof(struct sc_rpc_msg_s);
 254        struct sc_rpc_msg_s msg;
 255        int ret;
 256
 257        if (!dev)
 258                hang();
 259
 260        RPC_VER(&msg) = SC_RPC_VERSION;
 261        RPC_SVC(&msg) = SC_RPC_SVC_MISC;
 262        RPC_FUNC(&msg) = MISC_FUNC_OTP_FUSE_READ;
 263        RPC_U32(&msg, 0) = word;
 264        RPC_SIZE(&msg) = 2;
 265
 266        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 267        if (ret < 0)
 268                return ret;
 269
 270        if (val)
 271                *val = RPC_U32(&msg, 0U);
 272
 273        return 0;
 274}
 275
 276int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
 277                     s16 *celsius, s8 *tenths)
 278{
 279        struct udevice *dev = gd->arch.scu_dev;
 280        int size = sizeof(struct sc_rpc_msg_s);
 281        struct sc_rpc_msg_s msg;
 282        int ret;
 283
 284        RPC_VER(&msg) = SC_RPC_VERSION;
 285        RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
 286        RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_TEMP;
 287        RPC_U16(&msg, 0U) = (u16)resource;
 288        RPC_U8(&msg, 2U) = (u8)temp;
 289        RPC_SIZE(&msg) = 2U;
 290
 291        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 292        if (ret < 0)
 293                return ret;
 294
 295        if (celsius)
 296                *celsius = RPC_I16(&msg, 0U);
 297
 298        if (tenths)
 299                *tenths = RPC_I8(&msg, 2U);
 300
 301        return 0;
 302}
 303
 304/* RM */
 305sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
 306{
 307        struct udevice *dev = gd->arch.scu_dev;
 308        int size = sizeof(struct sc_rpc_msg_s);
 309        struct sc_rpc_msg_s msg;
 310        int ret;
 311        sc_err_t result;
 312
 313        if (!dev)
 314                hang();
 315
 316        RPC_VER(&msg) = SC_RPC_VERSION;
 317        RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
 318        RPC_FUNC(&msg) = (u8)RM_FUNC_IS_MEMREG_OWNED;
 319        RPC_U8(&msg, 0U) = (u8)mr;
 320        RPC_SIZE(&msg) = 2U;
 321
 322        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 323        result = RPC_R8(&msg);
 324
 325        if (result != 0 && result != 1) {
 326                printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
 327                if (ret)
 328                        printf("%s: mr:%d res:%d\n", __func__, mr,
 329                               RPC_R8(&msg));
 330        }
 331
 332        return (sc_bool_t)result;
 333}
 334
 335int sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr, sc_faddr_t *addr_start,
 336                          sc_faddr_t *addr_end)
 337{
 338        struct udevice *dev = gd->arch.scu_dev;
 339        int size = sizeof(struct sc_rpc_msg_s);
 340        struct sc_rpc_msg_s msg;
 341        int ret;
 342
 343        if (!dev)
 344                hang();
 345
 346        RPC_VER(&msg) = SC_RPC_VERSION;
 347        RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
 348        RPC_FUNC(&msg) = (u8)RM_FUNC_GET_MEMREG_INFO;
 349        RPC_U8(&msg, 0U) = (u8)mr;
 350        RPC_SIZE(&msg) = 2U;
 351
 352        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 353        if (ret)
 354                printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
 355
 356        if (addr_start)
 357                *addr_start = ((u64)RPC_U32(&msg, 0U) << 32U) |
 358                        RPC_U32(&msg, 4U);
 359
 360        if (addr_end)
 361                *addr_end = ((u64)RPC_U32(&msg, 8U) << 32U) |
 362                        RPC_U32(&msg, 12U);
 363
 364        return ret;
 365}
 366
 367sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
 368{
 369        struct udevice *dev = gd->arch.scu_dev;
 370        int size = sizeof(struct sc_rpc_msg_s);
 371        struct sc_rpc_msg_s msg;
 372        int ret;
 373        u8 result;
 374
 375        if (!dev)
 376                hang();
 377
 378        RPC_VER(&msg) = SC_RPC_VERSION;
 379        RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
 380        RPC_FUNC(&msg) = (u8)RM_FUNC_IS_RESOURCE_OWNED;
 381        RPC_U16(&msg, 0U) = (u16)resource;
 382        RPC_SIZE(&msg) = 2U;
 383
 384        ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
 385        result = RPC_R8(&msg);
 386        if (result != 0 && result != 1) {
 387                printf("%s: resource:%d res:%d\n",
 388                       __func__, resource, RPC_R8(&msg));
 389                if (ret)
 390                        printf("%s: res:%d res:%d\n", __func__, resource,
 391                               RPC_R8(&msg));
 392        }
 393
 394        return !!result;
 395}
 396