12e192b24SSimon Glass /*
22e192b24SSimon Glass * (C) Copyright 2000
32e192b24SSimon Glass * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
42e192b24SSimon Glass *
52e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+
62e192b24SSimon Glass */
72e192b24SSimon Glass
82e192b24SSimon Glass /*
92e192b24SSimon Glass * Cache support: switch on or off, get status
102e192b24SSimon Glass */
112e192b24SSimon Glass #include <common.h>
122e192b24SSimon Glass #include <command.h>
132e192b24SSimon Glass #include <linux/compiler.h>
142e192b24SSimon Glass
152e192b24SSimon Glass static int parse_argv(const char *);
162e192b24SSimon Glass
invalidate_icache_all(void)172e192b24SSimon Glass void __weak invalidate_icache_all(void)
182e192b24SSimon Glass {
192e192b24SSimon Glass /* please define arch specific invalidate_icache_all */
202e192b24SSimon Glass puts("No arch specific invalidate_icache_all available!\n");
212e192b24SSimon Glass }
222e192b24SSimon Glass
do_icache(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])232e192b24SSimon Glass static int do_icache(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
242e192b24SSimon Glass {
252e192b24SSimon Glass switch (argc) {
262e192b24SSimon Glass case 2: /* on / off */
272e192b24SSimon Glass switch (parse_argv(argv[1])) {
282e192b24SSimon Glass case 0:
292e192b24SSimon Glass icache_disable();
302e192b24SSimon Glass break;
312e192b24SSimon Glass case 1:
322e192b24SSimon Glass icache_enable();
332e192b24SSimon Glass break;
342e192b24SSimon Glass case 2:
352e192b24SSimon Glass invalidate_icache_all();
362e192b24SSimon Glass break;
372e192b24SSimon Glass }
382e192b24SSimon Glass break;
392e192b24SSimon Glass case 1: /* get status */
402e192b24SSimon Glass printf("Instruction Cache is %s\n",
412e192b24SSimon Glass icache_status() ? "ON" : "OFF");
422e192b24SSimon Glass return 0;
432e192b24SSimon Glass default:
442e192b24SSimon Glass return CMD_RET_USAGE;
452e192b24SSimon Glass }
462e192b24SSimon Glass return 0;
472e192b24SSimon Glass }
482e192b24SSimon Glass
flush_dcache_all(void)492e192b24SSimon Glass void __weak flush_dcache_all(void)
502e192b24SSimon Glass {
512e192b24SSimon Glass puts("No arch specific flush_dcache_all available!\n");
522e192b24SSimon Glass /* please define arch specific flush_dcache_all */
532e192b24SSimon Glass }
542e192b24SSimon Glass
do_dcache(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])552e192b24SSimon Glass static int do_dcache(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
562e192b24SSimon Glass {
57*b46a81a1SJoseph Chen ulong start, size;
58*b46a81a1SJoseph Chen
592e192b24SSimon Glass switch (argc) {
60*b46a81a1SJoseph Chen case 4:
61*b46a81a1SJoseph Chen start = simple_strtoul(argv[2], NULL, 16);
62*b46a81a1SJoseph Chen size = simple_strtoul(argv[3], NULL, 16);
63*b46a81a1SJoseph Chen
64*b46a81a1SJoseph Chen switch (parse_argv(argv[1])) {
65*b46a81a1SJoseph Chen case 2:
66*b46a81a1SJoseph Chen printf("flush dcache: 0x%08lx - 0x%08lx\n", start, start + size);
67*b46a81a1SJoseph Chen flush_dcache_range(start, start + size);
68*b46a81a1SJoseph Chen break;
69*b46a81a1SJoseph Chen case 3:
70*b46a81a1SJoseph Chen printf("invalidate dcache: 0x%08lx - 0x%08lx\n", start, start + size);
71*b46a81a1SJoseph Chen invalidate_dcache_range(start, start + size);
72*b46a81a1SJoseph Chen break;
73*b46a81a1SJoseph Chen }
74*b46a81a1SJoseph Chen break;
752e192b24SSimon Glass case 2: /* on / off */
762e192b24SSimon Glass switch (parse_argv(argv[1])) {
772e192b24SSimon Glass case 0:
782e192b24SSimon Glass dcache_disable();
792e192b24SSimon Glass break;
802e192b24SSimon Glass case 1:
812e192b24SSimon Glass dcache_enable();
822e192b24SSimon Glass break;
832e192b24SSimon Glass case 2:
842e192b24SSimon Glass flush_dcache_all();
852e192b24SSimon Glass break;
86*b46a81a1SJoseph Chen case 3:
87*b46a81a1SJoseph Chen printf("error: dcache invalidate require [start] [size]\n");
88*b46a81a1SJoseph Chen break;
892e192b24SSimon Glass }
902e192b24SSimon Glass break;
912e192b24SSimon Glass case 1: /* get status */
922e192b24SSimon Glass printf("Data (writethrough) Cache is %s\n",
932e192b24SSimon Glass dcache_status() ? "ON" : "OFF");
942e192b24SSimon Glass return 0;
952e192b24SSimon Glass default:
962e192b24SSimon Glass return CMD_RET_USAGE;
972e192b24SSimon Glass }
982e192b24SSimon Glass return 0;
992e192b24SSimon Glass }
1002e192b24SSimon Glass
parse_argv(const char * s)1012e192b24SSimon Glass static int parse_argv(const char *s)
1022e192b24SSimon Glass {
103*b46a81a1SJoseph Chen if (strcmp(s, "invalidate") == 0)
104*b46a81a1SJoseph Chen return 3;
105*b46a81a1SJoseph Chen else if (strcmp(s, "flush") == 0)
1062e192b24SSimon Glass return 2;
1072e192b24SSimon Glass else if (strcmp(s, "on") == 0)
1082e192b24SSimon Glass return 1;
1092e192b24SSimon Glass else if (strcmp(s, "off") == 0)
1102e192b24SSimon Glass return 0;
1112e192b24SSimon Glass
1122e192b24SSimon Glass return -1;
1132e192b24SSimon Glass }
1142e192b24SSimon Glass
1152e192b24SSimon Glass
1162e192b24SSimon Glass U_BOOT_CMD(
1172e192b24SSimon Glass icache, 2, 1, do_icache,
1182e192b24SSimon Glass "enable or disable instruction cache",
1192e192b24SSimon Glass "[on, off, flush]\n"
1202e192b24SSimon Glass " - enable, disable, or flush instruction cache"
1212e192b24SSimon Glass );
1222e192b24SSimon Glass
1232e192b24SSimon Glass U_BOOT_CMD(
124*b46a81a1SJoseph Chen dcache, 4, 1, do_dcache,
1252e192b24SSimon Glass "enable or disable data cache",
126*b46a81a1SJoseph Chen "[on, off, flush, invalidate] [start] [size]\n"
1272e192b24SSimon Glass " - enable, disable, or flush data (writethrough) cache"
1282e192b24SSimon Glass );
129