Merge "msm: sensor: Enable combo mode in 10NM CSI PHY"

This commit is contained in:
Linux Build Service Account 2016-09-08 14:32:06 -07:00 committed by Gerrit - the friendly Code Review server
commit 0a838df5d0
3 changed files with 203 additions and 97 deletions

View file

@ -101,4 +101,61 @@ struct csiphy_reg_3ph_parms_t csiphy_v5_0_3ph = {
{0x38, 0xFE},
{0x81c, 0x6},
};
struct csiphy_settings_t csiphy_combo_mode_v5_0 = {
{
{0x818, 0x1},
{0x81c, 0x2},
{0x004, 0x08},
{0x704, 0x08},
{0x204, 0x08},
{0x404, 0x08},
{0x604, 0x08},
{0x02c, 0x1},
{0x22c, 0x1},
{0x42c, 0x1},
{0x62c, 0x1},
{0x72c, 0x1},
{0x034, 0x0f},
{0x234, 0x0f},
{0x434, 0x0f},
{0x634, 0x0f},
{0x734, 0x0f},
{0x01c, 0x0a},
{0x21c, 0x0a},
{0x41c, 0x0a},
{0x61c, 0x0a},
{0x71c, 0x0a},
{0x014, 0x60},
{0x214, 0x60},
{0x414, 0x60},
{0x614, 0x60},
{0x714, 0x60},
{0x728, 0x4},
{0x428, 0x0a},
{0x628, 0x0e},
{0x03c, 0xb8},
{0x73c, 0xb8},
{0x23c, 0xb8},
{0x43c, 0xb8},
{0x63c, 0xb8},
{0x000, 0x91},
{0x700, 0x80},
{0x200, 0x91},
{0x400, 0x91},
{0x600, 0x80},
{0x70c, 0xA5},
{0x60c, 0xA5},
{0x010, 0x52},
{0x710, 0x52},
{0x210, 0x52},
{0x410, 0x52},
{0x610, 0x52},
{0x038, 0xfe},
{0x738, 0x1f},
{0x238, 0xfe},
{0x438, 0xfe},
{0x638, 0x1f},
}
};
#endif

View file

