From 6bbe8530ddc04c136afcd5aad2fa3add2029a3bd Mon Sep 17 00:00:00 2001 From: haizhouyang Date: Tue, 18 May 2021 21:12:01 +0800 Subject: [PATCH 1/2] platform sync from l2 --- Makefile | 1 - platform/Makefile | 4 +- platform/emmc/emmc_adapter.c | 13 +- platform/gpio/gpio_adapter.c | 8 +- platform/i2c/i2c_adapter.c | 4 +- platform/mipi_dsi/Makefile | 12 +- platform/mipi_dsi/mipi_dsi_adapter.c | 16 +- platform/mipi_dsi/mipi_dsi_adapter.h | 4 +- platform/mipi_dsi/mipi_tx_dev.c | 447 +++++++++ platform/mipi_dsi/mipi_tx_dev.h | 120 +++ platform/mipi_dsi/mipi_tx_hi35xx.c | 1101 ++++++++++++++++++++++ platform/mipi_dsi/mipi_tx_hi35xx.h | 119 +++ platform/mipi_dsi/mipi_tx_reg.h | 928 ++++++++++++++++++ platform/platform.mk | 3 +- platform/pwm/Makefile | 5 +- platform/pwm/adapter/Makefile | 18 - platform/pwm/driver/Kconfig | 5 - platform/pwm/driver/Makefile | 17 - platform/pwm/{adapter => }/pwm_adapter.c | 0 platform/pwm/pwm_hi35xx.h | 112 +++ platform/pwm/pwm_hi35xx_linux.c | 185 ++++ platform/rtc/rtc_adapter.c | 6 +- platform/sdio/sdio_adapter.c | 10 +- platform/uart/uart_adapter.c | 62 +- platform/watchdog/watchdog_adapter.c | 12 +- 25 files changed, 3113 insertions(+), 99 deletions(-) create mode 100644 platform/mipi_dsi/mipi_tx_dev.c create mode 100644 platform/mipi_dsi/mipi_tx_dev.h create mode 100644 platform/mipi_dsi/mipi_tx_hi35xx.c create mode 100644 platform/mipi_dsi/mipi_tx_hi35xx.h create mode 100644 platform/mipi_dsi/mipi_tx_reg.h delete mode 100644 platform/pwm/adapter/Makefile delete mode 100644 platform/pwm/driver/Kconfig delete mode 100644 platform/pwm/driver/Makefile rename platform/pwm/{adapter => }/pwm_adapter.c (100%) create mode 100644 platform/pwm/pwm_hi35xx.h create mode 100644 platform/pwm/pwm_hi35xx_linux.c diff --git a/Makefile b/Makefile index 41399ef..236cb94 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,6 @@ # export HDF_ROOT := drivers/hdf -obj-y += platform/pwm/driver/ obj-$(CONFIG_DRIVERS_HDF) += osal/ obj-$(CONFIG_DRIVERS_HDF) += network/ obj-$(CONFIG_DRIVERS_HDF) += config/ diff --git a/platform/Makefile b/platform/Makefile index a8f29fc..f6ade0b 100644 --- a/platform/Makefile +++ b/platform/Makefile @@ -12,12 +12,12 @@ # # -obj-$(CONFIG_DRIVERS_HDF_PLATFORM) += common/ +obj-$(CONFIG_DRIVERS_HDF_PLATFORM) += common/ obj-$(CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI) += mipi_dsi/ obj-$(CONFIG_DRIVERS_HDF_PLATFORM_GPIO) += gpio/ obj-$(CONFIG_DRIVERS_HDF_PLATFORM_I2C) += i2c/ obj-$(CONFIG_DRIVERS_HDF_PLATFORM_WATCHDOG) += watchdog/ -obj-y += pwm/ +obj-$(CONFIG_DRIVERS_HDF_PLATFORM_PWM) += pwm/ obj-$(CONFIG_DRIVERS_HDF_PLATFORM_UART) += uart/ obj-$(CONFIG_DRIVERS_HDF_PLATFORM_SDIO) += sdio/ obj-$(CONFIG_DRIVERS_HDF_PLATFORM_EMMC) += emmc/ diff --git a/platform/emmc/emmc_adapter.c b/platform/emmc/emmc_adapter.c index 2ec4819..5ab9576 100644 --- a/platform/emmc/emmc_adapter.c +++ b/platform/emmc/emmc_adapter.c @@ -1,5 +1,5 @@ /* - * emmc_adatper.c + * emmc_adapter.c * * hi35xx linux emmc driver implement. * @@ -18,9 +18,9 @@ #include #include -#include #include "emmc_core.h" #include "hdf_log.h" +#include "securec.h" #define HDF_LOG_TAG emmc_adapter_c @@ -86,8 +86,11 @@ static int32_t Hi35xxLinuxEmmcBind(struct HdfDeviceObject *device) HDF_LOGE("Hi35xxLinuxEmmcBind: Fail, device is NULL."); return HDF_ERR_INVALID_OBJECT; } - HDF_LOGD("Hi35xxLinuxEmmcBind: Success."); - return (EmmcCntlrCreateAndBind(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS; + if (EmmcCntlrCreateAndBind(device) == NULL) { + return HDF_FAILURE; + } + HDF_LOGI("Hi35xxLinuxEmmcBind: Success."); + return HDF_SUCCESS; } static int32_t Hi35xxLinuxEmmcInit(struct HdfDeviceObject *device) @@ -114,7 +117,7 @@ static int32_t Hi35xxLinuxEmmcInit(struct HdfDeviceObject *device) cntlr->priv = (void *)himci_get_mmc_host(cntlr->configData.hostId); cntlr->method = &g_emmcMethod; - HDF_LOGD("Hi35xxLinuxEmmcInit: Success!"); + HDF_LOGI("Hi35xxLinuxEmmcInit: Success!"); return HDF_SUCCESS; } diff --git a/platform/gpio/gpio_adapter.c b/platform/gpio/gpio_adapter.c index d4b92e9..9ad2020 100644 --- a/platform/gpio/gpio_adapter.c +++ b/platform/gpio/gpio_adapter.c @@ -1,5 +1,5 @@ /* - * gpio_adatper.h + * gpio_adapter.h * * gpio driver adapter of linux * @@ -53,6 +53,7 @@ static int32_t LinuxGpioSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t int32_t ret; int val; + (void)cntlr; switch (dir) { case GPIO_DIR_IN: ret = gpio_direction_input(gpio); @@ -77,6 +78,7 @@ static int32_t LinuxGpioGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t { int dirGet; + (void)cntlr; dirGet = gpiod_get_direction(gpio_to_desc(gpio)); if (dirGet < 0) { return HDF_ERR_BSP_PLT_API_ERR; @@ -98,6 +100,7 @@ static int32_t LinuxGpioSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t int ret, irq; unsigned long flags = 0; + (void)cntlr; irq = gpio_to_irq(gpio); if (irq < 0) { HDF_LOGE("%s: gpio(%u) to irq fail:%d", __func__, gpio, irq); @@ -125,6 +128,7 @@ static int32_t LinuxGpioUnsetIrq(struct GpioCntlr *cntlr, uint16_t gpio) { int irq; + (void)cntlr; irq = gpio_to_irq(gpio); if (irq < 0) { HDF_LOGE("%s: gpio(%u) to irq fail:%d", __func__, gpio, irq); @@ -139,6 +143,7 @@ static inline int32_t LinuxGpioEnableIrq(struct GpioCntlr *cntlr, uint16_t gpio) { int irq; + (void)cntlr; irq = gpio_to_irq(gpio); if (irq < 0) { HDF_LOGE("%s: gpio(%u) to irq fail:%d", __func__, gpio, irq); @@ -152,6 +157,7 @@ static inline int32_t LinuxGpioDisableIrq(struct GpioCntlr *cntlr, uint16_t gpio { int irq; + (void)cntlr; irq = gpio_to_irq(gpio); if (irq < 0) { HDF_LOGE("%s: gpio(%u) to irq fail:%d", __func__, gpio, irq); diff --git a/platform/i2c/i2c_adapter.c b/platform/i2c/i2c_adapter.c index b37c90e..c3e4980 100644 --- a/platform/i2c/i2c_adapter.c +++ b/platform/i2c/i2c_adapter.c @@ -1,5 +1,5 @@ /* - * i2c_adatper.h + * i2c_adapter.h * * i2c driver adapter of linux * @@ -61,7 +61,7 @@ static int32_t LinuxI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int return HDF_ERR_INVALID_OBJECT; } if (msgs == NULL || count <= 0) { - HDF_LOGE("%s: err parms! count:%d", __func__, count); + HDF_LOGE("%s: err params! count:%d", __func__, count); return HDF_ERR_INVALID_PARAM; } diff --git a/platform/mipi_dsi/Makefile b/platform/mipi_dsi/Makefile index 890df24..e99d0b8 100644 --- a/platform/mipi_dsi/Makefile +++ b/platform/mipi_dsi/Makefile @@ -14,10 +14,10 @@ include drivers/hdf/khdf/platform/platform.mk -obj-y += mipi_dsi_adapter.o \ - $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/mipi_dsi_core.o \ - $(HDF_PLATFORM_VENDOR_ROOT)/mipi_dsi/mipi_tx_dev.o \ - $(HDF_PLATFORM_VENDOR_ROOT)/mipi_dsi/mipi_tx_hi35xx.o -ccflags-y += -I$(HDF_PLATFORM_VENDOR_ROOT)/mipi_dsi \ - -Idrivers/hdf/khdf/platform/mipi_dsi +obj-y += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/mipi_dsi_core.o \ + mipi_dsi_adapter.o + +obj-y += mipi_tx_dev.o \ + mipi_tx_hi35xx.o + EXTRA_CFLAGS += -Wno-error=date-time diff --git a/platform/mipi_dsi/mipi_dsi_adapter.c b/platform/mipi_dsi/mipi_dsi_adapter.c index 83189af..63a4aaa 100644 --- a/platform/mipi_dsi/mipi_dsi_adapter.c +++ b/platform/mipi_dsi/mipi_dsi_adapter.c @@ -3,7 +3,7 @@ * * Mipi dsi adapter driver. * - * Copyright (C) Huawei Device Co., Ltd. 2020-2021. All rights reserved. + * Copyright (c) Huawei Device Co., Ltd. 2020-2021. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -73,14 +73,14 @@ int MipiDsiRegisterDevice(const char *name, uint32_t id, unsigned short mode, st dev->mode = mode; error = misc_register(dev); if (error < 0) { - printk("%s: id %u cannot register miscdev on minor=%d (err=%d)\n", + printk("%s: id %u cannot register miscdev on minor=%d (err=%d)", __func__, id, MISC_DYNAMIC_MINOR, error); OsalMemFree((char *)dev->name); OsalMemFree(dev); return error; } g_mipiDsiMiscdev[id] = dev; - printk("mipi_dsi:create inode ok %s %d\n", dev->name, dev->minor); + printk("mipi_dsi:create inode ok %s %d", dev->name, dev->minor); return 0; } @@ -102,12 +102,12 @@ int MipiDsiProcRegister(const char *name, uint32_t id, unsigned short mode, cons ret = snprintf_s(procName, NAME_LEN + 1, NAME_LEN, "%s", name); } if (ret < 0) { - printk(KERN_ERR "%s: procName %s snprintf_s fail\n", __func__, procName); + printk(KERN_ERR "%s: procName %s snprintf_s fail", __func__, procName); return -1; } err = proc_create(procName, mode, NULL, ops); if (err == NULL) { - printk(KERN_ERR "%s: proc_create name %s fail\n", __func__, procName); + printk(KERN_ERR "%s: proc_create name %s fail", __func__, procName); return -1; } return 0; @@ -133,14 +133,16 @@ void MipiDsiProcUnregister(const char *name, uint32_t id) if (id >= MAX_CNTLR_CNT) { return; } - memset_s(procName, NAME_LEN + 1, 0, NAME_LEN + 1); + if (memset_s(procName, NAME_LEN + 1, 0, NAME_LEN + 1) != EOK) { + return; + } if (id != 0) { ret = snprintf_s(procName, NAME_LEN + 1, NAME_LEN, "%s%u", name, id); } else { ret = snprintf_s(procName, NAME_LEN + 1, NAME_LEN, "%s", name); } if (ret < 0) { - printk(KERN_ERR "%s: procName %s snprintf_s fail\n", __func__, procName); + printk(KERN_ERR "%s: procName format fail", __func__); return; } remove_proc_entry(procName, NULL); diff --git a/platform/mipi_dsi/mipi_dsi_adapter.h b/platform/mipi_dsi/mipi_dsi_adapter.h index 3aec296..ae85417 100644 --- a/platform/mipi_dsi/mipi_dsi_adapter.h +++ b/platform/mipi_dsi/mipi_dsi_adapter.h @@ -3,7 +3,7 @@ * * Mipi dsi adapter driver. * - * Copyright (C) Huawei Device Co., Ltd. 2020-2021. All rights reserved. + * Copyright (c) Huawei Device Co., Ltd. 2020-2021. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -25,4 +25,4 @@ int MipiDsiRegisterDevice(const char *name, uint32_t id, unsigned short mode, st void MipiDsiUnregisterDevice(uint32_t id); int MipiDsiProcRegister(const char *name, uint32_t id, unsigned short mode, const struct file_operations *ops); void MipiDsiProcUnregister(const char *name, uint32_t id); -#endif // MIPI_DSI_ADAPTER_H +#endif /* MIPI_DSI_ADAPTER_H */ diff --git a/platform/mipi_dsi/mipi_tx_dev.c b/platform/mipi_dsi/mipi_tx_dev.c new file mode 100644 index 0000000..cd0e4ea --- /dev/null +++ b/platform/mipi_dsi/mipi_tx_dev.c @@ -0,0 +1,447 @@ +/* + * mipi_tx_dev.c + * + * create vfs node for mipi + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "hdf_base.h" +#include "hdf_log.h" +#include "mipi_dsi_adapter.h" +#include "mipi_tx_dev.h" +#include "mipi_tx_hi35xx.h" +#include "mipi_tx_reg.h" +#include "osal_io.h" +#include "osal_mem.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C"{ +#endif +#endif /* End of #ifdef __cplusplus */ + +/**************************************************************************** + * macro definition * + ****************************************************************************/ +#define MIPI_TX_DEV_NAME "hi_mipi_tx" +#define MIPI_TX_PROC_NAME "mipi_tx" + +struct semaphore g_mipiTxSem; +static int32_t MipiTxSemaInit(struct semaphore *sem, uint16_t val) +{ + if (sem == NULL) { + return -1; + } + sema_init(sem, val); + return 0; +} + +static void MipiTxSemaDestroy(const struct semaphore *sem) +{ + (void *)sem; + return; +} + +static int32_t MipiTxSemaDownInterruptable(const struct semaphore *sem) +{ + return down_interruptible((struct semaphore *)sem); +} + +static void MipiTxUp(const struct semaphore *sem) +{ + up((struct semaphore *)sem); +} + +static int g_enDev; +static int g_enDevCfg; +MipiTxDevCtxTag g_mipiTxDevCtx; + +static int MipiTxCheckCombDevCfg(const ComboDevCfgTag *devCfg) +{ + int i; + int validLaneId[LANE_MAX_NUM] = {0, 1, 2, 3}; + + if (g_enDev == TRUE) { + HDF_LOGE("mipi_tx dev has enable!\n"); + return -1; + } + if (devCfg->devno != 0) { + HDF_LOGE("mipi_tx dev devno err!\n"); + return -1; + } + for (i = 0; i < LANE_MAX_NUM; i++) { + if ((devCfg->laneId[i] != validLaneId[i]) && (devCfg->laneId[i] != MIPI_TX_DISABLE_LANE_ID)) { + HDF_LOGE("mipi_tx dev laneId %d err!\n", devCfg->laneId[i]); + return -1; + } + } + if ((devCfg->outputMode != OUTPUT_MODE_CSI) && (devCfg->outputMode != OUTPUT_MODE_DSI_VIDEO) && + (devCfg->outputMode != OUTPUT_MODE_DSI_CMD)) { + HDF_LOGE("mipi_tx dev outputMode %d err!\n", devCfg->outputMode); + return -1; + } + if ((devCfg->videoMode != BURST_MODE) && (devCfg->videoMode != NON_BURST_MODE_SYNC_PULSES) && + (devCfg->videoMode != NON_BURST_MODE_SYNC_EVENTS)) { + HDF_LOGE("mipi_tx dev videoMode %d err!\n", devCfg->videoMode); + return -1; + } + if ((devCfg->outputFormat != OUT_FORMAT_RGB_16_BIT) && (devCfg->outputFormat != OUT_FORMAT_RGB_18_BIT) && + (devCfg->outputFormat != OUT_FORMAT_RGB_24_BIT) && (devCfg->outputFormat != + OUT_FORMAT_YUV420_8_BIT_NORMAL) && (devCfg->outputFormat != OUT_FORMAT_YUV420_8_BIT_LEGACY) && + (devCfg->outputFormat != OUT_FORMAT_YUV422_8_BIT)) { + HDF_LOGE("mipi_tx dev outputFormat %d err!\n", devCfg->outputFormat); + return -1; + } + return 0; +} + +int MipiTxSetComboDevCfg(const ComboDevCfgTag *devCfg) +{ + int ret; + + ret = MipiTxCheckCombDevCfg(devCfg); + if (ret < 0) { + HDF_LOGE("mipi_tx check combo_dev config failed!\n"); + return ret; + } + /* set controller config */ + MipiTxDrvSetControllerCfg(devCfg); + /* set phy config */ + MipiTxDrvSetPhyCfg(devCfg); + ret = memcpy_s(&g_mipiTxDevCtx.devCfg, sizeof(ComboDevCfgTag), devCfg, sizeof(ComboDevCfgTag)); + if (ret != EOK) { + return ret; + } + g_enDevCfg = TRUE; + return ret; +} + +static int MipiTxCheckSetCmdInfo(const CmdInfoTag *cmdInfo) +{ + if (g_enDev == TRUE) { + HDF_LOGE("mipi_tx dev has enable!\n"); + return -1; + } + if (g_enDevCfg != TRUE) { + HDF_LOGE("mipi_tx dev has not config!\n"); + return -1; + } + if (cmdInfo->devno != 0) { + HDF_LOGE("mipi_tx devno %d err!\n", cmdInfo->devno); + return -1; + } + /* When cmd is not NULL, cmd_size means the length of cmd or it means cmd and addr */ + if (cmdInfo->cmd != NULL) { + if (cmdInfo->cmdSize > MIPI_TX_SET_DATA_SIZE) { + HDF_LOGE("mipi_tx dev cmd_size %d err!\n", cmdInfo->cmdSize); + return -1; + } + } + return 0; +} + +int MipiTxSetCmd(const CmdInfoTag *cmdInfo) +{ + int ret; + + ret = MipiTxCheckSetCmdInfo(cmdInfo); + if (ret < 0) { + HDF_LOGE("mipi_tx check combo_dev config failed!\n"); + return ret; + } + return MipiTxDrvSetCmdInfo(cmdInfo); +} + +static int MipiTxCheckGetCmdInfo(const GetCmdInfoTag *getCmdInfo) +{ + if (g_enDev == TRUE) { + HDF_LOGE("mipi_tx dev has enable!\n"); + return -1; + } + if (g_enDevCfg != TRUE) { + HDF_LOGE("mipi_tx dev has not config!\n"); + return -1; + } + if (getCmdInfo->devno != 0) { + HDF_LOGE("mipi_tx dev devno %d err!\n", getCmdInfo->devno); + return -1; + } + if ((getCmdInfo->getDataSize == 0) || (getCmdInfo->getDataSize > MIPI_TX_GET_DATA_SIZE)) { + HDF_LOGE("mipi_tx dev getDataSize %d err!\n", getCmdInfo->getDataSize); + return -1; + } + if (getCmdInfo->getData == NULL) { + HDF_LOGE("mipi_tx dev getData is null!\n"); + return -1; + } + return 0; +} + +int MipiTxGetCmd(GetCmdInfoTag *getCmdInfo) +{ + int ret; + + ret = MipiTxCheckGetCmdInfo(getCmdInfo); + if (ret < 0) { + HDF_LOGE("mipi_tx check combo_dev config failed!\n"); + return ret; + } + return MipiTxDrvGetCmdInfo(getCmdInfo); +} + +static void MipiTxEnable(void) +{ + OutPutModeTag mode; + + mode = g_mipiTxDevCtx.devCfg.outputMode; + MipiTxDrvEnableInput(mode); + g_enDev = TRUE; +} + +static void MipiTxDisable(void) +{ + MipiTxDrvDisableInput(); + g_enDev = FALSE; + g_enDevCfg = FALSE; +} + +static long MipiTxIoctl(struct file *filep, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + void *pArg = (void *)arg; + + if (filep == NULL || pArg == NULL) { + HDF_LOGE("invalid input param"); + return -1; + } + if (MipiTxSemaDownInterruptable(&g_mipiTxSem)) { + return -1; + } + switch (cmd) { + case HI_MIPI_TX_SET_DEV_CFG: + ret = MipiTxSetComboDevCfg((ComboDevCfgTag *)pArg); + if (ret < 0) { + HDF_LOGE("mipi_tx set combo_dev config failed!\n"); + } + break; + case HI_MIPI_TX_SET_CMD: + ret = MipiTxSetCmd((CmdInfoTag *)pArg); + if (ret < 0) { + HDF_LOGE("mipi_tx set cmd failed!\n"); + } + break; + case HI_MIPI_TX_GET_CMD: + ret = MipiTxGetCmd((GetCmdInfoTag *)pArg); + if (ret < 0) { + HDF_LOGE("mipi_tx get cmd failed!\n"); + } + break; + case HI_MIPI_TX_ENABLE: + MipiTxEnable(); + break; + case HI_MIPI_TX_DISABLE: + MipiTxDisable(); + break; + default: + HDF_LOGE("invalid mipi_tx ioctl cmd"); + ret = -1; + break; + } + MipiTxUp(&g_mipiTxSem); + return ret; +} + +static int MipiTxInit(int smooth) +{ + return MipiTxDrvInit(smooth); +} + +static void MipiTxExit(void) +{ + MipiTxDrvExit(); +} + +static int MipiTxOpen(struct inode *inode, struct file *filep) +{ + (void)inode; + (void)filep; + return 0; +} + +static int MipiTxRelease(struct inode *inode, struct file *filep) +{ + (void)inode; + (void)filep; + return 0; +} + +static void MipiTxProcDevShow(struct seq_file *s) +{ + ComboDevCfgTag *devCfg = NULL; + SyncInfoTag *syncInfo = NULL; + devCfg = (ComboDevCfgTag *)&g_mipiTxDevCtx.devCfg; + syncInfo = (SyncInfoTag *)&g_mipiTxDevCtx.devCfg.syncInfo; + + /* mipi tx device config */ + seq_printf(s, "----------MIPI_Tx DEV CONFIG---------------------------\n"); + seq_printf(s, "%8s%8s%8s%8s%8s%15s%15s%15s%15s%15s\n", + "devno", "lane0", "lane1", "lane2", "lane3", "output_mode", "phy_data_rate", "pixel_clk(KHz)", + "video_mode", "output_fmt"); + seq_printf(s, "%8d%8d%8d%8d%8d%15d%15d%15d%15d%15d\n", + devCfg->devno, + devCfg->laneId[0], + devCfg->laneId[1], + devCfg->laneId[2], /* lina id 2 */ + devCfg->laneId[3], /* lina id 3 */ + devCfg->outputMode, + devCfg->phyDataRate, + devCfg->pixelClk, + devCfg->videoMode, + devCfg->outputFormat); + seq_printf(s, "\r\n"); + /* mipi tx device sync config */ + seq_printf(s, "----------MIPI_Tx SYNC CONFIG---------------------------\n"); + seq_printf(s, "%14s%14s%14s%14s%14s%14s%14s%14s%14s\n", + "pkt_size", "hsa_pixels", "hbp_pixels", "hline_pixels", "vsa_lines", "vbp_lines", + "vfp_lines", "active_lines", "edpi_cmd_size"); + seq_printf(s, "%14d%14d%14d%14d%14d%14d%14d%14d%14d\n", + syncInfo->vidPktSize, + syncInfo->vidHsaPixels, + syncInfo->vidHbpPixels, + syncInfo->vidHlinePixels, + syncInfo->vidVsaLines, + syncInfo->vidVbpLines, + syncInfo->vidVfpLines, + syncInfo->vidActiveLines, + syncInfo->edpiCmdSize); + seq_printf(s, "\r\n"); +} + +static void MipiTxProcDevStatusShow(struct seq_file *s) +{ + MipiTxDevPhyTag phyCtx; + + MipiTxDrvGetDevStatus(&phyCtx); + /* mipi tx phy status */ + seq_printf(s, "----------MIPI_Tx DEV STATUS---------------------------\n"); + seq_printf(s, "%8s%8s%8s%8s%8s%8s%8s\n", + "width", "height", "HoriAll", "VertAll", "hbp", "hsa", "vsa"); + seq_printf(s, "%8u%8u%8u%8u%8u%8u%8u\n", + phyCtx.hactDet, + phyCtx.vactDet, + phyCtx.hallDet, + phyCtx.vallDet, + phyCtx.hbpDet, + phyCtx.hsaDet, + phyCtx.vsaDet); + seq_printf(s, "\r\n"); +} + +static int MipiTxProcShow(struct seq_file *m, void *v) +{ + seq_printf(m, "\nModule: [MIPI_TX], Build Time["__DATE__", "__TIME__"]\n"); + MipiTxProcDevShow(m); + MipiTxProcDevStatusShow(m); + HDF_LOGI("%s: v %p", __func__, v); + return 0; +} + +static int MipiTxProcOpen(struct inode *inode, struct file *file) +{ + return single_open(file, MipiTxProcShow, NULL); +} + +static const struct file_operations g_procMipiTxOps = { + .open = MipiTxProcOpen, + .read = seq_read, +}; + +static const struct file_operations g_mipiTxfOps = { + .open = MipiTxOpen, + .release = MipiTxRelease, + .unlocked_ioctl = MipiTxIoctl, +}; + +static int MipiVfsInit(int smooth) +{ + int ret; + + (void)smooth; + /* 0660 : node mode */ + ret = MipiDsiRegisterDevice(MIPI_TX_DEV_NAME, 0, 0660, (struct file_operations *)&g_mipiTxfOps); + if (ret < 0) { + HDF_LOGE("%s: mipi dsi reg dev fail:%d", __func__, ret); + return ret; + } + ret = MipiDsiProcRegister(MIPI_TX_PROC_NAME, 0, 0440, &g_procMipiTxOps); /* 0440 : proc file mode */ + if (ret < 0) { + MipiDsiUnregisterDevice(0); + HDF_LOGE("%s: mipi dsi reg proc fail:%d", __func__, ret); + return ret; + } + + return 0; +} + +static void MipiVfsRemove(void) +{ + MipiDsiUnregisterDevice(0); + MipiDsiProcUnregister(MIPI_TX_PROC_NAME, 0); +} + +int MipiTxModuleInit(int smooth) +{ + int ret; + + (void)MipiVfsInit; + + ret = MipiTxInit(smooth); + if (ret != 0) { + HDF_LOGE("hi_mipi_init failed!\n"); + goto fail1; + } + ret = MipiTxSemaInit(&g_mipiTxSem, 1); + if (ret != 0) { + HDF_LOGE("init sema error!\n"); + goto fail2; + } + HDF_LOGE("load mipi_tx driver successful!\n"); + return 0; + +fail2: + MipiTxExit(); +fail1: + (void)MipiVfsRemove; + + HDF_LOGE("load mipi_tx driver failed!\n"); + return ret; +} + +void MipiTxModuleExit(void) +{ + MipiTxSemaDestroy(&g_mipiTxSem); + MipiTxExit(); + (void)MipiVfsRemove; + HDF_LOGI("unload mipi_tx driver ok!\n"); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ diff --git a/platform/mipi_dsi/mipi_tx_dev.h b/platform/mipi_dsi/mipi_tx_dev.h new file mode 100644 index 0000000..1816531 --- /dev/null +++ b/platform/mipi_dsi/mipi_tx_dev.h @@ -0,0 +1,120 @@ +/* + * mipi_tx_dev.h + * + * hi35xx mipi_tx driver implement. + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef MIPI_TX_DEV_H +#define MIPI_TX_DEV_H + +#define CMD_MAX_NUM 4 +#define LANE_MAX_NUM 4 + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define CMD_MAX_NUM 4 +#define LANE_MAX_NUM 4 +#define MIPI_TX_DISABLE_LANE_ID (-1) +#define MIPI_TX_SET_DATA_SIZE 800 +#define MIPI_TX_GET_DATA_SIZE 160 + +typedef enum { + OUTPUT_MODE_CSI = 0x0, /* csi mode */ + OUTPUT_MODE_DSI_VIDEO = 0x1, /* dsi video mode */ + OUTPUT_MODE_DSI_CMD = 0x2, /* dsi command mode */ + + OUTPUT_MODE_BUTT +} OutPutModeTag; + +typedef enum { + BURST_MODE = 0x0, + NON_BURST_MODE_SYNC_PULSES = 0x1, + NON_BURST_MODE_SYNC_EVENTS = 0x2, + + VIDEO_DATA_MODE_BUTT +} VideoModeTag; + +typedef enum { + OUT_FORMAT_RGB_16_BIT = 0x0, + OUT_FORMAT_RGB_18_BIT = 0x1, + OUT_FORMAT_RGB_24_BIT = 0x2, + OUT_FORMAT_YUV420_8_BIT_NORMAL = 0x3, + OUT_FORMAT_YUV420_8_BIT_LEGACY = 0x4, + OUT_FORMAT_YUV422_8_BIT = 0x5, + + OUT_FORMAT_BUTT +} OutputFormatTag; + +typedef struct { + unsigned short vidPktSize; + unsigned short vidHsaPixels; + unsigned short vidHbpPixels; + unsigned short vidHlinePixels; + unsigned short vidVsaLines; + unsigned short vidVbpLines; + unsigned short vidVfpLines; + unsigned short vidActiveLines; + unsigned short edpiCmdSize; +} SyncInfoTag; + +typedef struct { + unsigned int devno; /* device number */ + short laneId[LANE_MAX_NUM]; /* lane_id: -1 - disable */ + OutPutModeTag outputMode; /* output mode: CSI/DSI_VIDEO/DSI_CMD */ + VideoModeTag videoMode; + OutputFormatTag outputFormat; + SyncInfoTag syncInfo; + unsigned int phyDataRate; /* mbps */ + unsigned int pixelClk; /* KHz */ +} ComboDevCfgTag; + +typedef struct { + unsigned int devno; /* device number */ + unsigned short dataType; + unsigned short cmdSize; + unsigned char *cmd; +} CmdInfoTag; + +typedef struct { + unsigned int devno; /* device number */ + unsigned short dataType; /* DSI data type */ + unsigned short dataParam; /* data param,low 8 bit:1st param.high 8 bit:2nt param, set 0 if not use */ + unsigned short getDataSize; /* read data size */ + unsigned char *getData; /* read data memory address, should malloc by user */ +} GetCmdInfoTag; + +typedef struct { + ComboDevCfgTag devCfg; +} MipiTxDevCtxTag; + +#define HI_MIPI_TX_IOC_MAGIC 't' + +#define HI_MIPI_TX_SET_DEV_CFG _IOW(HI_MIPI_TX_IOC_MAGIC, 0x01, ComboDevCfgTag) +#define HI_MIPI_TX_SET_CMD _IOW(HI_MIPI_TX_IOC_MAGIC, 0x02, CmdInfoTag) +#define HI_MIPI_TX_ENABLE _IO(HI_MIPI_TX_IOC_MAGIC, 0x03) +#define HI_MIPI_TX_GET_CMD _IOWR(HI_MIPI_TX_IOC_MAGIC, 0x04, GetCmdInfoTag) +#define HI_MIPI_TX_DISABLE _IO(HI_MIPI_TX_IOC_MAGIC, 0x05) + +int MipiTxSetCmd(const CmdInfoTag *cmdInfo); +int MipiTxGetCmd(GetCmdInfoTag *getCmdInfo); +int MipiTxSetComboDevCfg(const ComboDevCfgTag *devCfg); +int MipiTxModuleInit(int smooth); +void MipiTxModuleExit(void); +#endif /* MIPI_TX_DEV_H */ diff --git a/platform/mipi_dsi/mipi_tx_hi35xx.c b/platform/mipi_dsi/mipi_tx_hi35xx.c new file mode 100644 index 0000000..39832be --- /dev/null +++ b/platform/mipi_dsi/mipi_tx_hi35xx.c @@ -0,0 +1,1101 @@ +/* + * mipi_tx_hi35xx.c + * + * hi35xx mipi_tx driver implement + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include "hdf_log.h" +#include "mipi_dsi_core.h" +#include "mipi_tx_dev.h" +#include "mipi_tx_hi35xx.h" +#include "mipi_tx_reg.h" +#include "osal_io.h" +#include "osal_mem.h" +#include "osal_time.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +volatile MipiTxRegsTypeTag *g_mipiTxRegsVa = NULL; +unsigned int g_mipiTxIrqNum = MIPI_TX_IRQ; +unsigned int g_actualPhyDataRate; +static unsigned int g_regMapFlag; + +static void WriteReg32(unsigned long addr, unsigned int value, unsigned int mask) +{ + unsigned int t; + + t = OSAL_READL((void *)addr); + t &= ~mask; + t |= value & mask; + OSAL_WRITEL(t, (void *)addr); +} + +static void OsalIsb(void) +{ + isb(); +} + +static void OsalDsb(void) +{ + dsb(); +} + +static void OsalDmb(void) +{ + dmb(); +} + +static void HdfIsbDsbDmb(void) +{ + OsalIsb(); + OsalDsb(); + OsalDmb(); +} + +static void SetPhyReg(unsigned int addr, unsigned char value) +{ + HdfIsbDsbDmb(); + g_mipiTxRegsVa->PHY_TST_CTRL1.u32 = (0x10000 + addr); + HdfIsbDsbDmb(); + g_mipiTxRegsVa->PHY_TST_CTRL0.u32 = 0x2; + HdfIsbDsbDmb(); + g_mipiTxRegsVa->PHY_TST_CTRL0.u32 = 0x0; + HdfIsbDsbDmb(); + g_mipiTxRegsVa->PHY_TST_CTRL1.u32 = value; + HdfIsbDsbDmb(); + g_mipiTxRegsVa->PHY_TST_CTRL0.u32 = 0x2; + HdfIsbDsbDmb(); + g_mipiTxRegsVa->PHY_TST_CTRL0.u32 = 0x0; + HdfIsbDsbDmb(); +} + + +static unsigned char MipiTxDrvGetPhyPllSet0(unsigned int phyDataRate) +{ + unsigned char pllSet0; + + /* to get pllSet0, the parameters come from algorithm */ + if (phyDataRate > 750) { /* 750: mipi clk */ + pllSet0 = 0x0; + } else if (phyDataRate > 375) { /* 375: mipi clk */ + pllSet0 = 0x8; + } else if (phyDataRate > 188) { /* 188: mipi clk */ + pllSet0 = 0xa; + } else if (phyDataRate > 94) { /* 94: mipi clk */ + pllSet0 = 0xc; + } else { + pllSet0 = 0xe; + } + return pllSet0; +} + +static void MipiTxDrvGetPhyPllSet1Set5(unsigned int phyDataRate, + unsigned char pllSet0, + unsigned char *pllSet1, + unsigned char *pllSet5) +{ + int dataRateClk; + int pllRef; + + dataRateClk = (phyDataRate + MIPI_TX_REF_CLK - 1) / MIPI_TX_REF_CLK; + + /* to get pllSet1 and pllSet5, the parameters come from algorithm */ + if (pllSet0 / 2 == 4) { /* 2: pll, 4: pll sel */ + pllRef = 2; /* 2: pll set */ + } else if (pllSet0 / 2 == 5) { /* 2: pll, 5: pllSet5 */ + pllRef = 4; /* 4: pll set */ + } else if (pllSet0 / 2 == 6) { /* 2: pll, 6: pll sel */ + pllRef = 8; /* 8: pll set */ + } else if (pllSet0 / 2 == 7) { /* 2: pll, 7: pll sel */ + pllRef = 16; /* 16: pll set */ + } else { + pllRef = 1; + } + if ((dataRateClk * pllRef) % 2) { /* 2: pll */ + *pllSet1 = 0x10; + *pllSet5 = (dataRateClk * pllRef - 1) / 2; /* 2: pllRef sel */ + } else { + *pllSet1 = 0x20; + *pllSet5 = dataRateClk * pllRef / 2 - 1; /* 2: pllRef sel */ + } + + return; +} + +static void MipiTxDrvSetPhyPllSetX(unsigned int phyDataRate) +{ + unsigned char pllSet0; + unsigned char pllSet1; + unsigned char pllSet2; +#ifdef HI_FPGA + unsigned char pllSet3; +#endif + unsigned char pllSet4; + unsigned char pllSet5; + + /* pllSet0 */ + pllSet0 = MipiTxDrvGetPhyPllSet0(phyDataRate); + SetPhyReg(PLL_SET0, pllSet0); + /* pllSet1 */ + MipiTxDrvGetPhyPllSet1Set5(phyDataRate, pllSet0, &pllSet1, &pllSet5); + SetPhyReg(PLL_SET1, pllSet1); + /* pllSet2 */ + pllSet2 = 0x2; + SetPhyReg(PLL_SET2, pllSet2); + /* pllSet4 */ + pllSet4 = 0x0; + SetPhyReg(PLL_SET4, pllSet4); + +#ifdef HI_FPGA + pllSet3 = 0x1; + SetPhyReg(PLL_SET3, pllSet3); +#endif + /* pllSet5 */ + SetPhyReg(PLL_SET5, pllSet5); + +#ifdef MIPI_TX_DEBUG + HDF_LOGI("\n==========phy pll info======="); + HDF_LOGI("pllSet0(0x14): 0x%x", pllSet0); + HDF_LOGI("pllSet1(0x15): 0x%x", pllSet1); + HDF_LOGI("pllSet2(0x16): 0x%x", pllSet2); +#ifdef HI_FPGA + HDF_LOGI("pllSet3(0x17): 0x%x", pllSet3); +#endif + HDF_LOGI("pllSet4(0x1e): 0x%x", pllSet4); + HDF_LOGI("=========================\n"); +#endif +} + +static void MipiTxDrvGetPhyClkPrepare(unsigned char *clkPrepare) +{ + unsigned char temp0; + unsigned char temp1; + + temp0 = ((g_actualPhyDataRate * TCLK_PREPARE + ROUNDUP_VALUE) / INNER_PEROID - 1 + + ((g_actualPhyDataRate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID) - + ((((g_actualPhyDataRate * TCLK_PREPARE + ROUNDUP_VALUE) / INNER_PEROID + + ((g_actualPhyDataRate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID)) * INNER_PEROID - + PREPARE_COMPENSATE * g_actualPhyDataRate - TCLK_PREPARE * g_actualPhyDataRate) / INNER_PEROID)); + if (temp0 > 0) { /* 0 is the minimum */ + temp1 = temp0; + } else { + temp1 = 0; /* 0 is the minimum */ + } + + if (((temp1 + 1) * INNER_PEROID - PREPARE_COMPENSATE * g_actualPhyDataRate) /* temp + 1 is next level period */ + > 94 * g_actualPhyDataRate) { /* 94 is the maximum in mipi protocol */ + if (temp0 > 0) { + *clkPrepare = temp0 - 1; + } else { + *clkPrepare = 255; /* set 255 will easy to found mistake */ + HDF_LOGE("err when calc phy timing"); + } + } else { + if (temp0 > 0) { /* 0 is the minimum */ + *clkPrepare = temp0; + } else { + *clkPrepare = 0; /* 0 is the minimum */ + } + } +} + +static void MipiTxDrvGetPhyDataPrepare(unsigned char *dataPrepare) +{ + unsigned char temp0; + unsigned char temp1; + + /* DATA_THS_PREPARE */ + temp0 = ((g_actualPhyDataRate * THS_PREPARE + ROUNDUP_VALUE) / INNER_PEROID - 1 + + ((g_actualPhyDataRate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID) - + ((((g_actualPhyDataRate * THS_PREPARE + ROUNDUP_VALUE) / INNER_PEROID + + ((g_actualPhyDataRate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID)) * INNER_PEROID - + PREPARE_COMPENSATE * g_actualPhyDataRate - THS_PREPARE * g_actualPhyDataRate) / INNER_PEROID)); + if (temp0 > 0) { + temp1 = temp0; + } else { + temp1 = 0; + } + + if ((g_actualPhyDataRate > 105) && /* bigger than 105 */ + (((temp1 + 1) * INNER_PEROID - PREPARE_COMPENSATE * g_actualPhyDataRate) > + (85 * g_actualPhyDataRate + 6 * 1000))) { /* 85 + 6 * 1000 is the maximum in mipi protocol */ + if (temp0 > 0) { + *dataPrepare = temp0 - 1; + } else { + *dataPrepare = 255; /* set 255 will easy to found mistake */ + HDF_LOGE("err when calc phy timing"); + } + } else { + if (temp0 > 0) { + *dataPrepare = temp0; + } else { + *dataPrepare = 0; + } + } +} + +/* get global operation timing parameters. */ +static void MipiTxDrvGetPhyTimingParam(MipiTxPhyTimingParamTag *tp) +{ + /* DATA0~3 TPRE-DELAY */ + /* 1: compensate */ + tp->dataTpreDelay = (g_actualPhyDataRate * TPRE_DELAY + ROUNDUP_VALUE) / INNER_PEROID - 1; + /* CLK_TLPX */ + tp->clkTlpx = (g_actualPhyDataRate * TLPX + ROUNDUP_VALUE) / INNER_PEROID - 1; /* 1 is compensate */ + /* CLK_TCLK_PREPARE */ + MipiTxDrvGetPhyClkPrepare(&tp->clkTclkPrepare); + /* CLK_TCLK_ZERO */ + if ((g_actualPhyDataRate * TCLK_ZERO + ROUNDUP_VALUE) / INNER_PEROID > 4) { /* 4 is compensate */ + tp->clkTclkZero = (g_actualPhyDataRate * TCLK_ZERO + ROUNDUP_VALUE) / INNER_PEROID - 4; + } else { + tp->clkTclkZero = 0; /* 0 is minimum */ + } + /* CLK_TCLK_TRAIL */ + tp->clkTclkTrail = (g_actualPhyDataRate * TCLK_TRAIL + ROUNDUP_VALUE) / INNER_PEROID; + /* DATA_TLPX */ + tp->dataTlpx = (g_actualPhyDataRate * TLPX + ROUNDUP_VALUE) / INNER_PEROID - 1; /* 1 is compensate */ + /* DATA_THS_PREPARE */ + MipiTxDrvGetPhyDataPrepare(&tp->dataThsPrepare); + /* DATA_THS_ZERO */ + if ((g_actualPhyDataRate * THS_ZERO + ROUNDUP_VALUE) / INNER_PEROID > 4) { /* 4 is compensate */ + tp->dataThsZero = (g_actualPhyDataRate * THS_ZERO + ROUNDUP_VALUE) / INNER_PEROID - 4; + } else { + tp->dataThsZero = 0; /* 0 is minimum */ + } + /* DATA_THS_TRAIL */ + tp->dataThsTrail = (g_actualPhyDataRate * THS_TRAIL + ROUNDUP_VALUE) / INNER_PEROID + 1; /* 1 is compensate */ +} + +/* set global operation timing parameters. */ +static void MipiTxDrvSetPhyTimingParam(const MipiTxPhyTimingParamTag *tp) +{ + /* DATA0~3 TPRE-DELAY */ + SetPhyReg(DATA0_TPRE_DELAY, tp->dataTpreDelay); + SetPhyReg(DATA1_TPRE_DELAY, tp->dataTpreDelay); + SetPhyReg(DATA2_TPRE_DELAY, tp->dataTpreDelay); + SetPhyReg(DATA3_TPRE_DELAY, tp->dataTpreDelay); + + /* CLK_TLPX */ + SetPhyReg(CLK_TLPX, tp->clkTlpx); + /* CLK_TCLK_PREPARE */ + SetPhyReg(CLK_TCLK_PREPARE, tp->clkTclkPrepare); + /* CLK_TCLK_ZERO */ + SetPhyReg(CLK_TCLK_ZERO, tp->clkTclkZero); + /* CLK_TCLK_TRAIL */ + SetPhyReg(CLK_TCLK_TRAIL, tp->clkTclkTrail); + + /* + * DATA_TLPX + * DATA_THS_PREPARE + * DATA_THS_ZERO + * DATA_THS_TRAIL + */ + SetPhyReg(DATA0_TLPX, tp->dataTlpx); + SetPhyReg(DATA0_THS_PREPARE, tp->dataThsPrepare); + SetPhyReg(DATA0_THS_ZERO, tp->dataThsZero); + SetPhyReg(DATA0_THS_TRAIL, tp->dataThsTrail); + SetPhyReg(DATA1_TLPX, tp->dataTlpx); + SetPhyReg(DATA1_THS_PREPARE, tp->dataThsPrepare); + SetPhyReg(DATA1_THS_ZERO, tp->dataThsZero); + SetPhyReg(DATA1_THS_TRAIL, tp->dataThsTrail); + SetPhyReg(DATA2_TLPX, tp->dataTlpx); + SetPhyReg(DATA2_THS_PREPARE, tp->dataThsPrepare); + SetPhyReg(DATA2_THS_ZERO, tp->dataThsZero); + SetPhyReg(DATA2_THS_TRAIL, tp->dataThsTrail); + SetPhyReg(DATA3_TLPX, tp->dataTlpx); + SetPhyReg(DATA3_THS_PREPARE, tp->dataThsPrepare); + SetPhyReg(DATA3_THS_ZERO, tp->dataThsZero); + SetPhyReg(DATA3_THS_TRAIL, tp->dataThsTrail); + +#ifdef MIPI_TX_DEBUG + HDF_LOGI("\n==========phy timing parameters======="); + HDF_LOGI("data_tpre_delay(0x30/40/50/60): 0x%x", tp->dataTpreDelay); + HDF_LOGI("clk_tlpx(0x22): 0x%x", tp->clkTlpx); + HDF_LOGI("clk_tclk_prepare(0x23): 0x%x", tp->clkTclkPrepare); + HDF_LOGI("clk_tclk_zero(0x24): 0x%x", tp->clkTclkZero); + HDF_LOGI("clk_tclk_trail(0x25): 0x%x", tp->clkTclkTrail); + HDF_LOGI("data_tlpx(0x32/42/52/62): 0x%x", tp->dataTlpx); + HDF_LOGI("data_ths_prepare(0x33/43/53/63): 0x%x", tp->dataThsPrepare); + HDF_LOGI("data_ths_zero(0x34/44/54/64): 0x%x", tp->dataThsZero); + HDF_LOGI("data_ths_trail(0x35/45/55/65): 0x%x", tp->dataThsTrail); + HDF_LOGI("=========================\n"); +#endif +} + +/* + * set data lp2hs,hs2lp time + * set clk lp2hs,hs2lp time + * unit: hsclk + */ +static void MipiTxDrvSetPhyHsLpSwitchTime(const MipiTxPhyTimingParamTag *tp) +{ + /* data lp2hs,hs2lp time */ + g_mipiTxRegsVa->PHY_TMR_CFG.u32 = ((tp->dataThsTrail - 1) << 16) + /* 16 set register */ + tp->dataTpreDelay + tp->dataTlpx + tp->dataThsPrepare + tp->dataThsZero + 7; /* 7 from algorithm */ + /* clk lp2hs,hs2lp time */ + g_mipiTxRegsVa->PHY_TMR_LPCLK_CFG.u32 = ((31 + tp->dataThsTrail) << 16) + /* 31 from algorithm, 16 set register */ + tp->clkTlpx + tp->clkTclkPrepare + tp->clkTclkZero + 6; /* 6 from algorithm */ +#ifdef MIPI_TX_DEBUG + HDF_LOGI("PHY_TMR_CFG(0x9C): 0x%x", g_mipiTxRegsVa->PHY_TMR_CFG.u32); + HDF_LOGI("PHY_TMR_LPCLK_CFG(0x98): 0x%x", g_mipiTxRegsVa->PHY_TMR_LPCLK_CFG.u32); +#endif +} + +void MipiTxDrvSetPhyCfg(const ComboDevCfgTag *cfg) +{ + if (cfg == NULL) { + return; + } + MipiTxPhyTimingParamTag tp = {0}; + + /* set phy pll parameters setx */ + MipiTxDrvSetPhyPllSetX(cfg->phyDataRate); + /* get global operation timing parameters */ + MipiTxDrvGetPhyTimingParam(&tp); + /* set global operation timing parameters */ + MipiTxDrvSetPhyTimingParam(&tp); + /* set hs switch to lp and lp switch to hs time */ + MipiTxDrvSetPhyHsLpSwitchTime(&tp); + /* edpi_cmd_size */ + g_mipiTxRegsVa->EDPI_CMD_SIZE.u32 = 0xF0; + /* phy enable */ + g_mipiTxRegsVa->PHY_RSTZ.u32 = 0xf; + if (cfg->outputMode == OUTPUT_MODE_CSI) { + if (cfg->outputFormat == OUT_FORMAT_YUV420_8_BIT_NORMAL) { + g_mipiTxRegsVa->DATATYPE0.u32 = 0x10218; + g_mipiTxRegsVa->CSI_CTRL.u32 = 0x1111; + } else if (cfg->outputFormat == OUT_FORMAT_YUV422_8_BIT) { + g_mipiTxRegsVa->DATATYPE0.u32 = 0x1021E; + g_mipiTxRegsVa->CSI_CTRL.u32 = 0x1111; + } + } else { + if (cfg->outputFormat == OUT_FORMAT_RGB_16_BIT) { + g_mipiTxRegsVa->DATATYPE0.u32 = 0x111213D; + g_mipiTxRegsVa->CSI_CTRL.u32 = 0x10100; + } else if (cfg->outputFormat == OUT_FORMAT_RGB_18_BIT) { + g_mipiTxRegsVa->DATATYPE0.u32 = 0x111213D; + g_mipiTxRegsVa->CSI_CTRL.u32 = 0x10100; + } else if (cfg->outputFormat == OUT_FORMAT_RGB_24_BIT) { + g_mipiTxRegsVa->DATATYPE0.u32 = 0x111213D; + g_mipiTxRegsVa->CSI_CTRL.u32 = 0x10100; + } + } + g_mipiTxRegsVa->PHY_RSTZ.u32 = 0XF; + OsalMSleep(1); + g_mipiTxRegsVa->LPCLK_CTRL.u32 = 0x0; +} + +void MipiTxDrvGetDevStatus(MipiTxDevPhyTag *phyCtx) +{ + if (phyCtx == NULL) { + return; + } + phyCtx->hactDet = g_mipiTxRegsVa->HORI0_DET.bits.hact_det; + phyCtx->hallDet = g_mipiTxRegsVa->HORI0_DET.bits.hline_det; + phyCtx->hbpDet = g_mipiTxRegsVa->HORI1_DET.bits.hbp_det; + phyCtx->hsaDet = g_mipiTxRegsVa->HORI1_DET.bits.hsa_det; + phyCtx->vactDet = g_mipiTxRegsVa->VERT_DET.bits.vact_det; + phyCtx->vallDet = g_mipiTxRegsVa->VERT_DET.bits.vall_det; + phyCtx->vsaDet = g_mipiTxRegsVa->VSA_DET.bits.vsa_det; +} + +static void SetOutputFormat(const ComboDevCfgTag *cfg) +{ + int colorCoding = 0; + + if (cfg->outputMode == OUTPUT_MODE_CSI) { + if (cfg->outputFormat == OUT_FORMAT_YUV420_8_BIT_NORMAL) { + colorCoding = 0xd; + } else if (cfg->outputFormat == OUT_FORMAT_YUV422_8_BIT) { + colorCoding = 0x1; + } + } else { + if (cfg->outputFormat == OUT_FORMAT_RGB_16_BIT) { + colorCoding = 0x0; + } else if (cfg->outputFormat == OUT_FORMAT_RGB_18_BIT) { + colorCoding = 0x3; + } else if (cfg->outputFormat == OUT_FORMAT_RGB_24_BIT) { + colorCoding = 0x5; + } + } + g_mipiTxRegsVa->COLOR_CODING.u32 = colorCoding; +#ifdef MIPI_TX_DEBUG + HDF_LOGI("SetOutputFormat: 0x%x", colorCoding); +#endif +} + +static void SetVideoModeCfg(const ComboDevCfgTag *cfg) +{ + int videoMode; + + if (cfg->videoMode == NON_BURST_MODE_SYNC_PULSES) { + videoMode = 0; + } else if (cfg->videoMode == NON_BURST_MODE_SYNC_EVENTS) { + videoMode = 1; + } else { + videoMode = 2; /* 2 register value */ + } + if ((cfg->outputMode == OUTPUT_MODE_CSI) || (cfg->outputMode == OUTPUT_MODE_DSI_CMD)) { + videoMode = 2; /* 2 register value */ + } + g_mipiTxRegsVa->VID_MODE_CFG.u32 = 0x3f00 + videoMode; +} + +static void SetTimingConfig(const ComboDevCfgTag *cfg) +{ + unsigned int hsa; + unsigned int hbp; + unsigned int hline; + + if (cfg->pixelClk == 0) { + HDF_LOGE("cfg->pixelClk is 0, illegal."); + return; + } + /* 125 from algorithm */ + hsa = g_actualPhyDataRate * cfg->syncInfo.vidHsaPixels * 125 / cfg->pixelClk; + /* 125 from algorithm */ + hbp = g_actualPhyDataRate * cfg->syncInfo.vidHbpPixels * 125 / cfg->pixelClk; + /* 125 from algorithm */ + hline = g_actualPhyDataRate * cfg->syncInfo.vidHlinePixels * 125 / cfg->pixelClk; + g_mipiTxRegsVa->VID_HSA_TIME.u32 = hsa; + g_mipiTxRegsVa->VID_HBP_TIME.u32 = hbp; + g_mipiTxRegsVa->VID_HLINE_TIME.u32 = hline; + g_mipiTxRegsVa->VID_VSA_LINES.u32 = cfg->syncInfo.vidVsaLines; + g_mipiTxRegsVa->VID_VBP_LINES.u32 = cfg->syncInfo.vidVbpLines; + g_mipiTxRegsVa->VID_VFP_LINES.u32 = cfg->syncInfo.vidVfpLines; + g_mipiTxRegsVa->VID_VACTIVE_LINES.u32 = cfg->syncInfo.vidActiveLines; +#ifdef MIPI_TX_DEBUG + HDF_LOGI("VID_HSA_TIME(0x48): 0x%x", hsa); + HDF_LOGI("VID_HBP_TIME(0x4c): 0x%x", hbp); + HDF_LOGI("VID_HLINE_TIME(0x50): 0x%x", hline); + HDF_LOGI("VID_VSA_LINES(0x54): 0x%x", cfg->syncInfo.vidVsaLines); + HDF_LOGI("VID_VBP_LINES(0x58): 0x%x", cfg->syncInfo.vidVbpLines); + HDF_LOGI("VID_VFP_LINES(0x5c): 0x%x", cfg->syncInfo.vidVfpLines); + HDF_LOGI("VID_VACTIVE_LINES(0x60): 0x%x\n", cfg->syncInfo.vidActiveLines); +#endif +} + +void SetLaneConfig(const short laneId[], int len) +{ + int num = 0; + int i; + + for (i = 0; i < len; i++) { + if (-1 != laneId[i]) { + num++; + } + } + g_mipiTxRegsVa->PHY_IF_CFG.u32 = num - 1; +} + +void MipiTxDrvSetClkMgrCfg(void) +{ + if (g_actualPhyDataRate / 160 < 2) { /* 160 cal div, should not smaller than 2 */ + g_mipiTxRegsVa->CLKMGR_CFG.u32 = 0x102; + } else { + g_mipiTxRegsVa->CLKMGR_CFG.u32 = 0x100 + (g_actualPhyDataRate + 159) / 160; /* 159 160 cal div */ + } +} + +void MipiTxDrvSetControllerCfg(const ComboDevCfgTag *cfg) +{ + if (cfg == NULL) { + return; + } + /* disable input */ + g_mipiTxRegsVa->OPERATION_MODE.u32 = 0x0; + /* vc_id */ + g_mipiTxRegsVa->VCID.u32 = 0x0; + /* output format,color coding */ + SetOutputFormat(cfg); + /* txescclk,timeout */ + g_actualPhyDataRate = ((cfg->phyDataRate + MIPI_TX_REF_CLK - 1) / MIPI_TX_REF_CLK) * MIPI_TX_REF_CLK; + MipiTxDrvSetClkMgrCfg(); + /* cmd transmission mode */ + g_mipiTxRegsVa->CMD_MODE_CFG.u32 = 0xffffff00; + /* crc,ecc,eotp tran */ + g_mipiTxRegsVa->PCKHDL_CFG.u32 = 0x1c; + /* gen_vcid_rx */ + g_mipiTxRegsVa->GEN_VCID.u32 = 0x0; + /* mode config */ + g_mipiTxRegsVa->MODE_CFG.u32 = 0x1; + /* video mode cfg */ + SetVideoModeCfg(cfg); + if ((cfg->outputMode == OUTPUT_MODE_DSI_VIDEO) || (cfg->outputMode == OUTPUT_MODE_CSI)) { + g_mipiTxRegsVa->VID_PKT_SIZE.u32 = cfg->syncInfo.vidPktSize; + } else { + g_mipiTxRegsVa->EDPI_CMD_SIZE.u32 = cfg->syncInfo.edpiCmdSize; + } + /* num_chunks/null_size */ + g_mipiTxRegsVa->VID_NUM_CHUNKS.u32 = 0x0; + g_mipiTxRegsVa->VID_NULL_SIZE.u32 = 0x0; + /* timing config */ + SetTimingConfig(cfg); + /* invact,outvact time */ + g_mipiTxRegsVa->LP_CMD_TIM.u32 = 0x0; + g_mipiTxRegsVa->PHY_TMR_CFG.u32 = 0x9002D; + g_mipiTxRegsVa->PHY_TMR_LPCLK_CFG.u32 = 0x29002E; + g_mipiTxRegsVa->EDPI_CMD_SIZE.u32 = 0xF0; + /* lp_wr_to_cnt */ + g_mipiTxRegsVa->LP_WR_TO_CNT.u32 = 0x0; + /* bta_to_cnt */ + g_mipiTxRegsVa->BTA_TO_CNT.u32 = 0x0; + /* lanes */ + SetLaneConfig(cfg->laneId, LANE_MAX_NUM); + /* phy_tx requlpsclk */ + g_mipiTxRegsVa->PHY_ULPS_CTRL.u32 = 0x0; + /* int msk0 */ + g_mipiTxRegsVa->INT_MSK0.u32 = 0x0; + /* pwr_up unreset */ + g_mipiTxRegsVa->PWR_UP.u32 = 0x0; + g_mipiTxRegsVa->PWR_UP.u32 = 0xf; +} + +static int MipiTxWaitCmdFifoEmpty(void) +{ + U_CMD_PKT_STATUS cmdPktStatus; + unsigned int waitCnt; + + waitCnt = 0; + do { + cmdPktStatus.u32 = g_mipiTxRegsVa->CMD_PKT_STATUS.u32; + waitCnt++; + OsalUDelay(1); + if (waitCnt > MIPI_TX_READ_TIMEOUT_CNT) { + HDF_LOGW("timeout when send cmd buffer"); + return -1; + } + } while (cmdPktStatus.bits.gen_cmd_empty == 0); + return 0; +} + +static int MipiTxWaitWriteFifoEmpty(void) +{ + U_CMD_PKT_STATUS cmdPktStatus; + unsigned int waitCnt; + + waitCnt = 0; + do { + cmdPktStatus.u32 = g_mipiTxRegsVa->CMD_PKT_STATUS.u32; + waitCnt++; + OsalUDelay(1); + if (waitCnt > MIPI_TX_READ_TIMEOUT_CNT) { + HDF_LOGW("timeout when send data buffer"); + return -1; + } + } while (cmdPktStatus.bits.gen_pld_w_empty == 0); + return 0; +} + +static int MipiTxWaitWriteFifoNotFull(void) +{ + U_CMD_PKT_STATUS cmdPktStatus; + unsigned int waitCnt; + + waitCnt = 0; + do { + cmdPktStatus.u32 = g_mipiTxRegsVa->CMD_PKT_STATUS.u32; + if (waitCnt > 0) { + OsalUDelay(1); + HDF_LOGW("write fifo full happened wait count = %u", waitCnt); + } + if (waitCnt > MIPI_TX_READ_TIMEOUT_CNT) { + HDF_LOGW("timeout when wait write fifo not full buffer"); + return -1; + } + waitCnt++; + } while (cmdPktStatus.bits.gen_pld_w_full == 1); + return 0; +} + +/* + * set payloads data by writing register + * each 4 bytes in cmd corresponds to one register + */ +static void MipiTxDrvSetPayloadData(const unsigned char *cmd, unsigned short cmdSize) +{ + U_GEN_PLD_DATA genPldData; + int i, j; + + genPldData.u32 = g_mipiTxRegsVa->GEN_PLD_DATA.u32; + + for (i = 0; i < (cmdSize / 4); i++) { /* 4 cmd once */ + genPldData.bits.gen_pld_b1 = cmd[i * 4]; /* 0 in 4 */ + genPldData.bits.gen_pld_b2 = cmd[i * 4 + 1]; /* 1 in 4 */ + genPldData.bits.gen_pld_b3 = cmd[i * 4 + 2]; /* 2 in 4 */ + genPldData.bits.gen_pld_b4 = cmd[i * 4 + 3]; /* 3 in 4 */ + MipiTxWaitWriteFifoNotFull(); + g_mipiTxRegsVa->GEN_PLD_DATA.u32 = genPldData.u32; + } + j = cmdSize % 4; /* remainder of 4 */ + if (j != 0) { + if (j > 0) { + genPldData.bits.gen_pld_b1 = cmd[i * 4]; /* 0 in 4 */ + } + if (j > 1) { + genPldData.bits.gen_pld_b2 = cmd[i * 4 + 1]; /* 1 in 4 */ + } + if (j > 2) { /* bigger than 2 */ + genPldData.bits.gen_pld_b3 = cmd[i * 4 + 2]; /* 2 in 4 */ + } + MipiTxWaitWriteFifoNotFull(); + g_mipiTxRegsVa->GEN_PLD_DATA.u32 = genPldData.u32; + } +#ifdef MIPI_TX_DEBUG + HDF_LOGI("\n=====set cmd======="); + HDF_LOGI("GEN_PLD_DATA(0x70): 0x%x\n", genPldData); +#endif +} + +int MipiTxDrvSetCmdInfo(const CmdInfoTag *cmdInfo) +{ + U_GEN_HDR genHdr; + unsigned char *cmd = NULL; + + if (cmdInfo == NULL) { + return -1; + } + genHdr.u32 = g_mipiTxRegsVa->GEN_HDR.u32; + if (cmdInfo->cmd != NULL) { + if (cmdInfo->cmdSize > 200 || cmdInfo->cmdSize == 0) { /* 200 is max cmd size */ + HDF_LOGE("set cmd size illegal, size =%u", cmdInfo->cmdSize); + return -1; + } + cmd = (unsigned char *)OsalMemCalloc(cmdInfo->cmdSize); + if (cmd == NULL) { + HDF_LOGE("kmalloc fail,please check,need %u bytes", cmdInfo->cmdSize); + return -1; + } + if (access_ok(VERIFY_READ, cmdInfo->cmd, cmdInfo->cmdSize)) { /* user space */ + if (copy_from_user(cmd, cmdInfo->cmd, cmdInfo->cmdSize) != 0) { + OsalMemFree(cmd); + cmd = NULL; + HDF_LOGE("%s: copy_from_user fail", __func__); + return -1; + } + } else { /* kernel space */ + if (memcpy_s(cmd, cmdInfo->cmdSize, cmdInfo->cmd, cmdInfo->cmdSize) != EOK) { + OsalMemFree(cmd); + cmd = NULL; + HDF_LOGE("%s: memcpy_s fail", __func__); + return -1; + } + } + MipiTxDrvSetPayloadData(cmd, cmdInfo->cmdSize); + OsalMemFree(cmd); + cmd = NULL; + } + genHdr.bits.gen_dt = cmdInfo->dataType; + genHdr.bits.gen_wc_lsbyte = cmdInfo->cmdSize & 0xff; + genHdr.bits.gen_wc_msbyte = (cmdInfo->cmdSize & 0xff00) >> 8; /* height 8 bits */ + g_mipiTxRegsVa->GEN_HDR.u32 = genHdr.u32; + OsalUDelay(350); /* wait 350 us transfer end */ + MipiTxWaitCmdFifoEmpty(); + MipiTxWaitWriteFifoEmpty(); +#ifdef MIPI_TX_DEBUG + HDF_LOGI("\n=====set cmd======="); + HDF_LOGI("cmdInfo->cmdSize: 0x%x", cmdInfo->cmdSize); + HDF_LOGI("cmdInfo->dataType: 0x%x", cmdInfo->dataType); + HDF_LOGI("GEN_HDR(0x6C): 0x%x\n", genHdr); +#endif + return 0; +} + +static int MipiTxWaitReadFifoNotEmpty(void) +{ + U_INT_ST0 intSt0; + U_INT_ST1 intSt1; + unsigned int waitCnt; + U_CMD_PKT_STATUS cmdPktStatus; + + waitCnt = 0; + do { + intSt1.u32 = g_mipiTxRegsVa->INT_ST1.u32; + intSt0.u32 = g_mipiTxRegsVa->INT_ST0.u32; + if ((intSt1.u32 & 0x3e) != 0) { + HDF_LOGE("err happened when read data, int_st1 = 0x%x,int_st0 = %x", intSt1.u32, intSt0.u32); + return -1; + } + if (waitCnt > MIPI_TX_READ_TIMEOUT_CNT) { + HDF_LOGW("timeout when read data"); + return -1; + } + waitCnt++; + OsalUDelay(1); + cmdPktStatus.u32 = g_mipiTxRegsVa->CMD_PKT_STATUS.u32; + } while (cmdPktStatus.bits.gen_pld_r_empty == 0x1); + return 0; +} + +static int MipiTxWaitReadFifoEmpty(void) +{ + U_GEN_PLD_DATA pldData; + U_INT_ST1 intSt1; + unsigned int waitCnt; + + waitCnt = 0; + do { + intSt1.u32 = g_mipiTxRegsVa->INT_ST1.u32; + if ((intSt1.bits.gen_pld_rd_err) == 0x0) { + pldData.u32 = g_mipiTxRegsVa->GEN_PLD_DATA.u32; + } + waitCnt++; + OsalUDelay(1); + if (waitCnt > MIPI_TX_READ_TIMEOUT_CNT) { + HDF_LOGW("timeout when clear data buffer, the last read data is 0x%x", pldData.u32); + return -1; + } + } while ((intSt1.bits.gen_pld_rd_err) == 0x0); + return 0; +} + +static int MipiTxSendShortPacket(unsigned char virtualChannel, + short unsigned dataType, unsigned short dataParam) +{ + U_GEN_HDR genHdr; + + genHdr.bits.gen_vc = virtualChannel; + genHdr.bits.gen_dt = dataType; + genHdr.bits.gen_wc_lsbyte = (dataParam & 0xff); + genHdr.bits.gen_wc_msbyte = (dataParam & 0xff00) >> 8; /* height 8 bits */ + g_mipiTxRegsVa->GEN_HDR.u32 = genHdr.u32; + if (MipiTxWaitCmdFifoEmpty() != 0) { + return -1; + } + return 0; +} + +static int MipiTxGetReadFifoData(unsigned int getDataSize, unsigned char *dataBuf) +{ + U_GEN_PLD_DATA pldData; + unsigned int i, j; + + for (i = 0; i < getDataSize / 4; i++) { /* 4byte once */ + if (MipiTxWaitReadFifoNotEmpty() != 0) { + return -1; + } + pldData.u32 = g_mipiTxRegsVa->GEN_PLD_DATA.u32; + dataBuf[i * 4] = pldData.bits.gen_pld_b1; /* 0 in 4 */ + dataBuf[i * 4 + 1] = pldData.bits.gen_pld_b2; /* 1 in 4 */ + dataBuf[i * 4 + 2] = pldData.bits.gen_pld_b3; /* 2 in 4 */ + dataBuf[i * 4 + 3] = pldData.bits.gen_pld_b4; /* 3 in 4 */ + } + + j = getDataSize % 4; /* remainder of 4 */ + + if (j != 0) { + if (MipiTxWaitReadFifoNotEmpty() != 0) { + return -1; + } + pldData.u32 = g_mipiTxRegsVa->GEN_PLD_DATA.u32; + if (j > 0) { + dataBuf[i * 4] = pldData.bits.gen_pld_b1; /* 0 in 4 */ + } + if (j > 1) { + dataBuf[i * 4 + 1] = pldData.bits.gen_pld_b2; /* 1 in 4 */ + } + if (j > 2) { /* bigger than 2 */ + dataBuf[i * 4 + 2] = pldData.bits.gen_pld_b3; /* 2 in 4 */ + } + } + return 0; +} + +void MipiTxReset(void) +{ + g_mipiTxRegsVa->PWR_UP.u32 = 0x0; + g_mipiTxRegsVa->PHY_RSTZ.u32 = 0xd; + OsalUDelay(1); + g_mipiTxRegsVa->PWR_UP.u32 = 0x1; + g_mipiTxRegsVa->PHY_RSTZ.u32 = 0xf; + OsalUDelay(1); + return; +} + +int MipiTxDrvGetCmdInfo(GetCmdInfoTag *getCmdInfo) +{ + unsigned char *dataBuf = NULL; + + dataBuf = (unsigned char*)OsalMemAlloc(getCmdInfo->getDataSize); + if (dataBuf == NULL) { + return -1; + } + if (MipiTxWaitReadFifoEmpty() != 0) { + goto fail0; + } + if (MipiTxSendShortPacket(0, getCmdInfo->dataType, getCmdInfo->dataParam) != 0) { + goto fail0; + } + if (MipiTxGetReadFifoData(getCmdInfo->getDataSize, dataBuf) != 0) { + /* fail will block mipi data lane, so need reset */ + MipiTxReset(); + goto fail0; + } + if (access_ok(VERIFY_WRITE, getCmdInfo->getData, getCmdInfo->getDataSize)) { /* user space */ + if (copy_to_user(getCmdInfo->getData, dataBuf, getCmdInfo->getDataSize) != 0) { + HDF_LOGE("copy_to_user fail"); + } + } else { /* kernel space */ + if (memcpy_s(getCmdInfo->getData, getCmdInfo->getDataSize, dataBuf, getCmdInfo->getDataSize) != EOK) { + HDF_LOGE("memcpy_s fail"); + } + } + OsalMemFree(dataBuf); + dataBuf = NULL; + return 0; + +fail0: + OsalMemFree(dataBuf); + dataBuf = NULL; + return -1; +} + +void MipiTxDrvEnableInput(const OutPutModeTag outputMode) +{ + if ((outputMode == OUTPUT_MODE_DSI_VIDEO) || (outputMode == OUTPUT_MODE_CSI)) { + g_mipiTxRegsVa->MODE_CFG.u32 = 0x0; + } + if (outputMode == OUTPUT_MODE_DSI_CMD) { + g_mipiTxRegsVa->CMD_MODE_CFG.u32 = 0x0; + } + /* enable input */ + g_mipiTxRegsVa->OPERATION_MODE.u32 = 0x80150000; + g_mipiTxRegsVa->LPCLK_CTRL.u32 = 0x1; + MipiTxReset(); +} + +void MipiTxDrvDisableInput(void) +{ + /* disable input */ + g_mipiTxRegsVa->OPERATION_MODE.u32 = 0x0; + g_mipiTxRegsVa->CMD_MODE_CFG.u32 = 0xffffff00; + /* command mode */ + g_mipiTxRegsVa->MODE_CFG.u32 = 0x1; + g_mipiTxRegsVa->LPCLK_CTRL.u32 = 0x0; + MipiTxReset(); +} + +static int MipiTxDrvRegInit(void) +{ + if (!g_mipiTxRegsVa) { + g_mipiTxRegsVa = (MipiTxRegsTypeTag *)OsalIoRemap(MIPI_TX_REGS_ADDR, (unsigned int)MIPI_TX_REGS_SIZE); + if (g_mipiTxRegsVa == NULL) { + HDF_LOGE("remap mipi_tx reg addr fail"); + return -1; + } + g_regMapFlag = 1; + } + + return 0; +} + +static void MipiTxDrvRegExit(void) +{ + if (g_regMapFlag == 1) { + if (g_mipiTxRegsVa != NULL) { + OsalIoUnmap((void *)g_mipiTxRegsVa); + g_mipiTxRegsVa = NULL; + } + g_regMapFlag = 0; + } +} + +static void MipiTxDrvHwInit(int smooth) +{ + unsigned long mipiTxCrgAddr; + + mipiTxCrgAddr = (unsigned long)OsalIoRemap(MIPI_TX_CRG, (unsigned long)0x4); + /* mipi_tx gate clk enable */ + WriteReg32(mipiTxCrgAddr, 1, 0x1); + /* reset */ + if (smooth == FALSE) { + WriteReg32(mipiTxCrgAddr, 1 << 1, 0x1 << 1); + } + /* unreset */ + WriteReg32(mipiTxCrgAddr, 0 << 1, 0x1 << 1); + /* ref clk */ + WriteReg32(mipiTxCrgAddr, 1 << 2, 0x1 << 2); /* 2 clk bit */ + OsalIoUnmap((void *)mipiTxCrgAddr); +} + +int MipiTxDrvInit(int smooth) +{ + int ret; + + ret = MipiTxDrvRegInit(); + if (ret < 0) { + HDF_LOGE("MipiTxDrvRegInit fail!"); + return -1; + } + MipiTxDrvHwInit(smooth); + return 0; +} + +void MipiTxDrvExit(void) +{ + MipiTxDrvRegExit(); +} + +ComboDevCfgTag *GetDevCfg(struct MipiDsiCntlr *cntlr) +{ + static ComboDevCfgTag dev; + int i; + + if (cntlr == NULL) { + return NULL; + } + dev.devno = cntlr->devNo; + dev.outputMode = (OutPutModeTag)cntlr->mode; + dev.videoMode = (VideoModeTag)cntlr->burstMode; + dev.outputFormat = (OutputFormatTag)cntlr->format; + dev.syncInfo.vidPktSize = cntlr->timing.xPixels; + dev.syncInfo.vidHsaPixels = cntlr->timing.hsaPixels; + dev.syncInfo.vidHbpPixels = cntlr->timing.hbpPixels; + dev.syncInfo.vidHlinePixels = cntlr->timing.hlinePixels; + dev.syncInfo.vidVsaLines = cntlr->timing.vsaLines; + dev.syncInfo.vidVbpLines = cntlr->timing.vbpLines; + dev.syncInfo.vidVfpLines = cntlr->timing.vfpLines; + dev.syncInfo.vidActiveLines = cntlr->timing.ylines; + dev.syncInfo.edpiCmdSize = cntlr->timing.edpiCmdSize; + dev.phyDataRate = cntlr->phyDataRate; + dev.pixelClk = cntlr->pixelClk; + for (i = 0; i < LANE_MAX_NUM; i++) { + dev.laneId[i] = -1; /* -1 : not use */ + } + for (i = 0; i < cntlr->lane; i++) { + dev.laneId[i] = i; + } + return &dev; +} + +int32_t Hi35xxSetCntlrCfg(struct MipiDsiCntlr *cntlr) +{ + ComboDevCfgTag *dev = GetDevCfg(cntlr); + + if (dev == NULL) { + return -1; + } + return MipiTxSetComboDevCfg(dev); +} + +int32_t Hi35xxSetCmd(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd) +{ + CmdInfoTag cmdInfo; + + (void)cntlr; + if (cmd == NULL) { + return HDF_FAILURE; + } + cmdInfo.devno = 0; + if (cmd->dataLen > 2) { /* 2: use long data type */ + cmdInfo.cmdSize = cmd->dataLen; + cmdInfo.dataType = cmd->dataType; /* 0x29: long data type */ + cmdInfo.cmd = cmd->payload; + } else if (cmd->dataLen == 2) { /* 2: use short data type */ + uint16_t tmp = cmd->payload[1]; /* 3: payload */ + tmp = (tmp & 0x00ff) << 8; /* 0x00ff , 8: payload to high */ + tmp = 0xff00 & tmp; + tmp = tmp | cmd->payload[0]; /* 2: reg addr */ + cmdInfo.cmdSize = tmp; + cmdInfo.dataType = cmd->dataType; /* 0x23: short data type */ + cmdInfo.cmd = NULL; + } else if (cmd->dataLen == 1) { + cmdInfo.cmdSize = cmd->payload[0]; /* 2: reg addr */ + cmdInfo.dataType = cmd->dataType; /* 0x05: short data type */ + cmdInfo.cmd = NULL; + } else { + // error + return HDF_FAILURE; + } + return MipiTxSetCmd(&cmdInfo); +} + +int32_t Hi35xxGetCmd(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out) +{ + GetCmdInfoTag cmdInfo; + + (void)cntlr; + if (cmd == NULL || out == NULL) { + return HDF_FAILURE; + } + cmdInfo.devno = 0; + cmdInfo.dataType = cmd->dataType; + cmdInfo.dataParam = cmd->payload[0]; + cmdInfo.getDataSize = readLen; + cmdInfo.getData = out; + return MipiTxGetCmd(&cmdInfo); +} + +void Hi35xxToLp(struct MipiDsiCntlr *cntlr) +{ + (void)cntlr; + MipiTxDrvDisableInput(); +} + +void Hi35xxToHs(struct MipiDsiCntlr *cntlr) +{ + ComboDevCfgTag *dev = GetDevCfg(cntlr); + + if (dev == NULL) { + return; + } + MipiTxDrvEnableInput(dev->outputMode); +} + +static struct MipiDsiCntlr g_mipiTx = { + .devNo = 0, + .setCntlrCfg = Hi35xxSetCntlrCfg, + .setCmd = Hi35xxSetCmd, + .getCmd = Hi35xxGetCmd, + .toHs = Hi35xxToHs, + .toLp = Hi35xxToLp, +}; + +static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device) +{ + int32_t ret; + (void)device; + ret = MipiDsiRegisterCntlr(&g_mipiTx); + if (ret != HDF_SUCCESS) { + return ret; + } + HDF_LOGI("load mipi_tx driver 1212!"); + return MipiTxModuleInit(0); +} + +static void Hi35xxMipiTxRelease(struct HdfDeviceObject *device) +{ + (void)device; + return MipiTxModuleExit(); +} +struct HdfDriverEntry g_mipiTxDriverEntry = { + .moduleVersion = 1, + .Init = Hi35xxMipiTxInit, + .Release = Hi35xxMipiTxRelease, + .moduleName = "HDF_MIPI_TX", +}; +HDF_INIT(g_mipiTxDriverEntry); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ diff --git a/platform/mipi_dsi/mipi_tx_hi35xx.h b/platform/mipi_dsi/mipi_tx_hi35xx.h new file mode 100644 index 0000000..2611af1 --- /dev/null +++ b/platform/mipi_dsi/mipi_tx_hi35xx.h @@ -0,0 +1,119 @@ +/* + * mipi_tx_hi35xx.h + * + * hi35xx mipi_tx driver implement. + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef MIPI_TX_HI35XX_H +#define MIPI_TX_HI35XX_H + +#include "mipi_tx_dev.h" +/**************************************************************************** + * macro definition * + ****************************************************************************/ +#define MIPI_TX_REGS_ADDR 0x11270000 +#define MIPI_TX_REGS_SIZE 0x10000 + +#define MIPI_TX_IRQ 120 + +#define MIPI_TX_CRG 0x1201010C + +#define MIPI_TX_REF_CLK 27 + +#define TLPX 60 +#define TCLK_PREPARE 60 +#define TCLK_ZERO 250 +#define TCLK_TRAIL 80 +#define TPRE_DELAY 100 +#define THS_PREPARE 80 +#define THS_ZERO 180 +#define THS_TRAIL 110 + +/* phy addr */ +#define PLL_SET0 0x60 +#define PLL_SET1 0x64 +#define PLL_SET2 0x65 +#ifdef HI_FPGA +#define PLL_SET3 0x17 +#endif +#define PLL_SET4 0x66 +#define PLL_SET5 0x67 + +#define DATA0_TPRE_DELAY 0x28 +#define DATA1_TPRE_DELAY 0x38 +#define DATA2_TPRE_DELAY 0x48 +#define DATA3_TPRE_DELAY 0x58 + +#define CLK_TLPX 0x10 +#define CLK_TCLK_PREPARE 0x11 +#define CLK_TCLK_ZERO 0x12 +#define CLK_TCLK_TRAIL 0x13 + +#define DATA0_TLPX 0x20 +#define DATA0_THS_PREPARE 0x21 +#define DATA0_THS_ZERO 0x22 +#define DATA0_THS_TRAIL 0x23 +#define DATA1_TLPX 0x30 +#define DATA1_THS_PREPARE 0x31 +#define DATA1_THS_ZERO 0x32 +#define DATA1_THS_TRAIL 0x33 +#define DATA2_TLPX 0x40 +#define DATA2_THS_PREPARE 0x41 +#define DATA2_THS_ZERO 0x42 +#define DATA2_THS_TRAIL 0x43 +#define DATA3_TLPX 0x50 +#define DATA3_THS_PREPARE 0x51 +#define DATA3_THS_ZERO 0x52 +#define DATA3_THS_TRAIL 0x53 + +#define MIPI_TX_READ_TIMEOUT_CNT 1000 + +#define PREPARE_COMPENSATE 10 +#define ROUNDUP_VALUE 7999 +#define INNER_PEROID 8000 /* 8 * 1000 ,1000 is 1us = 1000ns, 8 is division ratio */ + +typedef struct { + unsigned char dataTpreDelay; + unsigned char clkTlpx; + unsigned char clkTclkPrepare; + unsigned char clkTclkZero; + unsigned char clkTclkTrail; + unsigned char dataTlpx; + unsigned char dataThsPrepare; + unsigned char dataThsZero; + unsigned char dataThsTrail; +} MipiTxPhyTimingParamTag; + +typedef struct { + unsigned int vallDet; + unsigned int vactDet; + unsigned int hallDet; + unsigned int hactDet; + unsigned int hbpDet; + unsigned int hsaDet; + unsigned int vsaDet; +} MipiTxDevPhyTag; + +void MipiTxDrvSetPhyCfg(const ComboDevCfgTag *cfg); +void MipiTxDrvGetDevStatus(MipiTxDevPhyTag *phyCtx); +void MipiTxDrvSetControllerCfg(const ComboDevCfgTag *cfg); +int MipiTxDrvSetCmdInfo(const CmdInfoTag *cmdInfo); +int MipiTxDrvGetCmdInfo(GetCmdInfoTag *getCmdInfo); +void MipiTxDrvEnableInput(const OutPutModeTag outputMode); +void MipiTxDrvDisableInput(void); +int MipiTxDrvInit(int smooth); +void MipiTxDrvExit(void); + +#endif /* MIPI_TX_HI35XX_H */ diff --git a/platform/mipi_dsi/mipi_tx_reg.h b/platform/mipi_dsi/mipi_tx_reg.h new file mode 100644 index 0000000..ea4a5d8 --- /dev/null +++ b/platform/mipi_dsi/mipi_tx_reg.h @@ -0,0 +1,928 @@ +/* + * mipi_tx_reg.h + * + * mipi tx register header file. + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef MIPI_TX_REG_H +#define MIPI_TX_REG_H + +/* Define the union U_PWR_UP */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int pwr_up : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PWR_UP; + +/* Define the union U_CLKMGR_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tx_esc_clk_division : 8; /* [7..0] */ + unsigned int reserved_0 : 8; /* [15..8] */ + unsigned int reserved_1 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_CLKMGR_CFG; + +/* Define the union U_VCID */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vcid : 2; /* [1..0] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VCID; + +/* Define the union U_COLOR_CODING */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int color_coding : 4; /* [3..0] */ + unsigned int reserved_0 : 4; /* [7..4] */ + unsigned int loosely18_en : 1; /* [8] */ + unsigned int reserved_1 : 23; /* [31..9] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_COLOR_CODING; + +/* Define the union U_LP_CMD_TIM */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int invact_lpcmd_time : 8; /* [7..0] */ + unsigned int reserved_0 : 8; /* [15..8] */ + unsigned int outvact_lpcmd_time : 8; /* [23..16] */ + unsigned int reserved_1 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_LP_CMD_TIM; + +/* Define the union U_PCKHDL_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int eotp_tx_en : 1; /* [0] */ + unsigned int eotp_rx_en : 1; /* [1] */ + unsigned int bta_en : 1; /* [2] */ + unsigned int ecc_rx_en : 1; /* [3] */ + unsigned int crc_rx_en : 1; /* [4] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PCKHDL_CFG; + +/* Define the union U_GEN_VCID */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int gen_vcid_rx : 2; /* [1..0] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_GEN_VCID; + +/* Define the union U_MODE_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cmd_video_mode : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_MODE_CFG; + +/* Define the union U_VID_MODE_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vid_mode_type : 2; /* [1..0] */ + unsigned int reserved_0 : 6; /* [7..2] */ + unsigned int lp_vsa_en : 1; /* [8] */ + unsigned int lp_vbp_en : 1; /* [9] */ + unsigned int lp_vfp_en : 1; /* [10] */ + unsigned int lp_vact_en : 1; /* [11] */ + unsigned int lp_hbp_en : 1; /* [12] */ + unsigned int lp_hfp_en : 1; /* [13] */ + unsigned int frame_bta_ack_en : 1; /* [14] */ + unsigned int lp_cmd_en : 1; /* [15] */ + unsigned int vpg_en : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int vpg_mode : 1; /* [20] */ + unsigned int reserved_2 : 3; /* [23..21] */ + unsigned int vpg_orientation : 1; /* [24] */ + unsigned int reserved_3 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_MODE_CFG; + +/* Define the union U_VID_PKT_SIZE */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vid_pkt_size : 14; /* [13..0] */ + unsigned int reserved_0 : 18; /* [31..14] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_PKT_SIZE; + +/* Define the union U_VID_NUM_CHUNKS */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vid_num_chunks : 13; /* [12..0] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_NUM_CHUNKS; + +/* Define the union U_VID_NULL_SIZE */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vid_null_size : 13; /* [12..0] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_NULL_SIZE; + +/* Define the union U_VID_HSA_TIME */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vid_hsa_time : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_HSA_TIME; + +/* Define the union U_VID_HBP_TIME */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vid_hbp_time : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_HBP_TIME; + +/* Define the union U_VID_HLINE_TIME */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vid_hline_time : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_HLINE_TIME; + +/* Define the union U_VID_VSA_LINES */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsa_lines : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_VSA_LINES; + +/* Define the union U_VID_VBP_LINES */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbp_lines : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_VBP_LINES; + +/* Define the union U_VID_VFP_LINES */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vfp_lines : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_VFP_LINES; + +/* Define the union U_VID_VACTIVE_LINES */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v_active_lines : 14; /* [13..0] */ + unsigned int reserved_0 : 18; /* [31..14] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VID_VACTIVE_LINES; + +/* Define the union U_EDPI_CMD_SIZE */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int edpi_allowed_cmd_size : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_EDPI_CMD_SIZE; + +/* Define the union U_CMD_MODE_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int reserved_1 : 1; /* [1] */ + unsigned int reserved_2 : 6; /* [7..2] */ + unsigned int gen_sw_0p_tx : 1; /* [8] */ + unsigned int gen_sw_1p_tx : 1; /* [9] */ + unsigned int gen_sw_2p_tx : 1; /* [10] */ + unsigned int gen_sr_0p_tx : 1; /* [11] */ + unsigned int gen_sr_1p_tx : 1; /* [12] */ + unsigned int gen_sr_2p_tx : 1; /* [13] */ + unsigned int gen_lw_tx : 1; /* [14] */ + unsigned int reserved_3 : 1; /* [15] */ + unsigned int dcs_sw_0p_tx : 1; /* [16] */ + unsigned int dcs_sw_1p_tx : 1; /* [17] */ + unsigned int dcs_sr_0p_tx : 1; /* [18] */ + unsigned int dcs_lw_tx : 1; /* [19] */ + unsigned int reserved_4 : 4; /* [23..20] */ + unsigned int max_rd_pkt_size : 1; /* [24] */ + unsigned int reserved_5 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_CMD_MODE_CFG; + +/* Define the union U_GEN_HDR */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int gen_dt : 6; /* [5..0] */ + unsigned int gen_vc : 2; /* [7..6] */ + unsigned int gen_wc_lsbyte : 8; /* [15..8] */ + unsigned int gen_wc_msbyte : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_GEN_HDR; + +/* Define the union U_GEN_PLD_DATA */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int gen_pld_b1 : 8; /* [7..0] */ + unsigned int gen_pld_b2 : 8; /* [15..8] */ + unsigned int gen_pld_b3 : 8; /* [23..16] */ + unsigned int gen_pld_b4 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_GEN_PLD_DATA; + +/* Define the union U_CMD_PKT_STATUS */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int gen_cmd_empty : 1; /* [0] */ + unsigned int gen_cmd_full : 1; /* [1] */ + unsigned int gen_pld_w_empty : 1; /* [2] */ + unsigned int gen_pld_w_full : 1; /* [3] */ + unsigned int gen_pld_r_empty : 1; /* [4] */ + unsigned int gen_pld_r_full : 1; /* [5] */ + unsigned int gen_rd_cmd_busy : 1; /* [6] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_CMD_PKT_STATUS; + +/* Define the union U_LP_WR_TO_CNT */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lp_wr_to_cnt : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_LP_WR_TO_CNT; + +/* Define the union U_BTA_TO_CNT */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bta_to_cnt : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_BTA_TO_CNT; + +/* Define the union U_LPCLK_CTRL */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_txrequestclkhs : 1; /* [0] */ + unsigned int auto_clklane_ctrl : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_LPCLK_CTRL; + +/* Define the union U_PHY_TMR_LPCLK_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_clklp2hs_time : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int phy_clkhs2lp_time : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_TMR_LPCLK_CFG; + +/* Define the union U_PHY_TMR_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_lp2hs_time : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int phy_hs2lp_time : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_TMR_CFG; + +/* Define the union U_PHY_RSTZ */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_shutdownz : 1; /* [0] */ + unsigned int phy_rstz : 1; /* [1] */ + unsigned int phy_enableclk : 1; /* [2] */ + unsigned int phy_forcepll : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_RSTZ; + +/* Define the union U_PHY_IF_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int n_lanes : 2; /* [1..0] */ + unsigned int reserved_0 : 6; /* [7..2] */ + unsigned int phy_stop_wait_time : 8; /* [15..8] */ + unsigned int reserved_1 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_IF_CFG; + +/* Define the union U_PHY_ULPS_CTRL */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_txrequlpsclk : 1; /* [0] */ + unsigned int phy_txexitulpsclk : 1; /* [1] */ + unsigned int phy_txrequlpslan : 1; /* [2] */ + unsigned int phy_txexitulpslan : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_ULPS_CTRL; + +/* Define the union U_PHY_STATUS */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_lock : 1; /* [0] */ + unsigned int phy_direction : 1; /* [1] */ + unsigned int phy_stopstateclklane : 1; /* [2] */ + unsigned int phy_ulpsactivenotclk : 1; /* [3] */ + unsigned int phy_stopstate0lane : 1; /* [4] */ + unsigned int phy_ulpsactivenot0lane : 1; /* [5] */ + unsigned int phy_rxulpsesc0lane : 1; /* [6] */ + unsigned int phy_stopstate1lane : 1; /* [7] */ + unsigned int phy_ulpsactivenot1lane : 1; /* [8] */ + unsigned int phy_stopstate2lane : 1; /* [9] */ + unsigned int phy_ulpsactivenot2lane : 1; /* [10] */ + unsigned int phy_stopstate3lane : 1; /* [11] */ + unsigned int phy_ulpsactivenot3lane : 1; /* [12] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_STATUS; + +/* Define the union U_PHY_TST_CTRL0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_testclr : 1; /* [0] */ + unsigned int phy_testclk : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_TST_CTRL0; + +/* Define the union U_PHY_TST_CTRL1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int phy_testdin : 8; /* [7..0] */ + unsigned int phy_testdout : 8; /* [15..8] */ + unsigned int phy_testen : 1; /* [16] */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_TST_CTRL1; + +/* Define the union U_INT_ST0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ack_with_err_0 : 1; /* [0] */ + unsigned int ack_with_err_1 : 1; /* [1] */ + unsigned int ack_with_err_2 : 1; /* [2] */ + unsigned int ack_with_err_3 : 1; /* [3] */ + unsigned int ack_with_err_4 : 1; /* [4] */ + unsigned int ack_with_err_5 : 1; /* [5] */ + unsigned int ack_with_err_6 : 1; /* [6] */ + unsigned int ack_with_err_7 : 1; /* [7] */ + unsigned int ack_with_err_8 : 1; /* [8] */ + unsigned int ack_with_err_9 : 1; /* [9] */ + unsigned int ack_with_err_10 : 1; /* [10] */ + unsigned int ack_with_err_11 : 1; /* [11] */ + unsigned int ack_with_err_12 : 1; /* [12] */ + unsigned int ack_with_err_13 : 1; /* [13] */ + unsigned int ack_with_err_14 : 1; /* [14] */ + unsigned int ack_with_err_15 : 1; /* [15] */ + unsigned int dphy_errors_0 : 1; /* [16] */ + unsigned int dphy_errors_1 : 1; /* [17] */ + unsigned int dphy_errors_2 : 1; /* [18] */ + unsigned int dphy_errors_3 : 1; /* [19] */ + unsigned int dphy_errors_4 : 1; /* [20] */ + unsigned int reserved_0 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_INT_ST0; + +/* Define the union U_INT_ST1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int to_hs_tx : 1; /* [0] */ + unsigned int to_lp_rx : 1; /* [1] */ + unsigned int ecc_single_err : 1; /* [2] */ + unsigned int ecc_multi_err : 1; /* [3] */ + unsigned int crc_err : 1; /* [4] */ + unsigned int pkt_size_err : 1; /* [5] */ + unsigned int eopt_err : 1; /* [6] */ + unsigned int dpi_pld_wr_err : 1; /* [7] */ + unsigned int gen_cmd_wr_err : 1; /* [8] */ + unsigned int gen_pld_wr_err : 1; /* [9] */ + unsigned int gen_pld_send_err : 1; /* [10] */ + unsigned int gen_pld_rd_err : 1; /* [11] */ + unsigned int gen_pld_recev_err : 1; /* [12] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int vsstart : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int rxtrigger_0 : 1; /* [20] */ + unsigned int rxtrigger_1 : 1; /* [21] */ + unsigned int rxtrigger_2 : 1; /* [22] */ + unsigned int rxtrigger_3 : 1; /* [23] */ + unsigned int hss_abnormal : 1; /* [24] */ + unsigned int reserved_2 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_INT_ST1; + +/* Define the union U_INT_MSK0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mask_ack_with_err_0 : 1; /* [0] */ + unsigned int mask_ack_with_err_1 : 1; /* [1] */ + unsigned int mask_ack_with_err_2 : 1; /* [2] */ + unsigned int mask_ack_with_err_3 : 1; /* [3] */ + unsigned int mask_ack_with_err_4 : 1; /* [4] */ + unsigned int mask_ack_with_err_5 : 1; /* [5] */ + unsigned int mask_ack_with_err_6 : 1; /* [6] */ + unsigned int mask_ack_with_err_7 : 1; /* [7] */ + unsigned int mask_ack_with_err_8 : 1; /* [8] */ + unsigned int mask_ack_with_err_9 : 1; /* [9] */ + unsigned int mask_ack_with_err_10 : 1; /* [10] */ + unsigned int mask_ack_with_err_11 : 1; /* [11] */ + unsigned int mask_ack_with_err_12 : 1; /* [12] */ + unsigned int mask_ack_with_err_13 : 1; /* [13] */ + unsigned int mask_ack_with_err_14 : 1; /* [14] */ + unsigned int mask_ack_with_err_15 : 1; /* [15] */ + unsigned int mask_dphy_errors_0 : 1; /* [16] */ + unsigned int mask_dphy_errors_1 : 1; /* [17] */ + unsigned int mask_dphy_errors_2 : 1; /* [18] */ + unsigned int mask_dphy_errors_3 : 1; /* [19] */ + unsigned int mask_dphy_errors_4 : 1; /* [20] */ + unsigned int reserved_0 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_INT_MSK0; + +/* Define the union U_INT_MSK1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mask_to_hs_tx : 1; /* [0] */ + unsigned int mask_to_lp_rx : 1; /* [1] */ + unsigned int mask_ecc_single_err : 1; /* [2] */ + unsigned int mask_ecc_multi_err : 1; /* [3] */ + unsigned int mask_crc_err : 1; /* [4] */ + unsigned int mask_pkt_size_err : 1; /* [5] */ + unsigned int mask_eopt_err : 1; /* [6] */ + unsigned int mask_dpi_pld_wr_err : 1; /* [7] */ + unsigned int mask_gen_cmd_wr_err : 1; /* [8] */ + unsigned int mask_gen_pld_wr_err : 1; /* [9] */ + unsigned int mask_gen_pld_send_err : 1; /* [10] */ + unsigned int mask_gen_pld_rd_err : 1; /* [11] */ + unsigned int mask_gen_pld_recev_err : 1; /* [12] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int mask_vsstart : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int mask_trigger_0 : 1; /* [20] */ + unsigned int mask_trigger_1 : 1; /* [21] */ + unsigned int mask_trigger_2 : 1; /* [22] */ + unsigned int mask_trigger_3 : 1; /* [23] */ + unsigned int mask_hss_abnormal : 1; /* [24] */ + unsigned int reserved_2 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_INT_MSK1; + +/* Define the union U_PHY_CAL */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int txskewcalhs : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_PHY_CAL; + +/* Define the union U_INT_FORCE1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int reserved_1 : 1; /* [1] */ + unsigned int reserved_2 : 1; /* [2] */ + unsigned int reserved_3 : 1; /* [3] */ + unsigned int reserved_4 : 1; /* [4] */ + unsigned int reserved_5 : 1; /* [5] */ + unsigned int reserved_6 : 1; /* [6] */ + unsigned int reserved_7 : 1; /* [7] */ + unsigned int reserved_8 : 1; /* [8] */ + unsigned int reserved_9 : 1; /* [9] */ + unsigned int reserved_10 : 1; /* [10] */ + unsigned int reserved_11 : 1; /* [11] */ + unsigned int reserved_12 : 1; /* [12] */ + unsigned int reserved_13 : 3; /* [15..13] */ + unsigned int reserved_14 : 1; /* [16] */ + unsigned int reserved_15 : 3; /* [19..17] */ + unsigned int reserved_16 : 1; /* [20] */ + unsigned int reserved_17 : 1; /* [21] */ + unsigned int reserved_18 : 1; /* [22] */ + unsigned int reserved_19 : 1; /* [23] */ + unsigned int reserved_20 : 1; /* [24] */ + unsigned int reserved_21 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_INT_FORCE1; + +/* Define the union U_OPERATION_MODE */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int mem_ck_en : 1; /* [1] */ + unsigned int reserved_1 : 2; /* [3..2] */ + unsigned int reserved_2 : 1; /* [4] */ + unsigned int init_skew_en : 1; /* [5] */ + unsigned int period_skew_en : 1; /* [6] */ + unsigned int reserved_3 : 1; /* [7] */ + unsigned int reserved_4 : 1; /* [8] */ + unsigned int reserved_5 : 1; /* [9] */ + unsigned int reserved_6 : 1; /* [10] */ + unsigned int reserved_7 : 1; /* [11] */ + unsigned int reserved_8 : 1; /* [12] */ + unsigned int reserved_9 : 1; /* [13] */ + unsigned int reserved_10 : 1; /* [14] */ + unsigned int reserved_11 : 1; /* [15] */ + unsigned int read_empty_vsync_en : 1; /* [16] */ + unsigned int reserved_12 : 1; /* [17] */ + unsigned int buf_clr_en : 1; /* [18] */ + unsigned int reserved_13 : 1; /* [19] */ + unsigned int hss_abnormal_rst : 1; /* [20] */ + unsigned int reserved_14 : 3; /* [23..21] */ + unsigned int reserved_15 : 1; /* [24] */ + unsigned int reserved_16 : 1; /* [25] */ + unsigned int reserved_17 : 1; /* [26] */ + unsigned int reserved_18 : 1; /* [27] */ + unsigned int reserved_19 : 3; /* [30..28] */ + unsigned int input_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_OPERATION_MODE; + +/* Define the union U_VERT_DET */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vact_det : 16; /* [15..0] */ + unsigned int vall_det : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VERT_DET; + +/* Define the union U_HORI0_DET */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hact_det : 16; /* [15..0] */ + unsigned int hline_det : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_HORI0_DET; + +/* Define the union U_HORI1_DET */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsa_det : 16; /* [15..0] */ + unsigned int hbp_det : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_HORI1_DET; + +/* Define the union U_VSA_DET */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsa_det : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_VSA_DET; + +/* Define the union U_V_H_SEND */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int h_send : 16; /* [15..0] */ + unsigned int v_send : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_V_H_SEND; + +/* Define the union U_DATATYPE0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 6; /* [5..0] */ + unsigned int reserved_1 : 2; /* [7..6] */ + unsigned int dt_hss : 6; /* [13..8] */ + unsigned int reserved_2 : 2; /* [15..14] */ + unsigned int dt_vse : 6; /* [21..16] */ + unsigned int reserved_3 : 2; /* [23..22] */ + unsigned int dt_vss : 6; /* [29..24] */ + unsigned int reserved_4 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_DATATYPE0; + +/* Define the union U_CSI_CTRL */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int csi_en : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int reserved_1 : 1; /* [4] */ + unsigned int reserved_2 : 3; /* [7..5] */ + unsigned int reserved_3 : 1; /* [8] */ + unsigned int reserved_4 : 3; /* [11..9] */ + unsigned int reserved_5 : 1; /* [12] */ + unsigned int reserved_6 : 3; /* [15..13] */ + unsigned int reserved_7 : 1; /* [16] */ + unsigned int reserved_8 : 15; /* [31..17] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_CSI_CTRL; + +/* Define the union U_SKEW_BEGIN */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int skew_begin : 32; /* [31..0] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_SKEW_BEGIN; +/* Define the union U_SKEW_END */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int skew_end : 32; /* [31..0] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_SKEW_END; +/* Define the union U_LANE_ID */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lane0_id : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int lane1_id : 2; /* [5..4] */ + unsigned int reserved_1 : 2; /* [7..6] */ + unsigned int lane2_id : 2; /* [9..8] */ + unsigned int reserved_2 : 2; /* [11..10] */ + unsigned int lane3_id : 2; /* [13..12] */ + unsigned int reserved_3 : 18; /* [31..14] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} U_LANE_ID; + + +/* Define the global struct */ +typedef struct { + unsigned int reserved_0; /* 0x0 */ + U_PWR_UP PWR_UP; /* 0x4 */ + U_CLKMGR_CFG CLKMGR_CFG; /* 0x8 */ + U_VCID VCID; /* 0xc */ + U_COLOR_CODING COLOR_CODING; /* 0x10 */ + unsigned int reserved_1; /* 0x14 */ + U_LP_CMD_TIM LP_CMD_TIM; /* 0x18 */ + unsigned int reserved_2[4]; /* 0x1c~0x28 */ + U_PCKHDL_CFG PCKHDL_CFG; /* 0x2c */ + U_GEN_VCID GEN_VCID; /* 0x30 */ + U_MODE_CFG MODE_CFG; /* 0x34 */ + U_VID_MODE_CFG VID_MODE_CFG; /* 0x38 */ + U_VID_PKT_SIZE VID_PKT_SIZE; /* 0x3c */ + U_VID_NUM_CHUNKS VID_NUM_CHUNKS; /* 0x40 */ + U_VID_NULL_SIZE VID_NULL_SIZE; /* 0x44 */ + U_VID_HSA_TIME VID_HSA_TIME; /* 0x48 */ + U_VID_HBP_TIME VID_HBP_TIME; /* 0x4c */ + U_VID_HLINE_TIME VID_HLINE_TIME; /* 0x50 */ + U_VID_VSA_LINES VID_VSA_LINES; /* 0x54 */ + U_VID_VBP_LINES VID_VBP_LINES; /* 0x58 */ + U_VID_VFP_LINES VID_VFP_LINES; /* 0x5c */ + U_VID_VACTIVE_LINES VID_VACTIVE_LINES; /* 0x60 */ + U_EDPI_CMD_SIZE EDPI_CMD_SIZE; /* 0x64 */ + U_CMD_MODE_CFG CMD_MODE_CFG; /* 0x68 */ + U_GEN_HDR GEN_HDR; /* 0x6c */ + U_GEN_PLD_DATA GEN_PLD_DATA; /* 0x70 */ + U_CMD_PKT_STATUS CMD_PKT_STATUS; /* 0x74 */ + unsigned int reserved_3[4]; /* 0x78~0x84 */ + U_LP_WR_TO_CNT LP_WR_TO_CNT; /* 0x88 */ + U_BTA_TO_CNT BTA_TO_CNT; /* 0x8c */ + unsigned int reserved_4; /* 0x90 */ + U_LPCLK_CTRL LPCLK_CTRL; /* 0x94 */ + U_PHY_TMR_LPCLK_CFG PHY_TMR_LPCLK_CFG; /* 0x98 */ + U_PHY_TMR_CFG PHY_TMR_CFG; /* 0x9c */ + U_PHY_RSTZ PHY_RSTZ; /* 0xa0 */ + U_PHY_IF_CFG PHY_IF_CFG; /* 0xa4 */ + U_PHY_ULPS_CTRL PHY_ULPS_CTRL; /* 0xa8 */ + unsigned int reserved_5; /* 0xac */ + U_PHY_STATUS PHY_STATUS; /* 0xb0 */ + U_PHY_TST_CTRL0 PHY_TST_CTRL0; /* 0xb4 */ + U_PHY_TST_CTRL1 PHY_TST_CTRL1; /* 0xb8 */ + U_INT_ST0 INT_ST0; /* 0xbc */ + U_INT_ST1 INT_ST1; /* 0xc0 */ + U_INT_MSK0 INT_MSK0; /* 0xc4 */ + U_INT_MSK1 INT_MSK1; /* 0xc8 */ + unsigned int reserved_6[79]; /* 0xcc~0x204 */ + U_OPERATION_MODE OPERATION_MODE; /* 0x208 */ + unsigned int reserved_8[2]; /* 0x20c~0x210 */ + volatile U_VERT_DET VERT_DET; /* 0x214 */ + volatile U_HORI0_DET HORI0_DET; /* 0x218 */ + volatile U_HORI1_DET HORI1_DET; /* 0x21c */ + volatile U_VSA_DET VSA_DET; /* 0x220 */ + U_V_H_SEND V_H_SEND; /* 0x224 */ + unsigned int reserved_9[2]; /* 0x228~0x22c */ + U_DATATYPE0 DATATYPE0; /* 0x230 */ + unsigned int reserved_10; /* 0x234 */ + U_CSI_CTRL CSI_CTRL; /* 0x238 */ + unsigned int reserved_11[6]; /* 0x23c~0x250 */ +} MipiTxRegsTypeTag; + +#endif /* __MIPI_TX_REG_H__ */ diff --git a/platform/platform.mk b/platform/platform.mk index b68803e..f822582 100644 --- a/platform/platform.mk +++ b/platform/platform.mk @@ -13,7 +13,6 @@ # HDF_PLATFORM_FRAMEWORKS_ROOT = ../../../../../framework/support/platform -HDF_PLATFORM_VENDOR_ROOT = ../../../../../../device/hisilicon/drivers/huawei_proprietary ccflags-$(CONFIG_DRIVERS_HDF_PLATFORM) += -Idrivers/hdf/framework/include/platform \ -Idrivers/hdf/framework/support/platform/include \ -Iinclude/hdf \ @@ -31,4 +30,4 @@ ccflags-$(CONFIG_DRIVERS_HDF_PLATFORM) += -Idrivers/hdf/framework/include/platfo -Idrivers/hdf/framework/core/common/include/host \ -Idrivers/hdf/framework/ability/sbuf/include \ -Idrivers/hdf/framework/utils/include \ - -I../../../../third_party/bounds_checking_function/include + -Iinclude/../../../../../../third_party/bounds_checking_function/include diff --git a/platform/pwm/Makefile b/platform/pwm/Makefile index 1da58e2..a09cbc0 100644 --- a/platform/pwm/Makefile +++ b/platform/pwm/Makefile @@ -11,5 +11,8 @@ # GNU General Public License for more details. # # +include drivers/hdf/khdf/platform/platform.mk -obj-y += adapter/ +obj-$(CONFIG_DRIVERS_HDF_PLATFORM_PWM) += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/pwm_core.o \ + pwm_adapter.o +obj-$(CONFIG_PWM_HI35XX) += pwm_hi35xx_linux.o diff --git a/platform/pwm/adapter/Makefile b/platform/pwm/adapter/Makefile deleted file mode 100644 index af5c85d..0000000 --- a/platform/pwm/adapter/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2020-2021 Huawei Device Co., Ltd. -# -# This software is licensed under the terms of the GNU General Public -# License version 2, as published by the Free Software Foundation, and -# may be copied, distributed, and modified under those terms. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# - -include drivers/hdf/khdf/platform/platform.mk - -obj-$(CONFIG_DRIVERS_HDF_PLATFORM_PWM) += ../$(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/pwm_core.o \ - pwm_adapter.o diff --git a/platform/pwm/driver/Kconfig b/platform/pwm/driver/Kconfig deleted file mode 100644 index eb7e469..0000000 --- a/platform/pwm/driver/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -config PWM_HI35XX - bool "hi35xx pwm driver" - depends on PWM - help - Answer Y to enable hi35xx pwm driver. diff --git a/platform/pwm/driver/Makefile b/platform/pwm/driver/Makefile deleted file mode 100644 index 3dc104e..0000000 --- a/platform/pwm/driver/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2020-2021 Huawei Device Co., Ltd. -# -# This software is licensed under the terms of the GNU General Public -# License version 2, as published by the Free Software Foundation, and -# may be copied, distributed, and modified under those terms. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# - -include drivers/hdf/khdf/platform/platform.mk - -obj-$(CONFIG_PWM_HI35XX) += ../$(HDF_PLATFORM_VENDOR_ROOT)/pwm/pwm_hi35xx_linux.o diff --git a/platform/pwm/adapter/pwm_adapter.c b/platform/pwm/pwm_adapter.c similarity index 100% rename from platform/pwm/adapter/pwm_adapter.c rename to platform/pwm/pwm_adapter.c diff --git a/platform/pwm/pwm_hi35xx.h b/platform/pwm/pwm_hi35xx.h new file mode 100644 index 0000000..ecdb5a7 --- /dev/null +++ b/platform/pwm/pwm_hi35xx.h @@ -0,0 +1,112 @@ +/* + * pwm_hi35xx.h + * + * hi35xx pwm driver implement. + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef PWM_HI35XX_H +#define PWM_HI35XX_H + +#include "hdf_base.h" + +#define PWM_CLK_HZ 3000000 // 3MHz +#define PWM_CLK_PERIOD 333 // 333ns + +#define PWM_MAX_HZ 1500000 // 1.5MHz +#define PWM_MIN_PERIOD 666 // 666ns + +#define PWM_MIN_HZ 0.045 // 0.045Hz +#define PWM_MAX_PERIOD 22222222222 // 22222222222ns > 4294967295ns (UINT32_MAX) + +#define PWM_ENABLE 1 +#define PWM_DISABLE 0 + +#define PWM_INV_OFFSET 1 +#define PWM_KEEP_OFFSET 2 + +#define PWM_DEFAULT_PERIOD 0x018F +#define PWM_DEFAULT_POLARITY 0 +#define PWM_DEFAULT_DUTY_CYCLE 0x00C7 + +struct HiPwmRegs { + volatile uint32_t cfg0; + volatile uint32_t cfg1; + volatile uint32_t cfg2; + volatile uint32_t ctrl; + volatile uint32_t state0; + volatile uint32_t state1; + volatile uint32_t state2; +}; + +static inline void HiPwmDisable(struct HiPwmRegs *reg) +{ + if (reg == NULL) { + return; + } + reg->ctrl = PWM_DISABLE; +} + +static inline void HiPwmAlwaysOutput(struct HiPwmRegs *reg) +{ + if (reg == NULL) { + return; + } + /* keep the pwm always output */ + reg->ctrl |= ((1 << PWM_KEEP_OFFSET) | PWM_ENABLE); +} + +static inline void HiPwmOutputNumberSquareWaves(struct HiPwmRegs *reg, uint32_t number) +{ + uint32_t mask; + + if (reg == NULL) { + return; + } + /* pwm output number square waves */ + reg->cfg2 = number; + mask = ~(1 << PWM_KEEP_OFFSET); + reg->ctrl &= mask; + reg->ctrl |= PWM_ENABLE; +} + +static inline void HiPwmSetPolarity(struct HiPwmRegs *reg, uint8_t polarity) +{ + uint32_t mask; + + if (reg == NULL) { + return; + } + mask = ~(1 << PWM_INV_OFFSET); + reg->ctrl &= mask; + reg->ctrl |= (polarity << PWM_INV_OFFSET); +} + +static inline void HiPwmSetPeriod(struct HiPwmRegs *reg, uint32_t period) +{ + if (reg == NULL) { + return; + } + reg->cfg0 = period / PWM_CLK_PERIOD; +} + +static inline void HiPwmSetDuty(struct HiPwmRegs *reg, uint32_t duty) +{ + if (reg == NULL) { + return; + } + reg->cfg1 = duty / PWM_CLK_PERIOD; +} + +#endif /* PWM_HI35XX_H */ diff --git a/platform/pwm/pwm_hi35xx_linux.c b/platform/pwm/pwm_hi35xx_linux.c new file mode 100644 index 0000000..316417f --- /dev/null +++ b/platform/pwm/pwm_hi35xx_linux.c @@ -0,0 +1,185 @@ +/* + * pwm_hi35xx_linux.c + * + * pwm driver of hi35xx + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pwm_hi35xx.h" + +#define PWM_ENABLE_MASK 0x1 +#define PWM_HI35XX_N_CELLS 2 + +struct Hi35xxPwmChip { + struct pwm_chip chip; + struct HiPwmRegs *reg; + void __iomem *base; + struct clk *clk; +}; + +static int Hi35xxPwmApply(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) +{ + struct HiPwmRegs *reg = NULL; + struct Hi35xxPwmChip *hi35xxChip = (struct Hi35xxPwmChip *)chip; + + if (hi35xxChip == NULL || pwm == NULL || state == NULL) { + pr_err("%s: parameter is null\n", __func__); + return -EINVAL; + } + reg = (struct HiPwmRegs *)hi35xxChip->base; + if (state->polarity != PWM_POLARITY_NORMAL && state->polarity != PWM_POLARITY_INVERSED) { + pr_err("%s: polarity %u is invalid", __func__, state->polarity); + return -EINVAL; + } + + if (state->period < PWM_MIN_PERIOD) { + pr_err("%s: period %u is not support, min period %u", __func__, state->period, PWM_MIN_PERIOD); + return -EINVAL; + } + if (state->duty_cycle < 1 || state->duty_cycle > state->period) { + pr_err("%s: duty_cycle %u is not support, min duty_cycle 1 max duty_cycle %u", + __func__, state->duty_cycle , state->period); + return -EINVAL; + } + + HiPwmDisable(reg); + if (pwm->state.polarity != state->polarity) { + HiPwmSetPolarity(reg, state->polarity); + } + if (pwm->state.period != state->period) { + HiPwmSetPeriod(reg, state->period); + } + if (pwm->state.duty_cycle != state->duty_cycle) { + HiPwmSetDuty(reg, state->duty_cycle); + } + if (state->enabled) { + HiPwmAlwaysOutput(reg); + } + return 0; +} + + +static void Hi35xxGetState(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) +{ + struct HiPwmRegs *reg = NULL; + struct Hi35xxPwmChip *hi35xxChip = (struct Hi35xxPwmChip *)chip; + + if (hi35xxChip == NULL || pwm == NULL || state == NULL) { + pr_err("%s: parameter is null\n", __func__); + return; + } + reg = (struct HiPwmRegs *)hi35xxChip->base; + state->period = reg->cfg0; + state->duty_cycle = reg->cfg1; + state->enabled = reg->ctrl & PWM_ENABLE_MASK; +} + +static struct pwm_ops Hi35xxPwmOps = { + .apply = Hi35xxPwmApply, + .get_state = Hi35xxGetState, + .owner = THIS_MODULE, +}; + +static int PwmProbe(struct platform_device *pdev) +{ + int ret; + struct resource *r = NULL; + struct Hi35xxPwmChip *chip = NULL; + struct device_node *np = pdev->dev.of_node; + + if (!np) { + dev_err(&pdev->dev, "invalid devicetree node\n"); + return -EINVAL; + } + + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + return -ENOMEM; + } + chip->chip.dev = &pdev->dev; + chip->chip.ops = &Hi35xxPwmOps; + chip->chip.of_xlate = NULL; + chip->chip.of_pwm_n_cells = PWM_HI35XX_N_CELLS; + chip->chip.base = -1; + chip->chip.npwm = 1; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + chip->base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(chip->base)) { + return PTR_ERR(chip->base); + } + chip->reg = (struct HiPwmRegs *)chip->base; + chip->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(chip->clk)) { + dev_err(&pdev->dev, "failed to get clock\n"); + return PTR_ERR(chip->clk); + } + ret = clk_prepare_enable(chip->clk); + if (ret < 0) { + dev_err(&pdev->dev, "failed to enable clock\n"); + return ret; + } + ret = pwmchip_add(&chip->chip); + if (ret < 0) { + dev_err(&pdev->dev, "failed to add PWM chip\n"); + return ret; + } + + platform_set_drvdata(pdev, chip); + return ret; +} + +static int PwmRemove(struct platform_device *pdev) +{ + int ret; + struct Hi35xxPwmChip *chip = NULL; + + chip = platform_get_drvdata(pdev); + if (chip == NULL) { + return -ENODEV; + } + ret = pwmchip_remove(&chip->chip); + if (ret < 0) { + return ret; + } + clk_disable_unprepare(chip->clk); + return 0; +} + +static const struct of_device_id g_pwmMatch[] = { + { .compatible = "hisilicon,pwm" }, + {}, +}; + +static struct platform_driver g_pwmDriver = { + .probe = PwmProbe, + .remove = PwmRemove, + .driver = { + .name = "pwm", + .of_match_table = g_pwmMatch, + } +}; +module_platform_driver(g_pwmDriver); +MODULE_LICENSE("GPL"); diff --git a/platform/rtc/rtc_adapter.c b/platform/rtc/rtc_adapter.c index 6c413fc..41262fd 100644 --- a/platform/rtc/rtc_adapter.c +++ b/platform/rtc/rtc_adapter.c @@ -70,6 +70,7 @@ static int32_t HiRtcReadTime(struct RtcHost *host, struct RtcTime *hdfTime) struct rtc_time linuxTime = {0}; struct rtc_device *dev = HdfGetRtcDevice(); + (void)host; if (dev == NULL) { return HDF_FAILURE; } @@ -83,13 +84,13 @@ static int32_t HiRtcReadTime(struct RtcHost *host, struct RtcTime *hdfTime) return HDF_SUCCESS; } - static int32_t HiRtcWriteTime(struct RtcHost *host, const struct RtcTime *hdfTime) { int32_t ret; struct rtc_time linuxTime = {0}; struct rtc_device *dev = HdfGetRtcDevice(); + (void)host; if (dev == NULL) { return HDF_FAILURE; } @@ -110,6 +111,7 @@ static int32_t HiReadAlarm(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, struct rtc_wkalrm alarm = {0}; struct rtc_device *dev = HdfGetRtcDevice(); + (void)host; (void)alarmIndex; if (dev == NULL) { return HDF_FAILURE; @@ -131,6 +133,7 @@ static int32_t HiWriteAlarm(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, struct rtc_wkalrm alarm = {0}; struct rtc_device *dev = HdfGetRtcDevice(); + (void)host; (void)alarmIndex; if (dev == NULL) { return HDF_FAILURE; @@ -153,6 +156,7 @@ static int32_t HiAlarmInterruptEnable(struct RtcHost *host, enum RtcAlarmIndex a int32_t ret; struct rtc_device *dev = HdfGetRtcDevice(); + (void)host; (void)alarmIndex; if (dev == NULL) { return HDF_FAILURE; diff --git a/platform/sdio/sdio_adapter.c b/platform/sdio/sdio_adapter.c index 6dc2ad9..f999ac9 100644 --- a/platform/sdio/sdio_adapter.c +++ b/platform/sdio/sdio_adapter.c @@ -1,5 +1,5 @@ /* - * sdio_adatper.c + * sdio_adapter.c * * hi35xx linux sdio driver implement. * @@ -460,12 +460,12 @@ static struct SdioMethod g_method = { static int32_t Hi35xxLinuxSdioBind(struct HdfDeviceObject *device) { - PLAT_LOGV("Hi35xxLinuxSdioBind: entry."); + HDF_LOGI("Hi35xxLinuxSdioBind: entry."); if (device == NULL) { HDF_LOGE("Hi35xxLinuxSdioBind: Fail, device is NULL."); return HDF_ERR_INVALID_OBJECT; } - PLAT_LOGV("Hi35xxLinuxSdioBind: Success."); + HDF_LOGI("Hi35xxLinuxSdioBind: Success."); return (SdioCntlrCreateAndBind(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS; } @@ -474,7 +474,7 @@ static int32_t Hi35xxLinuxSdioInit(struct HdfDeviceObject *device) struct SdioCntlr *cntlr = NULL; int32_t ret; - PLAT_LOGV("Hi35xxLinuxSdioInit: entry!"); + HDF_LOGI("Hi35xxLinuxSdioInit: entry!"); if (device == NULL) { HDF_LOGE("Hi35xxLinuxSdioInit: device is NULL."); return HDF_ERR_INVALID_OBJECT; @@ -492,7 +492,7 @@ static int32_t Hi35xxLinuxSdioInit(struct HdfDeviceObject *device) return HDF_ERR_IO; } cntlr->method = &g_method; - PLAT_LOGV("Hi35xxLinuxSdioInit: Success!"); + HDF_LOGI("Hi35xxLinuxSdioInit: Success!"); return HDF_SUCCESS; } diff --git a/platform/uart/uart_adapter.c b/platform/uart/uart_adapter.c index e1fec9a..c554d2e 100644 --- a/platform/uart/uart_adapter.c +++ b/platform/uart/uart_adapter.c @@ -1,5 +1,5 @@ /* - * uart_adatper.c + * uart_adapter.c * * linux uart driver adapter. * @@ -42,7 +42,7 @@ static int32_t UartAdapterInit(struct UartHost *host) mm_segment_t oldfs; if (host == NULL) { - return HDF_FAILURE; + return HDF_ERR_INVALID_OBJECT; } if (sprintf_s(name, UART_NAME_LEN - 1, "/dev/%s%d", g_driverName, host->num) < 0) { return HDF_FAILURE; @@ -62,9 +62,13 @@ static int32_t UartAdapterInit(struct UartHost *host) static int32_t UartAdapterDeInit(struct UartHost *host) { int32_t ret = HDF_SUCCESS; - struct file *fp = (struct file *)host->priv; + struct file *fp = NULL; mm_segment_t oldfs; + if (host == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + fp = (struct file *)host->priv; oldfs = get_fs(); set_fs(KERNEL_DS); if (!IS_ERR(fp) && fp) { @@ -77,13 +81,17 @@ static int32_t UartAdapterRead(struct UartHost *host, uint8_t *data, uint32_t si { loff_t pos = 0; int ret; - struct file *fp = (struct file *)host->priv; + struct file *fp = NULL; char __user *p = (__force char __user *)data; mm_segment_t oldfs; uint32_t tmp = 0; + if (host == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + fp = (struct file *)host->priv; if (data == NULL || size == 0) { - return HDF_FAILURE; + return HDF_ERR_INVALID_PARAM; } oldfs = get_fs(); set_fs(KERNEL_DS); @@ -102,12 +110,16 @@ static int32_t UartAdapterWrite(struct UartHost *host, uint8_t *data, uint32_t s { loff_t pos = 0; int ret; - struct file *fp = (struct file *)host->priv; + struct file *fp = NULL; char __user *p = (__force char __user *)data; mm_segment_t oldfs; + if (host == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + fp = (struct file *)host->priv; if (data == NULL || size == 0) { - return HDF_FAILURE; + return HDF_ERR_INVALID_PARAM; } oldfs = get_fs(); set_fs(KERNEL_DS); @@ -189,10 +201,14 @@ static uint32_t CflagToBaudRate(unsigned short flag) static int32_t UartAdapterGetBaud(struct UartHost *host, uint32_t *baudRate) { struct termios termios; - struct file *fp = (struct file *)host->priv; + struct file *fp = NULL; + if (host == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + fp = (struct file *)host->priv; if (baudRate == NULL) { - return HDF_FAILURE; + return HDF_ERR_INVALID_PARAM; } if (UartAdapterIoctlInner(fp, TCGETS, (unsigned long)&termios) < 0) { HDF_LOGE("tcgets fail"); @@ -295,7 +311,7 @@ static unsigned char CSToAttr(unsigned short cs) } else if (t == CS5) { return UART_ATTR_DATABIT_5; } else { - /* defaule value */ + /* default value */ return UART_ATTR_DATABIT_8; } } @@ -311,7 +327,7 @@ static unsigned short AttrToCs(unsigned char attr) } else if (attr == UART_ATTR_DATABIT_5) { return CS5; } else { - /* defaule value */ + /* default value */ return CS8; } } @@ -325,7 +341,7 @@ static unsigned char PariTyToAttr(unsigned short ps) } else if (!(ps & (PARENB | PARODD))) { return UART_ATTR_PARITY_NONE; } else { - /* defaule value */ + /* default value */ return UART_ATTR_PARITY_NONE; } } @@ -337,7 +353,7 @@ static unsigned char StopBitToAttr(unsigned short st) } else if (st & CSTOPB) { return UART_ATTR_STOPBIT_2; } else { - /* defaule value */ + /* default value */ return UART_ATTR_STOPBIT_1; } } @@ -353,11 +369,15 @@ static unsigned char CtsRtsToAttr(unsigned short cr) static int32_t UartAdapterGetAttribute(struct UartHost *host, struct UartAttribute *attribute) { struct termios termios; - struct file *fp = (struct file *)host->priv; + struct file *fp = NULL; int ret; + if (host == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + fp = (struct file *)host->priv; if (attribute == NULL) { - return HDF_FAILURE; + return HDF_ERR_INVALID_PARAM; } ret = UartAdapterIoctlInner(fp, TCGETS, (unsigned long)&termios); if (ret < 0) { @@ -373,11 +393,15 @@ static int32_t UartAdapterGetAttribute(struct UartHost *host, struct UartAttribu static int32_t UartAdapterSetAttribute(struct UartHost *host, struct UartAttribute *attribute) { struct termios termios; - struct file *fp = (struct file *)host->priv; + struct file *fp = NULL; int ret; + if (host == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + fp = (struct file *)host->priv; if (attribute == NULL) { - return HDF_FAILURE; + return HDF_ERR_INVALID_PARAM; } ret = UartAdapterIoctlInner(fp, TCGETS, (unsigned long)&termios); if (ret < 0) { @@ -398,7 +422,7 @@ static int32_t UartAdapterSetAttribute(struct UartHost *host, struct UartAttribu termios.c_cflag &= ~PARODD; } else if (attribute->parity == UART_ATTR_PARITY_NONE) { termios.c_cflag &= ~(PARENB | PARODD); - } else { /* defaule value */ + } else { /* default value */ termios.c_cflag &= ~(PARENB | PARODD); } if (attribute->stopBits == UART_ATTR_STOPBIT_1) { @@ -406,7 +430,7 @@ static int32_t UartAdapterSetAttribute(struct UartHost *host, struct UartAttribu } else if (attribute->stopBits == UART_ATTR_STOPBIT_2) { termios.c_cflag |= CSTOPB; } else { - /* defaule value */ + /* default value */ termios.c_cflag &= ~CSTOPB; } ret = UartAdapterIoctlInner(fp, TCSETS, (unsigned long)&termios); diff --git a/platform/watchdog/watchdog_adapter.c b/platform/watchdog/watchdog_adapter.c index 0dfa142..84f24e9 100644 --- a/platform/watchdog/watchdog_adapter.c +++ b/platform/watchdog/watchdog_adapter.c @@ -31,7 +31,7 @@ #include "watchdog_core.h" #define HDF_LOG_TAG hdf_watchdog_adapter -#define UART_NAME_LEN 20 +#define WATCHDOG_NAME_LEN 20 static int WdtAdapterIoctlInner(struct file *fp, unsigned cmd, unsigned long arg) { @@ -49,14 +49,14 @@ static int WdtAdapterIoctlInner(struct file *fp, unsigned cmd, unsigned long arg static int32_t WdtOpenFile(struct WatchdogCntlr *wdt) { - char name[UART_NAME_LEN] = {0}; + char name[WATCHDOG_NAME_LEN] = {0}; struct file *fp = NULL; mm_segment_t oldfs; if (wdt == NULL) { return HDF_FAILURE; } - if (sprintf_s(name, UART_NAME_LEN - 1, "/dev/watchdog%d", wdt->wdtId) < 0) { + if (sprintf_s(name, WATCHDOG_NAME_LEN - 1, "/dev/watchdog%d", wdt->wdtId) < 0) { return HDF_FAILURE; } oldfs = get_fs(); @@ -74,14 +74,13 @@ static int32_t WdtOpenFile(struct WatchdogCntlr *wdt) static void WdtAdapterClose(struct WatchdogCntlr *wdt) { - int32_t ret; mm_segment_t oldfs; struct file *fp = (struct file *)wdt->priv; oldfs = get_fs(); set_fs(KERNEL_DS); if (!IS_ERR(fp) && fp) { - ret = filp_close(fp, NULL); + (void)filp_close(fp, NULL); } set_fs(oldfs); wdt->priv = NULL; @@ -240,11 +239,14 @@ static int32_t HdfWdtBind(struct HdfDeviceObject *obj) drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); if (drsOps == NULL || drsOps->GetUint32 == NULL) { HDF_LOGE("%s: invalid drs ops!", __func__); + OsalMemFree(wdt); return HDF_FAILURE; } ret = drsOps->GetUint16(obj->property, "id", &wdt->wdtId, 0); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: read wdtId fail, ret %d!", __func__, ret); + OsalMemFree(wdt); + return ret; } wdt->ops = &g_wdtMethod; wdt->device = obj; -- Gitee From f0bf253e1e0719ec0da8d4868a14d1ba97054a5a Mon Sep 17 00:00:00 2001 From: haizhouyang Date: Tue, 18 May 2021 21:17:40 +0800 Subject: [PATCH 2/2] normal including path of boundary_check --- platform/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform.mk b/platform/platform.mk index f822582..3544e29 100644 --- a/platform/platform.mk +++ b/platform/platform.mk @@ -30,4 +30,4 @@ ccflags-$(CONFIG_DRIVERS_HDF_PLATFORM) += -Idrivers/hdf/framework/include/platfo -Idrivers/hdf/framework/core/common/include/host \ -Idrivers/hdf/framework/ability/sbuf/include \ -Idrivers/hdf/framework/utils/include \ - -Iinclude/../../../../../../third_party/bounds_checking_function/include + -I$(PROJECT_ROOT)/third_party/bounds_checking_function/include -- Gitee