uboot/drivers/misc/imx8ulp/s400_api.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright 2020 NXP
   4 *
   5 */
   6
   7#include <common.h>
   8#include <hang.h>
   9#include <malloc.h>
  10#include <asm/io.h>
  11#include <dm.h>
  12#include <asm/arch/s400_api.h>
  13#include <misc.h>
  14
  15DECLARE_GLOBAL_DATA_PTR;
  16
  17int ahab_release_rdc(u8 core_id, bool xrdc, u32 *response)
  18{
  19        struct udevice *dev = gd->arch.s400_dev;
  20        int size = sizeof(struct imx8ulp_s400_msg);
  21        struct imx8ulp_s400_msg msg;
  22        int ret;
  23
  24        if (!dev) {
  25                printf("s400 dev is not initialized\n");
  26                return -ENODEV;
  27        }
  28
  29        msg.version = AHAB_VERSION;
  30        msg.tag = AHAB_CMD_TAG;
  31        msg.size = 2;
  32        msg.command = AHAB_RELEASE_RDC_REQ_CID;
  33        if (xrdc)
  34                msg.data[0] = (0x78 << 8) | core_id;
  35        else
  36                msg.data[0] = (0x74 << 8) | core_id;
  37
  38        ret = misc_call(dev, false, &msg, size, &msg, size);
  39        if (ret)
  40                printf("Error: %s: ret %d, core id %u, response 0x%x\n",
  41                       __func__, ret, core_id, msg.data[0]);
  42
  43        if (response)
  44                *response = msg.data[0];
  45
  46        return ret;
  47}
  48
  49int ahab_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
  50{
  51        struct udevice *dev = gd->arch.s400_dev;
  52        int size = sizeof(struct imx8ulp_s400_msg);
  53        struct imx8ulp_s400_msg msg;
  54        int ret;
  55
  56        if (!dev) {
  57                printf("s400 dev is not initialized\n");
  58                return -ENODEV;
  59        }
  60
  61        msg.version = AHAB_VERSION;
  62        msg.tag = AHAB_CMD_TAG;
  63        msg.size = 3;
  64        msg.command = AHAB_AUTH_OEM_CTNR_CID;
  65        msg.data[0] = upper_32_bits(ctnr_addr);
  66        msg.data[1] = lower_32_bits(ctnr_addr);
  67
  68        ret = misc_call(dev, false, &msg, size, &msg, size);
  69        if (ret)
  70                printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n",
  71                       __func__, ret, ctnr_addr, msg.data[0]);
  72
  73        if (response)
  74                *response = msg.data[0];
  75
  76        return ret;
  77}
  78
  79int ahab_release_container(u32 *response)
  80{
  81        struct udevice *dev = gd->arch.s400_dev;
  82        int size = sizeof(struct imx8ulp_s400_msg);
  83        struct imx8ulp_s400_msg msg;
  84        int ret;
  85
  86        if (!dev) {
  87                printf("s400 dev is not initialized\n");
  88                return -ENODEV;
  89        }
  90
  91        msg.version = AHAB_VERSION;
  92        msg.tag = AHAB_CMD_TAG;
  93        msg.size = 1;
  94        msg.command = AHAB_RELEASE_CTNR_CID;
  95
  96        ret = misc_call(dev, false, &msg, size, &msg, size);
  97        if (ret)
  98                printf("Error: %s: ret %d, response 0x%x\n",
  99                       __func__, ret, msg.data[0]);
 100
 101        if (response)
 102                *response = msg.data[0];
 103
 104        return ret;
 105}
 106
 107int ahab_verify_image(u32 img_id, u32 *response)
 108{
 109        struct udevice *dev = gd->arch.s400_dev;
 110        int size = sizeof(struct imx8ulp_s400_msg);
 111        struct imx8ulp_s400_msg msg;
 112        int ret;
 113
 114        if (!dev) {
 115                printf("s400 dev is not initialized\n");
 116                return -ENODEV;
 117        }
 118
 119        msg.version = AHAB_VERSION;
 120        msg.tag = AHAB_CMD_TAG;
 121        msg.size = 2;
 122        msg.command = AHAB_VERIFY_IMG_CID;
 123        msg.data[0] = 1 << img_id;
 124
 125        ret = misc_call(dev, false, &msg, size, &msg, size);
 126        if (ret)
 127                printf("Error: %s: ret %d, img_id %u, response 0x%x\n",
 128                       __func__, ret, img_id, msg.data[0]);
 129
 130        if (response)
 131                *response = msg.data[0];
 132
 133        return ret;
 134}
 135
 136int ahab_forward_lifecycle(u16 life_cycle, u32 *response)
 137{
 138        struct udevice *dev = gd->arch.s400_dev;
 139        int size = sizeof(struct imx8ulp_s400_msg);
 140        struct imx8ulp_s400_msg msg;
 141        int ret;
 142
 143        if (!dev) {
 144                printf("s400 dev is not initialized\n");
 145                return -ENODEV;
 146        }
 147
 148        msg.version = AHAB_VERSION;
 149        msg.tag = AHAB_CMD_TAG;
 150        msg.size = 2;
 151        msg.command = AHAB_FWD_LIFECYCLE_UP_REQ_CID;
 152        msg.data[0] = life_cycle;
 153
 154        ret = misc_call(dev, false, &msg, size, &msg, size);
 155        if (ret)
 156                printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n",
 157                       __func__, ret, life_cycle, msg.data[0]);
 158
 159        if (response)
 160                *response = msg.data[0];
 161
 162        return ret;
 163}
 164
 165int ahab_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
 166{
 167        struct udevice *dev = gd->arch.s400_dev;
 168        int size = sizeof(struct imx8ulp_s400_msg);
 169        struct imx8ulp_s400_msg msg;
 170        int ret;
 171
 172        if (!dev) {
 173                printf("s400 dev is not initialized\n");
 174                return -ENODEV;
 175        }
 176
 177        if (!fuse_words) {
 178                printf("Invalid parameters for fuse read\n");
 179                return -EINVAL;
 180        }
 181
 182        if ((fuse_id != 1 && fuse_num != 1) ||
 183            (fuse_id == 1 && fuse_num != 4)) {
 184                printf("Invalid fuse number parameter\n");
 185                return -EINVAL;
 186        }
 187
 188        msg.version = AHAB_VERSION;
 189        msg.tag = AHAB_CMD_TAG;
 190        msg.size = 2;
 191        msg.command = AHAB_READ_FUSE_REQ_CID;
 192        msg.data[0] = fuse_id;
 193
 194        ret = misc_call(dev, false, &msg, size, &msg, size);
 195        if (ret)
 196                printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
 197                       __func__, ret, fuse_id, msg.data[0]);
 198
 199        if (response)
 200                *response = msg.data[0];
 201
 202        fuse_words[0] = msg.data[1];
 203        if (fuse_id == 1) {
 204                /* OTP_UNIQ_ID */
 205                fuse_words[1] = msg.data[2];
 206                fuse_words[2] = msg.data[3];
 207                fuse_words[3] = msg.data[4];
 208        }
 209
 210        return ret;
 211}
 212
 213int ahab_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
 214{
 215        struct udevice *dev = gd->arch.s400_dev;
 216        int size = sizeof(struct imx8ulp_s400_msg);
 217        struct imx8ulp_s400_msg msg;
 218        int ret;
 219
 220        if (!dev) {
 221                printf("s400 dev is not initialized\n");
 222                return -ENODEV;
 223        }
 224
 225        msg.version = AHAB_VERSION;
 226        msg.tag = AHAB_CMD_TAG;
 227        msg.size = 3;
 228        msg.command = AHAB_WRITE_FUSE_REQ_CID;
 229        msg.data[0] = (32 << 16) | (fuse_id << 5);
 230        if (lock)
 231                msg.data[0] |= (1 << 31);
 232
 233        msg.data[1] = fuse_val;
 234
 235        ret = misc_call(dev, false, &msg, size, &msg, size);
 236        if (ret)
 237                printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
 238                       __func__, ret, fuse_id, msg.data[0]);
 239
 240        if (response)
 241                *response = msg.data[0];
 242
 243        return ret;
 244}
 245