diff options
| -rw-r--r-- | drivers/media/platform/qcom/camss/camss-vfe-gen3.c | 67 | ||||
| -rw-r--r-- | drivers/media/platform/qcom/camss/camss-vfe.c | 25 | ||||
| -rw-r--r-- | drivers/media/platform/qcom/camss/camss.c | 174 |
3 files changed, 246 insertions, 20 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-gen3.c b/drivers/media/platform/qcom/camss/camss-vfe-gen3.c index 93d16b0951e9..f2001140ead1 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-gen3.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-gen3.c @@ -12,13 +12,43 @@ #include "camss.h" #include "camss-vfe.h" -#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x200 : 0xC00) +#define IS_VFE_690(vfe) \ + (vfe->camss->res->version == CAMSS_8775P) + +#define BUS_REG_BASE_690 \ + (vfe_is_lite(vfe) ? 0x480 : 0x400) +#define BUS_REG_BASE_780 \ + (vfe_is_lite(vfe) ? 0x200 : 0xC00) +#define BUS_REG_BASE \ + (IS_VFE_690(vfe) ? BUS_REG_BASE_690 : BUS_REG_BASE_780) + +#define VFE_TOP_CORE_CFG (0x24) +#define VFE_DISABLE_DSCALING_DS4 BIT(21) +#define VFE_DISABLE_DSCALING_DS16 BIT(22) + +#define VFE_BUS_WM_TEST_BUS_CTRL_690 (BUS_REG_BASE + 0xFC) +#define VFE_BUS_WM_TEST_BUS_CTRL_780 (BUS_REG_BASE + 0xDC) +#define VFE_BUS_WM_TEST_BUS_CTRL \ + (IS_VFE_690(vfe) ? VFE_BUS_WM_TEST_BUS_CTRL_690 \ + : VFE_BUS_WM_TEST_BUS_CTRL_780) +/* + * Bus client mapping: + * + * Full VFE: + * VFE_690: 16 = RDI0, 17 = RDI1, 18 = RDI2 + * VFE_780: 23 = RDI0, 24 = RDI1, 25 = RDI2 + * + * VFE LITE: + * VFE_690 : 0 = RDI0, 1 = RDI1, 2 = RDI2, 3 = RDI3, 4 = RDI4, 5 = RDI5 + * VFE_780 : 0 = RDI0, 1 = RDI1, 2 = RDI2, 3 = RDI3, 4 = RDI4 + */ +#define RDI_WM_690(n) ((vfe_is_lite(vfe) ? 0x0 : 0x10) + (n)) +#define RDI_WM_780(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n)) +#define RDI_WM(n) (IS_VFE_690(vfe) ? RDI_WM_690(n) : RDI_WM_780(n)) #define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08) #define WM_CGC_OVERRIDE_ALL (0x7FFFFFF) -#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0xDC) - #define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x200 + (n) * 0x100) #define WM_CFG_EN BIT(0) #define WM_VIR_FRM_EN BIT(1) @@ -39,17 +69,6 @@ #define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x260 + (n) * 0x100) #define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x264 + (n) * 0x100) -/* - * Bus client mapping: - * - * Full VFE: - * 23 = RDI0, 24 = RDI1, 25 = RDI2 - * - * VFE LITE: - * 0 = RDI0, 1 = RDI1, 2 = RDI3, 4 = RDI4 - */ -#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n)) - static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line) { struct v4l2_pix_format_mplane *pix = @@ -62,14 +81,24 @@ static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line) writel(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL); - writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8, - vfe->base + VFE_BUS_WM_FRAME_INCR(wm)); + if (IS_VFE_690(vfe)) + writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height, + vfe->base + VFE_BUS_WM_FRAME_INCR(wm)); + else + writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8, + vfe->base + VFE_BUS_WM_FRAME_INCR(wm)); + writel((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF), vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm)); writel(WM_IMAGE_CFG_2_DEFAULT_STRIDE, vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm)); writel(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm)); + /* TOP CORE CFG */ + if (IS_VFE_690(vfe)) + writel(VFE_DISABLE_DSCALING_DS4 | VFE_DISABLE_DSCALING_DS16, + vfe->base + VFE_TOP_CORE_CFG); + /* no dropped frames, one irq per frame */ writel(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm)); writel(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm)); @@ -92,7 +121,11 @@ static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr, struct vfe_line *line) { wm = RDI_WM(wm); - writel((addr >> 8) & 0xFFFFFFFF, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm)); + + if (IS_VFE_690(vfe)) + writel(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm)); + else + writel((addr >> 8), vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm)); dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%x\n", wm, addr); diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index c575c9767492..3db183191b36 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -347,6 +347,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, case CAMSS_8280XP: case CAMSS_845: case CAMSS_8550: + case CAMSS_8775P: case CAMSS_X1E80100: switch (sink_code) { case MEDIA_BUS_FMT_YUYV8_1X16: @@ -911,7 +912,24 @@ static int vfe_match_clock_names(struct vfe_device *vfe, return (!strcmp(clock->name, vfe_name) || !strcmp(clock->name, vfe_lite_name) || - !strcmp(clock->name, "vfe_lite")); + !strcmp(clock->name, "vfe_lite") || + !strcmp(clock->name, "camnoc_axi")); +} + +/* + * vfe_check_clock_levels - Calculate and set clock rates on VFE module + * @clock: clocks data + * + * Return false if there is no non-zero clock level and true otherwise. + */ +static bool vfe_check_clock_levels(struct camss_clock *clock) +{ + int i; + + for (i = 0; i < clock->nfreqs; i++) + if (clock->freq[i]) + return true; + return false; } /* @@ -937,7 +955,7 @@ static int vfe_set_clock_rates(struct vfe_device *vfe) for (i = 0; i < vfe->nclocks; i++) { struct camss_clock *clock = &vfe->clock[i]; - if (vfe_match_clock_names(vfe, clock)) { + if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) { u64 min_rate = 0; long rate; @@ -1018,7 +1036,7 @@ static int vfe_check_clock_rates(struct vfe_device *vfe) for (i = 0; i < vfe->nclocks; i++) { struct camss_clock *clock = &vfe->clock[i]; - if (vfe_match_clock_names(vfe, clock)) { + if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) { u64 min_rate = 0; unsigned long rate; @@ -1976,6 +1994,7 @@ static int vfe_bpl_align(struct vfe_device *vfe) case CAMSS_8280XP: case CAMSS_845: case CAMSS_8550: + case CAMSS_8775P: case CAMSS_X1E80100: ret = 16; break; diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index ee2ac2cec219..003c676f5919 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -2821,6 +2821,180 @@ static const struct camss_subdev_resources csid_res_8775p[] = { }, }; +static const struct camss_subdev_resources vfe_res_8775p[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "cpas_vfe0", "vfe0", "vfe0_fast_ahb", + "cpas_ahb", "gcc_axi_hf", + "cpas_fast_ahb_clk", + "camnoc_axi"}, + .clock_rate = { + { 0 }, + { 480000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 300000000, 400000000 }, + { 400000000 }, + }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = false, + .pd_name = NULL, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE1 */ + { + .regulators = {}, + .clock = { "cpas_vfe1", "vfe1", "vfe1_fast_ahb", + "cpas_ahb", "gcc_axi_hf", + "cpas_fast_ahb_clk", + "camnoc_axi"}, + .clock_rate = { + { 0 }, + { 480000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 300000000, 400000000 }, + { 400000000 }, + }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = false, + .pd_name = NULL, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE2 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE3 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE4 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite2" }, + .interrupt = { "vfe_lite2" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE5 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite3" }, + .interrupt = { "vfe_lite3" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE6 (lite) */ + { + .regulators = {}, + .clock = { "cpas_vfe_lite", "vfe_lite_ahb", + "vfe_lite_csid", "vfe_lite_cphy_rx", + "vfe_lite"}, + .clock_rate = { + { 0, 0, 0, 0 }, + { 300000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 400000000, 400000000, 400000000, 400000000 }, + { 480000000, 600000000, 600000000, 600000000 }, + }, + .reg = { "vfe_lite4" }, + .interrupt = { "vfe_lite4" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + static const struct resources_icc icc_res_sa8775p[] = { { .name = "ahb", |
