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