1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * keystone2: commands for clocks
4  *
5  * (C) Copyright 2012-2014
6  *     Texas Instruments Incorporated, <www.ti.com>
7  */
8 
9 #include <common.h>
10 #include <command.h>
11 #include <asm/arch/hardware.h>
12 #include <asm/arch/clock.h>
13 #include <asm/arch/psc_defs.h>
14 
15 struct pll_init_data cmd_pll_data = {
16 	.pll = MAIN_PLL,
17 	.pll_m = 16,
18 	.pll_d = 1,
19 	.pll_od = 2,
20 };
21 
22 int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
23 {
24 	if (argc != 5)
25 		goto pll_cmd_usage;
26 
27 	if (strncmp(argv[1], "pa", 2) == 0)
28 		cmd_pll_data.pll = PASS_PLL;
29 #ifndef CONFIG_SOC_K2E
30 	else if (strncmp(argv[1], "arm", 3) == 0)
31 		cmd_pll_data.pll = TETRIS_PLL;
32 #endif
33 #ifdef CONFIG_SOC_K2HK
34 	else if (strncmp(argv[1], "ddr3a", 5) == 0)
35 		cmd_pll_data.pll = DDR3A_PLL;
36 	else if (strncmp(argv[1], "ddr3b", 5) == 0)
37 		cmd_pll_data.pll = DDR3B_PLL;
38 #else
39 	else if (strncmp(argv[1], "ddr3", 4) == 0)
40 		cmd_pll_data.pll = DDR3_PLL;
41 #endif
42 	else
43 		goto pll_cmd_usage;
44 
45 	cmd_pll_data.pll_m   = simple_strtoul(argv[2], NULL, 10);
46 	cmd_pll_data.pll_d   = simple_strtoul(argv[3], NULL, 10);
47 	cmd_pll_data.pll_od  = simple_strtoul(argv[4], NULL, 10);
48 
49 	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
50 	       cmd_pll_data.pll, cmd_pll_data.pll_m,
51 	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
52 	init_pll(&cmd_pll_data);
53 
54 	return 0;
55 
56 pll_cmd_usage:
57 	return cmd_usage(cmdtp);
58 }
59 
60 U_BOOT_CMD(
61 	pllset, 5,      0,      do_pll_cmd,
62 	"set pll multiplier and pre divider",
63 	PLLSET_CMD_LIST " <mult> <div> <OD>\n"
64 );
65 
66 int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
67 {
68 	unsigned int clk;
69 	unsigned long freq;
70 
71 	if (argc != 2)
72 		goto getclk_cmd_usage;
73 
74 	clk = simple_strtoul(argv[1], NULL, 10);
75 
76 	freq = ks_clk_get_rate(clk);
77 	if (freq)
78 		printf("clock index [%d] - frequency %lu\n", clk, freq);
79 	else
80 		printf("clock index [%d] Not available\n", clk);
81 	return 0;
82 
83 getclk_cmd_usage:
84 	return cmd_usage(cmdtp);
85 }
86 
87 U_BOOT_CMD(
88 	getclk,	2,	0,	do_getclk_cmd,
89 	"get clock rate",
90 	"<clk index>\n"
91 	"The indexes for clocks:\n"
92 	CLOCK_INDEXES_LIST
93 );
94 
95 int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
96 {
97 	int	psc_module;
98 	int	res;
99 
100 	if (argc != 3)
101 		goto psc_cmd_usage;
102 
103 	psc_module = simple_strtoul(argv[1], NULL, 10);
104 	if (strcmp(argv[2], "en") == 0) {
105 		res = psc_enable_module(psc_module);
106 		printf("psc_enable_module(%d) - %s\n", psc_module,
107 		       (res) ? "ERROR" : "OK");
108 		return 0;
109 	}
110 
111 	if (strcmp(argv[2], "di") == 0) {
112 		res = psc_disable_module(psc_module);
113 		printf("psc_disable_module(%d) - %s\n", psc_module,
114 		       (res) ? "ERROR" : "OK");
115 		return 0;
116 	}
117 
118 	if (strcmp(argv[2], "domain") == 0) {
119 		res = psc_disable_domain(psc_module);
120 		printf("psc_disable_domain(%d) - %s\n", psc_module,
121 		       (res) ? "ERROR" : "OK");
122 		return 0;
123 	}
124 
125 psc_cmd_usage:
126 	return cmd_usage(cmdtp);
127 }
128 
129 U_BOOT_CMD(
130 	psc,	3,	0,	do_psc_cmd,
131 	"<enable/disable psc module os disable domain>",
132 	"<mod/domain index> <en|di|domain>\n"
133 	"Intended to control Power and Sleep Controller (PSC) domains and\n"
134 	"modules. The module or domain index exectly corresponds to ones\n"
135 	"listed in official TRM. For instance, to enable MSMC RAM clock\n"
136 	"domain use command: psc 14 en.\n"
137 );
138