uboot/cmd/remoteproc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2015
   4 * Texas Instruments Incorporated - http://www.ti.com/
   5 */
   6#include <common.h>
   7#include <command.h>
   8#include <dm.h>
   9#include <errno.h>
  10#include <malloc.h>
  11#include <remoteproc.h>
  12
  13/**
  14 * print_remoteproc_list() - print all the remote processor devices
  15 *
  16 * Return: 0 if no error, else returns appropriate error value.
  17 */
  18static int print_remoteproc_list(void)
  19{
  20        struct udevice *dev;
  21        struct uclass *uc;
  22        int ret;
  23        char *type;
  24
  25        ret = uclass_get(UCLASS_REMOTEPROC, &uc);
  26        if (ret) {
  27                printf("Cannot find Remote processor class\n");
  28                return ret;
  29        }
  30
  31        uclass_foreach_dev(dev, uc) {
  32                struct dm_rproc_uclass_pdata *uc_pdata;
  33                const struct dm_rproc_ops *ops = rproc_get_ops(dev);
  34
  35                uc_pdata = dev_get_uclass_plat(dev);
  36
  37                /* Do not print if rproc is not probed */
  38                if (!(dev_get_flags(dev) & DM_FLAG_ACTIVATED))
  39                        continue;
  40
  41                switch (uc_pdata->mem_type) {
  42                case RPROC_INTERNAL_MEMORY_MAPPED:
  43                        type = "internal memory mapped";
  44                        break;
  45                default:
  46                        type = "unknown";
  47                        break;
  48                }
  49                printf("%d - Name:'%s' type:'%s' supports: %s%s%s%s%s%s\n",
  50                       dev_seq(dev),
  51                       uc_pdata->name,
  52                       type,
  53                       ops->load ? "load " : "",
  54                       ops->start ? "start " : "",
  55                       ops->stop ? "stop " : "",
  56                       ops->reset ? "reset " : "",
  57                       ops->is_running ? "is_running " : "",
  58                       ops->ping ? "ping " : "");
  59        }
  60        return 0;
  61}
  62
  63/**
  64 * do_rproc_init() - do basic initialization
  65 * @cmdtp:      unused
  66 * @flag:       unused
  67 * @argc:       unused
  68 * @argv:       unused
  69 *
  70 * Return: 0 if no error, else returns appropriate error value.
  71 */
  72static int do_rproc_init(struct cmd_tbl *cmdtp, int flag, int argc,
  73                         char *const argv[])
  74{
  75        int id;
  76
  77        if (rproc_is_initialized()) {
  78                printf("\tRemote Processors are already initialized\n");
  79                return CMD_RET_FAILURE;
  80        }
  81
  82        if (argc == 1) {
  83                if (!rproc_init())
  84                        return 0;
  85                printf("Few Remote Processors failed to be initialized\n");
  86        } else if (argc == 2) {
  87                id = (int)dectoul(argv[1], NULL);
  88                if (!rproc_dev_init(id))
  89                        return 0;
  90                printf("Remote Processor %d failed to be initialized\n", id);
  91        }
  92
  93        return CMD_RET_FAILURE;
  94}
  95
  96/**
  97 * do_remoteproc_list() - print list of remote proc devices.
  98 * @cmdtp:      unused
  99 * @flag:       unused
 100 * @argc:       unused
 101 * @argv:       unused
 102 *
 103 * Return: 0 if no error, else returns appropriate error value.
 104 */
 105static int do_remoteproc_list(struct cmd_tbl *cmdtp, int flag, int argc,
 106                              char *const argv[])
 107{
 108        if (print_remoteproc_list())
 109                return CMD_RET_FAILURE;
 110
 111        return 0;
 112}
 113
 114/**
 115 * do_remoteproc_load() - Load a remote processor with binary image
 116 * @cmdtp:      unused
 117 * @flag:       unused
 118 * @argc:       argument count for the load function
 119 * @argv:       arguments for the load function
 120 *
 121 * Return: 0 if no error, else returns appropriate error value.
 122 */
 123static int do_remoteproc_load(struct cmd_tbl *cmdtp, int flag, int argc,
 124                              char *const argv[])
 125{
 126        ulong addr, size;
 127        int id, ret;
 128
 129        if (argc != 4)
 130                return CMD_RET_USAGE;
 131
 132        id = (int)dectoul(argv[1], NULL);
 133        addr = hextoul(argv[2], NULL);
 134
 135        size = hextoul(argv[3], NULL);
 136
 137        if (!size) {
 138                printf("\t Expect some size??\n");
 139                return CMD_RET_USAGE;
 140        }
 141
 142        ret = rproc_load(id, addr, size);
 143        printf("Load Remote Processor %d with data@addr=0x%08lx %lu bytes:%s\n",
 144               id, addr, size, ret ? " Failed!" : " Success!");
 145
 146        return ret ? CMD_RET_FAILURE : 0;
 147}
 148
 149/**
 150 * do_remoteproc_wrapper() - wrapper for various  rproc commands
 151 * @cmdtp:      unused
 152 * @flag:       unused
 153 * @argc:       argument count for the rproc command
 154 * @argv:       arguments for the rproc command
 155 *
 156 * Most of the commands just take id as a parameter andinvoke various
 157 * helper routines in remote processor core. by using a set of
 158 * common checks, we can reduce the amount of code used for this.
 159 *
 160 * Return: 0 if no error, else returns appropriate error value.
 161 */
 162static int do_remoteproc_wrapper(struct cmd_tbl *cmdtp, int flag, int argc,
 163                                 char *const argv[])
 164{
 165        int id, ret = CMD_RET_USAGE;
 166
 167        if (argc != 2)
 168                return CMD_RET_USAGE;
 169
 170        id = (int)dectoul(argv[1], NULL);
 171
 172        if (!strcmp(argv[0], "start")) {
 173                ret = rproc_start(id);
 174        } else if (!strcmp(argv[0], "stop")) {
 175                ret = rproc_stop(id);
 176        } else if (!strcmp(argv[0], "reset")) {
 177                ret = rproc_reset(id);
 178        } else if (!strcmp(argv[0], "is_running")) {
 179                ret = rproc_is_running(id);
 180                if (!ret) {
 181                        printf("Remote processor is Running\n");
 182                } else if (ret == 1) {
 183                        printf("Remote processor is NOT Running\n");
 184                        ret = 0;
 185                }
 186                /* Else error.. */
 187        } else if (!strcmp(argv[0], "ping")) {
 188                ret = rproc_ping(id);
 189                if (!ret) {
 190                        printf("Remote processor responds 'Pong'\n");
 191                } else if (ret == 1) {
 192                        printf("No response from Remote processor\n");
 193                        ret = 0;
 194                }
 195                /* Else error.. */
 196        }
 197
 198        if (ret < 0)
 199                printf("Operation Failed with error (%d)\n", ret);
 200
 201        return ret ? CMD_RET_FAILURE : 0;
 202}
 203
 204static struct cmd_tbl cmd_remoteproc_sub[] = {
 205        U_BOOT_CMD_MKENT(init, 1, 1, do_rproc_init,
 206                         "Enumerate and initialize the remote processor(s)",
 207                         "id - ID of the remote processor\n"
 208                         "If id is not passed, initialize all the remote processors"),
 209        U_BOOT_CMD_MKENT(list, 0, 1, do_remoteproc_list,
 210                         "list remote processors", ""),
 211        U_BOOT_CMD_MKENT(load, 5, 1, do_remoteproc_load,
 212                         "Load remote processor with provided image",
 213                         "<id> [addr] [size]\n"
 214                         "- id: ID of the remote processor(see 'list' cmd)\n"
 215                         "- addr: Address in memory of the image to loadup\n"
 216                         "- size: Size of the image to loadup\n"),
 217        U_BOOT_CMD_MKENT(start, 1, 1, do_remoteproc_wrapper,
 218                         "Start remote processor",
 219                         "id - ID of the remote processor (see 'list' cmd)\n"),
 220        U_BOOT_CMD_MKENT(stop, 1, 1, do_remoteproc_wrapper,
 221                         "Stop remote processor",
 222                         "id - ID of the remote processor (see 'list' cmd)\n"),
 223        U_BOOT_CMD_MKENT(reset, 1, 1, do_remoteproc_wrapper,
 224                         "Reset remote processor",
 225                         "id - ID of the remote processor (see 'list' cmd)\n"),
 226        U_BOOT_CMD_MKENT(is_running, 1, 1, do_remoteproc_wrapper,
 227                         "Check to see if remote processor is running\n",
 228                         "id - ID of the remote processor (see 'list' cmd)\n"),
 229        U_BOOT_CMD_MKENT(ping, 1, 1, do_remoteproc_wrapper,
 230                         "Ping to communicate with remote processor\n",
 231                         "id - ID of the remote processor (see 'list' cmd)\n"),
 232};
 233
 234/**
 235 * do_remoteproc() - (replace: short desc)
 236 * @cmdtp:      unused
 237 * @flag:       unused
 238 * @argc:       argument count
 239 * @argv:       argument list
 240 *
 241 * parses up the command table to invoke the correct command.
 242 *
 243 * Return: 0 if no error, else returns appropriate error value.
 244 */
 245static int do_remoteproc(struct cmd_tbl *cmdtp, int flag, int argc,
 246                         char *const argv[])
 247{
 248        struct cmd_tbl *c = NULL;
 249
 250        /* Strip off leading 'rproc' command argument */
 251        argc--;
 252        argv++;
 253
 254        if (argc)
 255                c = find_cmd_tbl(argv[0], cmd_remoteproc_sub,
 256                                 ARRAY_SIZE(cmd_remoteproc_sub));
 257        if (c)
 258                return c->cmd(cmdtp, flag, argc, argv);
 259
 260        return CMD_RET_USAGE;
 261}
 262
 263U_BOOT_CMD(rproc, 5, 1, do_remoteproc,
 264           "Control operation of remote processors in an SoC",
 265           " [init|list|load|start|stop|reset|is_running|ping]\n"
 266           "\t\t Where:\n"
 267           "\t\t[addr] is a memory address\n"
 268           "\t\t<id> is a numerical identifier for the remote processor\n"
 269           "\t\t     provided by 'list' command.\n"
 270           "\t\tNote: Remote processors must be initalized prior to usage\n"
 271           "\t\tNote: Services are dependent on the driver capability\n"
 272           "\t\t      'list' command shows the capability of each device\n"
 273           "\n\tSubcommands:\n"
 274           "\tinit <id> - Enumerate and initalize the remote processor.\n"
 275           "\t            if id is not passed, initialize all the remote prcessors\n"
 276           "\tlist   - list available remote processors\n"
 277           "\tload <id> [addr] [size]- Load the remote processor with binary\n"
 278           "\t            image stored at address [addr] in memory\n"
 279           "\tstart <id>        - Start the remote processor(must be loaded)\n"
 280           "\tstop <id> - Stop the remote processor\n"
 281           "\treset <id>        - Reset the remote processor\n"
 282           "\tis_running <id> - Reports if the remote processor is running\n"
 283           "\tping <id> - Ping the remote processor for communication\n");
 284