diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 6eda1796590d..cea15fecc025 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -35,9 +35,19 @@ /* Mask to enable skew calibration registers */ #define SKEW_CAL_MASK 0x2 +static DEFINE_MUTEX(active_csiphy_cnt_mutex); + static int csiphy_dump; module_param(csiphy_dump, int, 0644); +struct g_csiphy_data { + void __iomem *base_address; + uint8_t is_3phase; +}; + +static struct g_csiphy_data g_phy_data[MAX_CSIPHY] = {{0, 0}}; +static int active_csiphy_hw_cnt; + int32_t cam_csiphy_get_instance_offset( struct csiphy_device *csiphy_dev, int32_t dev_handle) @@ -109,6 +119,59 @@ void cam_csiphy_reset(struct csiphy_device *csiphy_dev) } } +static void cam_csiphy_prgm_cmn_data( + struct csiphy_device *csiphy_dev, + bool reset) +{ + int csiphy_idx = 0; + uint32_t size = 0; + int i = 0; + void __iomem *csiphybase; + bool is_3phase = false; + struct csiphy_reg_t *csiphy_common_reg = NULL; + + size = csiphy_dev->ctrl_reg->csiphy_reg.csiphy_common_array_size; + + if (active_csiphy_hw_cnt < 0 || active_csiphy_hw_cnt >= MAX_CSIPHY) { + CAM_WARN(CAM_CSIPHY, + "MisMatched in active phy hw: %d and Max supported: %d", + active_csiphy_hw_cnt, MAX_CSIPHY); + return; + } + + if (active_csiphy_hw_cnt == 0) { + CAM_DBG(CAM_CSIPHY, "CSIPHYs HW state needs to be %s", + reset ? "reset" : "set"); + } else { + CAM_DBG(CAM_CSIPHY, "Active CSIPHY hws are %d", + active_csiphy_hw_cnt); + return; + } + + for (csiphy_idx = 0; csiphy_idx < MAX_CSIPHY; csiphy_idx++) { + csiphybase = g_phy_data[csiphy_idx].base_address; + is_3phase = g_phy_data[csiphy_idx].is_3phase; + + for (i = 0; i < size; i++) { + csiphy_common_reg = + &csiphy_dev->ctrl_reg->csiphy_common_reg[i]; + switch (csiphy_common_reg->csiphy_param_type) { + case CSIPHY_DEFAULT_PARAMS: + cam_io_w_mb(reset ? 0x00 : + csiphy_common_reg->reg_data, + csiphybase + + csiphy_common_reg->reg_addr); + break; + default: + break; + } + if (csiphy_common_reg->delay > 0) + usleep_range(csiphy_common_reg->delay, + csiphy_common_reg->delay + 5); + } + } +} + static int32_t cam_csiphy_update_secure_info( struct csiphy_device *csiphy_dev, int32_t index) { @@ -1132,6 +1195,15 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } + if (!csiphy_dev->acquire_count) { + g_phy_data[csiphy_dev->soc_info.index].is_3phase = + csiphy_acq_params.csiphy_3phase; + CAM_DBG(CAM_CSIPHY, + "g_csiphy data is updated for index: %d is_3phase: %u", + csiphy_dev->soc_info.index, + g_phy_data[csiphy_dev->soc_info.index].is_3phase); + } + csiphy_dev->acquire_count++; CAM_DBG(CAM_CSIPHY, "ACQUIRE_CNT: %d", csiphy_dev->acquire_count); @@ -1209,6 +1281,15 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask = 0x0; + if (csiphy_dev->ctrl_reg->csiphy_reg + .prgm_cmn_reg_across_csiphy) { + mutex_lock(&active_csiphy_cnt_mutex); + active_csiphy_hw_cnt--; + mutex_unlock(&active_csiphy_cnt_mutex); + + cam_csiphy_prgm_cmn_data(csiphy_dev, true); + } + rc = cam_csiphy_disable_hw(csiphy_dev); if (rc < 0) CAM_ERR(CAM_CSIPHY, "Failed in csiphy release"); @@ -1451,6 +1532,16 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } csiphy_dev->start_dev_count++; + + if (csiphy_dev->ctrl_reg->csiphy_reg + .prgm_cmn_reg_across_csiphy) { + cam_csiphy_prgm_cmn_data(csiphy_dev, false); + + mutex_lock(&active_csiphy_cnt_mutex); + active_csiphy_hw_cnt++; + mutex_unlock(&active_csiphy_cnt_mutex); + } + CAM_DBG(CAM_CSIPHY, "START DEV CNT: %d", csiphy_dev->start_dev_count); csiphy_dev->csiphy_state = CAM_CSIPHY_START; @@ -1480,3 +1571,20 @@ release_mutex: return rc; } + +void cam_csiphy_register_baseaddress(struct csiphy_device *csiphy_dev) +{ + if (!csiphy_dev) { + CAM_WARN(CAM_CSIPHY, "Data is NULL"); + return; + } + + if (csiphy_dev->soc_info.index >= MAX_CSIPHY) { + CAM_ERR(CAM_CSIPHY, "Invalid soc index: %u Max soc index: %u", + csiphy_dev->soc_info.index, MAX_CSIPHY); + return; + } + + g_phy_data[csiphy_dev->soc_info.index].base_address = + csiphy_dev->soc_info.reg_map[0].mem_base; +} diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.h b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.h index 237fa787f226..271f6b0e28cd 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.h +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. */ #ifndef _CAM_CSIPHY_CORE_H_ @@ -49,4 +49,11 @@ irqreturn_t cam_csiphy_irq(int irq_num, void *data); */ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev); +/** + * @soc_idx : CSIPHY cell index + * + * This API registers base address per soc_idx + */ +void cam_csiphy_register_baseaddress(struct csiphy_device *csiphy_dev); + #endif /* _CAM_CSIPHY_CORE_H_ */ diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c index 5d5f58748cec..29efc2a7f119 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c @@ -221,6 +221,10 @@ static int cam_csiphy_component_bind(struct device *dev, CAM_DBG(CAM_CSIPHY, "CPAS registration successful handle=%d", cpas_parms.client_handle); new_csiphy_dev->cpas_handle = cpas_parms.client_handle; + + cam_csiphy_register_baseaddress(new_csiphy_dev); + + CAM_DBG(CAM_CSIPHY, "%s component bound successfully", pdev->name); return rc; diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h index 74d2dbd59080..4643b119805c 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h @@ -117,6 +117,7 @@ struct csiphy_reg_parms_t { uint32_t csiphy_cpas_cp_3ph_offset; uint32_t csiphy_2ph_clock_lane; uint32_t csiphy_2ph_combo_ck_ln; + uint32_t prgm_cmn_reg_across_csiphy; }; /** diff --git a/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h b/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h index 02d34d64b89d..1bfc6ca97b92 100644 --- a/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h +++ b/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h @@ -13,13 +13,14 @@ struct csiphy_reg_parms_t csiphy_v1_2_3 = { .mipi_csiphy_interrupt_clear0_addr = 0x858, .mipi_csiphy_glbl_irq_cmd_addr = 0x828, .csiphy_interrupt_status_size = 11, - .csiphy_common_array_size = 8, - .csiphy_reset_array_size = 5, + .csiphy_common_array_size = 5, + .csiphy_reset_array_size = 2, .csiphy_2ph_config_array_size = 16, .csiphy_3ph_config_array_size = 26, .csiphy_2ph_3ph_config_array_size = 0, .csiphy_2ph_clock_lane = 0x1, .csiphy_2ph_combo_ck_ln = 0x10, + .prgm_cmn_reg_across_csiphy = 1, }; struct csiphy_reg_t csiphy_common_reg_1_2_3[] = { @@ -28,15 +29,9 @@ struct csiphy_reg_t csiphy_common_reg_1_2_3[] = { {0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x081C, 0x5A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0824, 0x72, 0x00, CSIPHY_2PH_REGS}, - {0x0800, 0x01, 0x02, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_2PH_REGS}, - {0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS}, }; struct csiphy_reg_t csiphy_reset_reg_1_2_3[] = { - {0x0814, 0x00, 0x00, CSIPHY_LANE_ENABLE}, - {0x0818, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x081C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x01, 0x02, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, };