/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2021. All rights reserved. * Description: spread iapi api */ #include #include /* file operation interface */ #include #include #include #include #include /* terminate interface */ #include #include #include #include "securec.h" #include "soc_log.h" #include "drv_ioctl_spread.h" #undef LOG_MODULE_ID #define LOG_MODULE_ID SOC_ID_SPREAD #define MAX_BOOTARGS_LEN 1024 static td_s32 get_bootargs(td_u8 *bootargs, td_u16 length) { FILE *pf = NULL; if (bootargs == NULL) { soc_log_err("Pointer is null.\n"); return -1; } pf = fopen("/proc/cmdline", "r"); if (pf == NULL) { soc_log_err("Failed to open '/proc/cmdline'.\n"); return -1; } if (!fgets((td_char*)bootargs, length, pf)) { soc_log_err("Failed to fgets string.\n"); (td_void)fclose(pf); return -1; } (td_void)fclose(pf); return 0; } static td_s32 ext_spread_open(td_void) { td_s32 spread_fd; spread_fd = open("/dev/soc_spread", O_RDWR); return spread_fd; } static td_s32 ext_ss_get_emmc_type(td_void) { td_char *ret = NULL; td_char *bootargs = NULL; errno_t err_ret; bootargs = malloc(MAX_BOOTARGS_LEN); if (bootargs == NULL) { soc_log_err("alloc memory failed\n"); return TD_FAILURE; } err_ret = memset_s(bootargs, MAX_BOOTARGS_LEN, 0, MAX_BOOTARGS_LEN); if (err_ret != EOK) { soc_log_err("secure func call error\n"); goto err_free; } if (get_bootargs((td_u8 *)bootargs, MAX_BOOTARGS_LEN) < 0) { soc_log_err("get_bootargs failed.\n"); goto err_free; } ret = strstr((td_char *)bootargs, "mmcblk0:"); if (ret == NULL) { goto err_free; } free(bootargs); bootargs = NULL; return TD_SUCCESS; err_free: free(bootargs); bootargs = NULL; return TD_FAILURE; } td_s32 uapi_ss_ddr_set_spread(td_bool enable) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_DDR_ENABLE, &enable); if (ret < 0) { soc_log_err("uapi_ss_ddr_set_spread failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_ddr_set_spread_ratio(td_u32 ratio) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_DDR_RATIO, &ratio); if (ret < 0) { soc_log_err("uapi_ss_ddr_set_spread_ratio failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_ddr_set_spread_freq(td_u32 freq) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_DDR_FREQ, &freq); if (ret < 0) { soc_log_err("uapi_ss_ddr_set_spread_freq failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_emmc_set_clock(td_bool enable) { td_s32 ret; td_s32 spread_fd; if (ext_ss_get_emmc_type() == TD_FAILURE) { soc_log_err("Only support emmc device.\n"); return 0; } spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_EMMC_CLKEN, &enable); if (ret < 0) { soc_log_err("uapi_ss_emmc_set_clock failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_emmc_set_spread(td_bool enable) { td_s32 ret; td_s32 spread_fd; if (ext_ss_get_emmc_type() == TD_FAILURE) { soc_log_err("Only support emmc device.\n"); return 0; } spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_EMMC_ENABLE, &enable); if (ret < 0) { soc_log_err("uapi_ss_emmc_set_spread failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_emmc_set_spread_ratio(td_u32 ratio) { td_s32 ret; td_s32 spread_fd; if (ext_ss_get_emmc_type() == TD_FAILURE) { soc_log_err("Only support emmc device.\n"); return 0; } spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_EMMC_RATIO, &ratio); if (ret < 0) { soc_log_err("uapi_ss_emmc_set_spread_ratio failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_emmc_set_spread_freq(td_u32 freq) { td_s32 ret; td_s32 spread_fd; if (ext_ss_get_emmc_type() == TD_FAILURE) { soc_log_err("Only support emmc device.\n"); return 0; } spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_EMMC_FREQ, &freq); if (ret < 0) { soc_log_err("uapi_ss_emmc_set_spread_freq failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_gmac_set_clock(td_bool enable) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_GMAC_CLKEN, &enable); if (ret < 0) { soc_log_err("uapi_ss_gmac_set_clock failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_gmac_set_spread(td_bool enable) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_GMAC_ENABLE, &enable); if (ret < 0) { soc_log_err("uapi_ss_gmac_set_spread failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_gmac_set_spread_ratio(td_u32 ratio) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_GMAC_RATIO, &ratio); if (ret < 0) { soc_log_err("uapi_ss_gmac_set_spread_ratio failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ss_gmac_set_spread_freq(td_u32 freq) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_GMAC_FREQ, &freq); if (ret < 0) { soc_log_err("uapi_ss_gmac_set_spread_freq failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; } td_s32 uapi_ci_set_clock(td_bool enable) { td_s32 ret; td_s32 spread_fd; spread_fd = ext_spread_open(); if (spread_fd < 0) { soc_log_err("open spread dev failed.\n"); return TD_FAILURE; } ret = ioctl(spread_fd, CMD_SPREAD_SET_CI_CLKEN, &enable); if (ret < 0) { soc_log_err("uapi_ci_set_clock failed.\n"); close(spread_fd); return TD_FAILURE; } close(spread_fd); return TD_SUCCESS; }