📄 ss.c
字号:
/************************************************************************
* Include files
************************************************************************/
#include <sysdefs.h>
#include <shell_api.h>
#include <env_api.h>
#include <sysdev.h>
#include <io_api.h>
#include <ctype.h>
#include <stdio.h>
#include <sysenv_api.h>
#include <sys_api.h>
#include <string.h>
#include <pb1000.h>
#include "shell.h"
/************************************************************************
* Definitions
************************************************************************/
#define ACTION_READ 0x01
#define ACTION_UPDATE 0x04
/************************************************************************
* Public variables
************************************************************************/
/************************************************************************
* Static variables
************************************************************************/
/************************************************************************
* Static function prototypes
************************************************************************/
static void
re_init_port_ss(
UINT32 port );
static UINT32
get_options(
UINT32 argc,
char **argv,
UINT8 *action,
UINT32 *ipaddr,
UINT32 *size );
/************************************************************************
* Implementation : Static functions
************************************************************************/
/************************************************************************
* re_init_port_ss
*
* This is almost identical to the re_init_port() in shell/stty.c.
************************************************************************/
static void
re_init_port_ss(
UINT32 port )
{
/* Reinitialise device in order for the settings
* to take effect.
*/
UINT32 major, minor;
SYSCON_read( (port == PORT_TTY0) ?
SYSCON_COM_TTY0_MAJOR : SYSCON_COM_TTY1_MAJOR,
(void *)(&major),
sizeof(UINT32) );
SYSCON_read( (port == PORT_TTY0) ?
SYSCON_COM_TTY0_MINOR : SYSCON_COM_TTY1_MINOR,
(void *)(&minor),
sizeof(UINT32) );
sys_wait_ms( 100 );
IO_init( major, minor, (void *)&port );
}
/************************************************************************
* ss
************************************************************************/
static MON_FUNC(ss)
{
/* Options */
UINT8 action;
UINT32 pll_mult, sysbusdiv;
UINT32 sysbusdiv_old;
UINT32 brgdiv, cpu_speed, cpu_test;
UINT32 rc;
rc = get_options( argc, argv, &action, &pll_mult, &sysbusdiv );
if(action & ACTION_READ)
{
/* just tell the user what the current settings are */
SYSCON_read(SYSCON_BOARD_CPU_CLOCK_FREQ_ID,
&cpu_speed, sizeof(cpu_speed));
printf("CPU_PLL_MULT = %u, CPU = %u kHz, SysBus Divider = %u\n",
pll_mult, cpu_speed/1000, sysbusdiv);
return rc;
}
if(!(pll_mult >= 0 && pll_mult < 64))
{
printf("Invalid PLL Multiplier value, %d, must be between 0 and 64\n", pll_mult);
return rc;
}
if(!(sysbusdiv >= 2 && sysbusdiv <=5))
{
printf("Invalid Bus Divider value, %d, must be between 2 and 5\n", sysbusdiv);
return rc;
}
switch( pll_mult )
{
case 0: cpu_speed = 64 * AU1000_CPUOSC_FREQ; break;
case 1:
case 2: cpu_speed = 3 * AU1000_CPUOSC_FREQ; break;
case 5: cpu_speed = 6 * AU1000_CPUOSC_FREQ; break;
default: cpu_speed = pll_mult * AU1000_CPUOSC_FREQ; break;
}
printf("CPU_PLL_MULT -> %u, CPU -> %u kHz, SysBus Divider -> %u\n",
pll_mult, cpu_speed/1000, sysbusdiv);
/* update stored CPU freq and SD values */
SYSCON_write( SYSCON_BOARD_CPU_CLOCK_FREQ_ID,
&cpu_speed, sizeof(cpu_speed));
SYSCON_write( SYSCON_BOARD_BUS_CLOCK_FREQ_ID,
&sysbusdiv, sizeof(sysbusdiv));
/* re-init UARTs to divisors appropriate to new core freq */
re_init_port_ss(PORT_TTY1);
re_init_port_ss(PORT_TTY0);
sys_wait_ms(500); /* short delay to allow printf to complete */
/* update CPU PLL multiplier and SD (_after_ printf's go out) */
REG32(AU1000_SYS_CPUPLL) = pll_mult;
REG32(AU1000_SYS_POWERCTRL) = sysbusdiv - 2;
return rc;
}
/************************************************************************
* get_options
************************************************************************/
static UINT32
get_options(
UINT32 argc,
char **argv,
UINT8 *action,
UINT32 *pll_mult,
UINT32 *sysbusdiv )
{
UINT32 i;
/* Setup defaults */
*action = ACTION_UPDATE;
/* Check for options (not allowed) */
for( i=0; i<argc; i++ )
{
if( *argv[i] == '-' )
{
shell_error_data = argv[i];
return SHELL_ERROR_OPTION;
}
}
if(argc > 2)
{
*sysbusdiv = (int) strtol(argv[2], (char **) 0, 10);
} else
/* no SD specified on command line, retrieve current value */
SYSCON_read(SYSCON_BOARD_BUS_CLOCK_FREQ_ID,
sysbusdiv, sizeof(UINT32));
if(argc > 1)
*pll_mult = (int) strtol(argv[1], (char **) 0, 10);
else
{
*action = ACTION_READ;
*pll_mult = REG32(AU1000_SYS_CPUPLL) & 0x03f;
}
return OK;
}
/* Command definition for help */
static t_cmd cmd_def =
{
"ss",
ss,
"ss PLL_MULTIPLIER [<SYSTEM_BUS_DIVIDER>]",
"Set CPU PLL multiplier and optionally change system bus divider.\n"
"\n"
"Supported values of PLL_MULTIPLIER: 16-46 only.\n"
"Valid values of SYSTEM_BUS_DIVIDER: 2, 3, or 4 only.\n"
"\n"
"If CPUOSC=12 MHz, PLL_MULTIPLIER=33 produces CPU_CORE_FREQ=396.000 MHz.\n",
NULL,
0,
FALSE
};
/************************************************************************
* Implementation : Public functions
************************************************************************/
/************************************************************************
*
* shell_ping_init
* Description :
* -------------
*
* Initialise command
*
* Return values :
* ---------------
*
* void
*
************************************************************************/
t_cmd *
shell_ss_init( void )
{
return &cmd_def;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -