linuxOS_D21X/source/artinchip/test-clock/test_clock.c
2024-11-29 16:33:21 +08:00

348 lines
6.9 KiB
C

// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2023 ArtInChip Technology Co., Ltd.
* Author: senye.liang <senye.liang@artinchip.com>
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdbool.h>
#define CLOCK_VERSION "0.1"
#define DIR_CLK "/sys/kernel/debug/clk"
#define GET_PARENT 0
#define GET_ALL_INFO 1
#define GET_NAME 2
#define GET_MAJOR_INFO 3
char clk_info_type_aic[3][20] = {
"clk_rate",
"clk_enable_count",
"clk_parent"
};
static void usage(char *program)
{
printf("\n");
printf("Usage: %s [a] [-a name] [-p name] [-g name] [-v] [-h]\n", program);
printf(" -a Get all info for clocks.\n");
printf(" -f NAME Get all major info for clock with this name.\n");
printf(" -p NAME Get all parent for clock with this name.\n");
printf(" -v Display clock_test version.\n");
printf(" -h Display this help screen\n");
printf("\n");
}
static char *clk_info_get(char *path, char *filename)
{
FILE *file;
char *buffer = NULL;
char *temp = (char *)malloc(64 * sizeof(char));
sprintf(temp, "%s/%s", path, filename);
file = fopen(temp, "r");
free(temp);
temp =NULL;
if (file == NULL)
return NULL;
buffer = (char *)malloc(32 * sizeof(char));
fscanf(file, "%s\\0", buffer);
fclose(file);
return buffer;
}
char *clk_get_parent_rate(char *clk_name)
{
char *path = (char *)malloc(64 * sizeof(char));
char *parent_name = NULL;
char *parent_rate = NULL;
sprintf(path, "%s/%s", DIR_CLK, clk_name);
/*get parent clock*/
parent_name = clk_info_get(path, "clk_parent");
if (parent_name == NULL)
goto __out;
/*get parent rate*/
sprintf(path, "%s/%s", DIR_CLK, parent_name);
parent_rate = clk_info_get(path, "clk_rate");
free(parent_name);
parent_name = NULL;
__out:
free(path);
path = NULL;
return parent_rate;
}
static int clk_get_parent(char *clk_name)
{
char *path = (char *)malloc(64 * sizeof(char));
char *parent_name = NULL;
sprintf(path, "%s/%s", DIR_CLK, clk_name);
parent_name = clk_info_get(path, "clk_parent");
if (parent_name == NULL) {
printf("%s", clk_name);
goto __out;
}
clk_get_parent(parent_name);
printf(" -> %s", clk_name);
__out:
free(path);
path = NULL;
free(parent_name);
parent_name = NULL;
return 0;
}
int clk_each_file(char *clk_name)
{
char dirname[64];
DIR *dir;
struct dirent *entry;
char *buffer = NULL;
char *filename = (char *)malloc(512 * sizeof(char));
printf("\n-----\t%s\t-----\n", clk_name);
sprintf(dirname, "%s/%s", DIR_CLK, clk_name);
dir = opendir(dirname);
printf("dirname:%s\n", dirname);
if (dir == NULL) {
free(filename);
filename = NULL;
perror("Unable to open directory");
return -1;
}
/*each all files in this clock dir*/
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type != DT_REG)
continue;
buffer = clk_info_get(dirname, entry->d_name);
printf("%-20s%s", entry->d_name, buffer);
printf("\n");
};
free(filename);
filename = NULL;
free(buffer);
buffer = NULL;
closedir(dir);
return 0;
}
int clk_major_info(char *clk_name)
{
int num = sizeof(clk_info_type_aic)/sizeof(clk_info_type_aic[0]);
char *path = (char *)malloc(64 * sizeof(char));
char *parent_rate = NULL;
printf("%8s ", clk_name);
sprintf(path, "%s/%s", DIR_CLK, clk_name);
for (int i= 0; i < num; i++) {
char *buffer = clk_info_get(path, clk_info_type_aic[i]);
printf("%14s",buffer);
free(buffer);
buffer = NULL;
}
parent_rate = clk_get_parent_rate(clk_name);
printf("%16s",parent_rate);
free(parent_rate);
parent_rate = NULL;
printf("\n");
return 0;
}
int get_byname(char *name, int ch)
{
DIR *dir = opendir(DIR_CLK);
struct dirent *entry;
int ret;
if (dir == NULL) {
printf("Unable to open directory");
goto _err;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type != DT_DIR || strcmp(entry->d_name,".") == 0\
|| strcmp(entry->d_name, "..") == 0) {
continue;
}
ret = strncmp(entry->d_name, name, strlen(name));
if (ret == 0) {
switch (ch) {
case GET_PARENT:
ret = clk_get_parent(entry->d_name);
printf("\n");
if (ret < 0)
goto _err;
break;
case GET_ALL_INFO:
ret = clk_each_file(entry->d_name);
printf("\n");
if (ret < 0)
goto _err;
break;
case GET_MAJOR_INFO:
ret = clk_major_info(entry->d_name);
printf("\n");
if (ret < 0)
goto _err;
default:
break;
}
}
}
return 0;
_err:
return -1;
}
int get_all_info_task(char *clk[], int opt)
{
int i = 2;
int ret = 0;
if (clk[i]) {
while (clk[i]) {
ret = get_byname(clk[i], GET_ALL_INFO);
if (ret < 0)
goto _err;
i++;
}
printf("\n");
} else {
system("cat /sys/kernel/debug/clk/clk_summary");
}
return 0;
_err:
return -1;
}
int get_parent_task(char *clk[])
{
int i = 2;
int ret = 0;
printf("------------ get parent --------------\n");
while (clk[i]) {
get_byname(clk[i], GET_PARENT);
if (ret < 0)
goto _err;
i++;
}
printf("\n");
return 0;
_err:
return -1;
}
int get_major_info_task(char *clk[])
{
int i = 2;
int ret = 0;
printf( "---------------------------------------------------------------------\n");
printf( " clock rate enable count parent parent rate \n");
printf( "------------ ----------- -------------- ------------- -----------\n");
while (clk[i]) {
get_byname(clk[i], GET_MAJOR_INFO);
if (ret < 0)
goto _err;
i++;
}
printf("\n");
return 0;
_err:
return -1;
}
int main(int argc, char *argv[])
{
int opt;
int ret = 0;
extern int optind, opterr, optopt;
extern char *optarg;
char buffer[256];
if (access("/sys/kernel/debug/clk/", F_OK) != 0)
system("mount -t debugfs none /sys/kernel/debug/");
while ((opt = getopt(argc, argv, "a::p:f:s:vh")) != -1) {
switch (opt) {
case 'a':
ret = get_all_info_task(argv, optind);
if (ret <0)
goto _err;
exit(0);
break;
case 'p':
ret = get_parent_task(argv);
if (ret <0)
goto _err;
exit(0);
break;
case 'f':
ret = get_major_info_task(argv);
if (ret <0)
goto _err;
exit(0);
break;
case 's':
sprintf(buffer, "echo %s > /sys/kernel/debug/clk"
"/%s/clk_rate", argv[3], argv[2]);
system(buffer);
ret = get_byname(argv[2], GET_ALL_INFO);
if (ret <0)
goto _err;
exit(0);
break;
case 'v':
printf("clock_test version:0.1\n");
case 'h':
usage(argv[0]);
exit(0);
return 0;
default:
goto _err;
}
}
usage(argv[0]);
return 0;
_err:
return -1;
}