@ -46,7 +46,7 @@
#define NUM_LANES_OFFSET 4
#define CSI_3PHASE_HW 1
#define MAX_LANES 4
#define MAX_DPHY_DATA_LN 4
#define CLOCK_OFFSET 0x700
#define CSIPHY_SOF_DEBUG_COUNT 2
@ -55,6 +55,22 @@
static struct v4l2_file_operations msm_csiphy_v4l2_subdev_fops;
static void msm_csiphy_write_settings(
struct csiphy_device *csiphy_dev,
struct csiphy_settings_t csiphy_settings)
{
int i = 0;
for (i = 0; i < MAX_CSIPHY_SETTINGS; i++) {
if (csiphy_settings.settings[i].addr == 0 &&
csiphy_settings.settings[i].data == 0)
break;
msm_camera_io_w(csiphy_settings.settings[i].data,
csiphy_dev->base + csiphy_settings.settings[i].addr);
}
}
static void msm_csiphy_cphy_irq_config(
struct csiphy_device *csiphy_dev,
struct msm_camera_csiphy_params *csiphy_params)
@ -418,7 +434,7 @@ static int msm_csiphy_2phase_lane_config(
csiphybase = csiphy_dev->base;
lane_mask = csiphy_params->lane_mask & 0x1f;
for (i = 0; i < MAX_LANES; i++) {
for (i = 0; i < MAX_DPHY_DATA_LN; i++) {
if (mask == 0x2) {
if (lane_mask & mask)
lane_enable |= 0x80;
@ -437,7 +453,7 @@ static int msm_csiphy_2phase_lane_config(
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_3ph_cmn_ctrl6.addr);
for (i = 0, mask = 0x1; i < MAX_LANES; i++) {
for (i = 0, mask = 0x1; i < MAX_DPHY_DATA_LN; i++) {
if (!(lane_mask & mask)) {
if (mask == 0x2)
i--;
@ -562,112 +578,134 @@ static int msm_csiphy_2phase_lane_config_v50(
struct csiphy_device *csiphy_dev,
struct msm_camera_csiphy_params *csiphy_params)
{
uint32_t val = 0, lane_enable = 0, clk_lane, mask = 1;
uint32_t lane_enable = 0, mask = 1;
uint16_t lane_mask = 0, i = 0, offset;
void __iomem *csiphybase;
csiphybase = csiphy_dev->base;
lane_mask = csiphy_params->lane_mask & 0x1f;
for (i = 0; i < MAX_LANES; i++) {
lane_enable = msm_camera_io_r(csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_3ph_cmn_ctrl5.addr);
/* write settle count and lane_enable */
for (i = 0; i < MAX_DPHY_DATA_LN; i++) {
if (mask == 0x2) {
if (lane_mask & mask)
lane_enable |= 0x80;
i--;
} else if (lane_mask & mask)
offset = CLOCK_OFFSET;
} else if (lane_mask & mask) {
lane_enable |= 0x1 << (i<<1);
offset = 0x200*i;
}
if (lane_mask & mask)
msm_camera_io_w((csiphy_params->settle_cnt & 0xFF),
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg2.addr + offset);
mask <<= 1;
}
CDBG("%s:%d lane_enable: %d\n", __func__, __LINE__, lane_enable);
CDBG("%s:%d lane_enable: 0x%x\n", __func__, __LINE__, lane_enable);
msm_camera_io_w(lane_enable,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_3ph_cmn_ctrl5.addr);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_3ph_cmn_ctrl6.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_3ph_cmn_ctrl6.addr);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_3ph_cmn_ctrl7.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_3ph_cmn_ctrl7.addr);
for (i = 0, mask = 0x1; i < MAX_LANES; i++) {
if (!(lane_mask & mask)) {
if (mask == 0x2)
i--;
mask <<= 0x1;
continue;
}
if (mask == 0x2) {
val = 4;
offset = CLOCK_OFFSET;
clk_lane = 1;
i--;
} else {
offset = 0x200*i;
val = 0;
clk_lane = 0;
}
if (csiphy_params->combo_mode == 1) {
val |= 0xA;
if (mask == csiphy_dev->ctrl_reg->
csiphy_reg.combo_clk_mask) {
val |= 0x4;
clk_lane = 1;
}
}
/* write mode specific settings */
if (csiphy_params->combo_mode == 1)
msm_csiphy_write_settings(csiphy_dev,
csiphy_dev->ctrl_reg->csiphy_combo_mode_settings);
else {
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl11.data,
mipi_csiphy_3ph_cmn_ctrl6.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl11.addr + offset);
mipi_csiphy_3ph_cmn_ctrl6.addr);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl13.data,
mipi_csiphy_3ph_cmn_ctrl7.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl13.addr + offset);
mipi_csiphy_3ph_cmn_ctrl7.addr);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg7.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg7.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg5.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg5.addr + offset);
if (clk_lane == 1)
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnck_ctrl10.data,
csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnck_ctrl10.addr);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl15.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl15.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl0.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl0.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg1.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg1.addr + offset);
msm_camera_io_w((csiphy_params->settle_cnt & 0xFF),
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg2.addr + offset);
if (clk_lane == 1)
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnck_ctrl3.data, csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnck_ctrl3.addr);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg4.data, csiphybase +
mipi_csiphy_2ph_lnck_ctrl10.data,
csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg4.addr + offset);
mipi_csiphy_2ph_lnck_ctrl10.addr);
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl14.data,
csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl14.addr + offset);
mask <<= 1;
mipi_csiphy_2ph_lnck_ctrl3.data, csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnck_ctrl3.addr);
for (i = 0, mask = 0x1; i < MAX_DPHY_DATA_LN; i++) {
if (!(lane_mask & mask)) {
if (mask == 0x2)
i--;
mask <<= 0x1;
continue;
}
if (mask == 0x2) {
offset = CLOCK_OFFSET;
i--;
} else {
offset = 0x200*i;
}
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl11.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl11.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl13.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl13.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg7.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg7.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg5.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg5.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl15.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl15.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl0.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl0.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg1.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg1.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg4.data, csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg4.addr + offset);
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl14.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl14.addr + offset);
mask <<= 1;
}
}
msm_csiphy_cphy_irq_config(csiphy_dev, csiphy_params);
return 0;
@ -985,6 +1023,13 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
if (csiphy_dev->ref_count++) {
CDBG("%s csiphy refcount = %d\n", __func__,
csiphy_dev->ref_count);
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
if (csiphy_dev->csiphy_state == CSIPHY_POWER_UP) {
pr_err("%s: csiphy invalid state %d\n", __func__,
@ -992,13 +1037,7 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
rc = -EINVAL;
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
if (csiphy_dev->ref_count++) {
CDBG("%s csiphy refcount = %d\n", __func__,
csiphy_dev->ref_count);
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
@ -1063,6 +1102,14 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
return rc;
}
csiphy_dev->csiphy_sof_debug_count = 0;
CDBG("%s:%d called\n", __func__, __LINE__);
if (csiphy_dev->ref_count++) {
CDBG("%s csiphy refcount = %d\n", __func__,
csiphy_dev->ref_count);
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
if (csiphy_dev->csiphy_state == CSIPHY_POWER_UP) {
pr_err("%s: csiphy invalid state %d\n", __func__,
@ -1070,13 +1117,7 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
rc = -EINVAL;
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
if (csiphy_dev->ref_count++) {
CDBG("%s csiphy refcount = %d\n", __func__,
csiphy_dev->ref_count);
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
CAM_AHB_SVS_VOTE);
@ -1651,6 +1692,8 @@ static int csiphy_probe(struct platform_device *pdev)
new_csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v5_0;
new_csiphy_dev->hw_dts_version = CSIPHY_VERSION_V50;
new_csiphy_dev->csiphy_3phase = CSI_3PHASE_HW;
new_csiphy_dev->ctrl_reg->csiphy_combo_mode_settings =
csiphy_combo_mode_v5_0;
} else {
pr_err("%s:%d, invalid hw version : 0x%x\n", __func__, __LINE__,
new_csiphy_dev->hw_dts_version);

View file

@ -24,12 +24,17 @@
#define MAX_CSIPHY 3
#define CSIPHY_NUM_CLK_MAX 16
#define MAX_CSIPHY_SETTINGS 120
struct csiphy_reg_t {
uint32_t addr;
uint32_t data;
};
struct csiphy_settings_t {
struct csiphy_reg_t settings[MAX_CSIPHY_SETTINGS];
};
struct csiphy_reg_parms_t {
/*MIPI CSI PHY registers*/
uint32_t mipi_csiphy_lnn_cfg1_addr;
@ -140,6 +145,7 @@ struct csiphy_reg_3ph_parms_t {
struct csiphy_ctrl_t {
struct csiphy_reg_parms_t csiphy_reg;
struct csiphy_reg_3ph_parms_t csiphy_3ph_reg;
struct csiphy_settings_t csiphy_combo_mode_settings;
};
enum msm_csiphy_state_t {