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 
do_pll_cmd(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])22 int do_pll_cmd(struct cmd_tbl *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 
do_getclk_cmd(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])66 int do_getclk_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
67 		  char *const argv[])
68 {
69 	unsigned int clk;
70 	unsigned long freq;
71 
72 	if (argc != 2)
73 		goto getclk_cmd_usage;
74 
75 	clk = simple_strtoul(argv[1], NULL, 10);
76 
77 	freq = ks_clk_get_rate(clk);
78 	if (freq)
79 		printf("clock index [%d] - frequency %lu\n", clk, freq);
80 	else
81 		printf("clock index [%d] Not available\n", clk);
82 	return 0;
83 
84 getclk_cmd_usage:
85 	return cmd_usage(cmdtp);
86 }
87 
88 U_BOOT_CMD(
89 	getclk,	2,	0,	do_getclk_cmd,
90 	"get clock rate",
91 	"<clk index>\n"
92 	"The indexes for clocks:\n"
93 	CLOCK_INDEXES_LIST
94 );
95 
do_psc_cmd(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])96 int do_psc_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
97 {
98 	int	psc_module;
99 	int	res;
100 
101 	if (argc != 3)
102 		goto psc_cmd_usage;
103 
104 	psc_module = simple_strtoul(argv[1], NULL, 10);
105 	if (strcmp(argv[2], "en") == 0) {
106 		res = psc_enable_module(psc_module);
107 		printf("psc_enable_module(%d) - %s\n", psc_module,
108 		       (res) ? "ERROR" : "OK");
109 		return 0;
110 	}
111 
112 	if (strcmp(argv[2], "di") == 0) {
113 		res = psc_disable_module(psc_module);
114 		printf("psc_disable_module(%d) - %s\n", psc_module,
115 		       (res) ? "ERROR" : "OK");
116 		return 0;
117 	}
118 
119 	if (strcmp(argv[2], "domain") == 0) {
120 		res = psc_disable_domain(psc_module);
121 		printf("psc_disable_domain(%d) - %s\n", psc_module,
122 		       (res) ? "ERROR" : "OK");
123 		return 0;
124 	}
125 
126 psc_cmd_usage:
127 	return cmd_usage(cmdtp);
128 }
129 
130 U_BOOT_CMD(
131 	psc,	3,	0,	do_psc_cmd,
132 	"<enable/disable psc module os disable domain>",
133 	"<mod/domain index> <en|di|domain>\n"
134 	"Intended to control Power and Sleep Controller (PSC) domains and\n"
135 	"modules. The module or domain index exectly corresponds to ones\n"
136 	"listed in official TRM. For instance, to enable MSMC RAM clock\n"
137 	"domain use command: psc 14 en.\n"
138 );
139