diff --git a/arch/arm/boot/dts/amlogic/meson-s7.dtsi b/arch/arm/boot/dts/amlogic/meson-s7.dtsi index 7572c9d7a..eea7f9fb6 100644 --- a/arch/arm/boot/dts/amlogic/meson-s7.dtsi +++ b/arch/arm/boot/dts/amlogic/meson-s7.dtsi @@ -1967,7 +1967,7 @@ meson_uvm { compatible = "amlogic, meson_uvm"; - status = "disabled"; + status = "okay"; }; meson_videotunnel{ @@ -2077,7 +2077,7 @@ video_composer { compatible = "amlogic, video_composer"; dev_name = "video_composer"; - status = "disabled"; + status = "okay"; }; vpu_security { diff --git a/arch/arm/boot/dts/amlogic/mesons7_drm.dtsi b/arch/arm/boot/dts/amlogic/mesons7_drm.dtsi new file mode 100644 index 000000000..db7851cf0 --- /dev/null +++ b/arch/arm/boot/dts/amlogic/mesons7_drm.dtsi @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ + +#include +#include "meson-s7.dtsi" + +/ { + drm_amhdmitx: drm-amhdmitx { + status = "disabled"; + hdcp = "disabled"; + }; + + drm_amcvbsout: drm-amcvbsout { + status = "disabled"; + compatible = "amlogic, drm-cvbsout"; + dev_name = "meson-amcvbsout"; + ports { + port { + #address-cells = <1>; + #size-cells = <0>; +// cvbs_to_drm: endpoint@1 { +// reg = <1>; +// remote-endpoint = <&drm_to_cvbs>; +// }; + }; + }; + }; + + drm_vpu: drm-vpu@0xff900000 { + status = "disabled"; + compatible = "amlogic, meson-s7-vpu"; + osd_ver = /bits/ 8 ; + reg = <0xff900000 0x40000>, + <0xff63c000 0x2000>, + <0xff638000 0x2000>; + reg-names = "base", "hhi", "dmc"; + interrupts = ; + interrupt-names = "viu-vsync"; + dma-coherent; + /*EXTERNAL port for driver outside of drm.*/ + connectors_dev: port@1 { + #address-cells = <1>; + #size-cells = <0>; + drm_to_hdmitx: endpoint@0 { + reg = <0>; + remote-endpoint = <&hdmitx_to_drm>; + }; +// drm_to_cvbs: endpoint@1 { +// reg = <1>; +// remote-endpoint = <&cvbs_to_drm>; +// }; +// drm_to_dummyl: endpoint@2 { +// reg = <2>; +// remote-endpoint = <&dummyl_to_drm>; +// }; + }; + }; + + drm_subsystem: drm-subsystem { + status = "okay"; + compatible = "amlogic, drm-subsystem"; + ports = <&connectors_dev>; + fbdev_sizes = <1920 1080 1920 2160 32>; + vfm_mode = <1>; /** 0:drm mode 1:composer mode */ + memory-region = <&logo_reserved>; + primary_plane_index = <0>; /* primary plane index for crtcs */ + crtc_masks = <1 1 1>; /*for encoder: 0:hdmi 1:lcd 2:cvbs*/ + gamma_ctl = <0>; /*0:skip gamma init 1:gamma init*/ + + vpu_topology: vpu_topology { + vpu_blocks { + osd1_block: block@0 { + id = /bits/ 8 ; + index = /bits/ 8 <0>; + type = /bits/ 8 <0>; + block_name = "osd1_block"; + num_in_links = /bits/ 8 <0x0>; + num_out_links = /bits/ 8 <0x1>; + out_links = <0 &afbc_osd1_block>; + }; + osd2_block: block@1 { + id = /bits/ 8 ; + index = /bits/ 8 <1>; + type = /bits/ 8 <0>; + block_name = "osd2_block"; + num_in_links = /bits/ 8 <0x0>; + num_out_links = /bits/ 8 <0x1>; + out_links = <0 &afbc_osd2_block>; + }; + afbc_osd1_block: block@3 { + id = /bits/ 8 ; + index = /bits/ 8 <0>; + type = /bits/ 8 <1>; + block_name = "afbc_osd1_block"; + num_in_links = /bits/ 8 <0x1>; + in_links = <0 &osd1_block>; + num_out_links = /bits/ 8 <0x1>; + out_links = <0 &osd_blend_block>; + }; + afbc_osd2_block: block@4 { + id = /bits/ 8 ; + index = /bits/ 8 <1>; + type = /bits/ 8 <1>; + block_name = "afbc_osd2_block"; + num_in_links = /bits/ 8 <0x1>; + in_links = <0 &osd2_block>; + num_out_links = /bits/ 8 <0x1>; + out_links = <0 &scaler_osd2_block>; + }; + scaler_osd1_block: block@6 { + id = /bits/ 8 ; + index = /bits/ 8 <0>; + type = /bits/ 8 <2>; + block_name = "scaler_osd1_block"; + num_in_links = /bits/ 8 <0x1>; + in_links = <0 &osd1_hdr_dolby_block>; + num_out_links = /bits/ 8 <0x1>; + out_links = <0 &vpp_postblend_block>; + }; + scaler_osd2_block: block@7 { + id = /bits/ 8 ; + index = /bits/ 8 <1>; + type = /bits/ 8 <2>; + block_name = "scaler_osd2_block"; + num_in_links = /bits/ 8 <0x1>; + in_links = <0 &afbc_osd2_block>; + num_out_links = /bits/ 8 <0x1>; + out_links = <2 &osd_blend_block>; + }; + osd_blend_block: block@9 { + id = /bits/ 8 ; + block_name = "osd_blend_block"; + type = /bits/ 8 <3>; + num_in_links = /bits/ 8 <0x2>; + in_links = <0 &afbc_osd1_block>, + <0 &scaler_osd2_block>; + num_out_links = /bits/ 8 <0x2>; + out_links = <0 &osd1_hdr_dolby_block>, + <1 &vpp_postblend_block>; + }; + osd1_hdr_dolby_block: block@10 { + id = /bits/ 8 ; + block_name = "osd1_hdr_dolby_block"; + type = /bits/ 8 <4>; + num_in_links = /bits/ 8 <0x1>; + in_links = <0 &osd_blend_block>; + num_out_links = /bits/ 8 <0x1>; + out_links = <0 &scaler_osd1_block>; + }; + vpp_postblend_block: block@12 { + id = /bits/ 8 ; + block_name = "vpp_postblend_block"; + type = /bits/ 8 <6>; + num_in_links = /bits/ 8 <0x2>; + in_links = <0 &scaler_osd1_block>, + <1 &osd_blend_block>; + num_out_links = <0x0>; + }; + video1_block: block@13 { + id = /bits/ 8 ; + index = /bits/ 8 <0>; + type = /bits/ 8 <7>; + block_name = "video1_block"; + num_in_links = /bits/ 8 <0x0>; + num_out_links = /bits/ 8 <0x0>; + }; + video2_block: block@14 { + id = /bits/ 8 ; + index = /bits/ 8 <1>; + type = /bits/ 8 <7>; + block_name = "video2_block"; + num_in_links = /bits/ 8 <0x0>; + num_out_links = /bits/ 8 <0x0>; + }; + }; + }; + + vpu_hw_para: vpu_hw_para@0 { + osd_ver = /bits/ 8 <0x2>; + afbc_type = /bits/ 8 <0x2>; + has_deband = /bits/ 8 <0x1>; + has_lut = /bits/ 8 <0x1>; + has_rdma = /bits/ 8 <0x1>; + osd_fifo_len = /bits/ 8 <64>; + vpp_fifo_len = /bits/ 32 <0xfff>; + }; + }; +}; + +&amhdmitx { + ports { + port { + #address-cells = <1>; + #size-cells = <0>; + hdmitx_to_drm: endpoint@0 { + reg = <0>; + remote-endpoint = <&drm_to_hdmitx>; + }; + }; + }; +}; + +&dummy_venc { + ports { + port { + #address-cells = <1>; + #size-cells = <0>; +// dummyl_to_drm: endpoint@0 { +// reg = <0>; +// remote-endpoint = <&drm_to_dummyl>; +// }; + }; + }; +}; diff --git a/arch/arm/boot/dts/amlogic/s7_pxp.dts b/arch/arm/boot/dts/amlogic/s7_pxp.dts index f32c01094..81a1e3530 100644 --- a/arch/arm/boot/dts/amlogic/s7_pxp.dts +++ b/arch/arm/boot/dts/amlogic/s7_pxp.dts @@ -6,7 +6,7 @@ /dts-v1/; #include "meson-s7.dtsi" -#include "mesons4d_drm.dtsi" +#include "mesons7_drm.dtsi" / { amlogic-dt-id = "s7_pxp"; compatible = "s7_pxp"; @@ -1544,7 +1544,7 @@ }; &drm_vpu { - status = "disabled"; + status = "okay"; logo_addr = "0x1fc00000"; }; @@ -1565,10 +1565,6 @@ status = "disabled"; }; -&drm_lcd { - status = "disabled"; -}; - /*if you want to use vdin just modify status to "ok"*/ &vdin0 { /*compatible = "amlogic, vdin-sc2";*/ diff --git a/drivers/drm/meson_crtc.c b/drivers/drm/meson_crtc.c index 25e8f0062..9cc958aa4 100644 --- a/drivers/drm/meson_crtc.c +++ b/drivers/drm/meson_crtc.c @@ -26,6 +26,7 @@ MODULE_PARM_DESC(crtc_force_hint, "\n force modesetting hint\n"); module_param(crtc_force_hint, int, 0644); int gamma_ctl = 1; +int meson_gamma_ctl = -1; #ifndef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION bool get_amdv_mode(void) @@ -1183,7 +1184,10 @@ struct am_meson_crtc *meson_crtc_bind(struct meson_drm *priv, int idx) meson_vpu_reg_handle_register(sub_pipeline); #endif #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT - if (gamma_ctl) { + ret = of_property_read_u32(priv->dev->of_node, "gamma_ctl", &meson_gamma_ctl); + if (!gamma_ctl || !meson_gamma_ctl) { + DRM_INFO("skip gamma init\n"); + } else { amvecm_drm_init(0); gamma_lut_size = amvecm_drm_get_gamma_size(0); drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size); diff --git a/drivers/drm/meson_vpu.c b/drivers/drm/meson_vpu.c index 055712541..080f7616c 100644 --- a/drivers/drm/meson_vpu.c +++ b/drivers/drm/meson_vpu.c @@ -343,6 +343,18 @@ static const struct meson_vpu_data vpu_g12b_data = { .dv_ops = &db_ops, .postblend_ops = &g12b_postblend_ops, .video_ops = &video_ops, +}; + +static const struct meson_vpu_data vpu_s7_data = { + .pipe_ops = &g12a_vpu_pipeline_ops, + .osd_ops = &t7_osd_ops, + .afbc_ops = &s7_afbc_ops, + .scaler_ops = &scaler_ops, + .osdblend_ops = &osdblend_ops, + .hdr_ops = &hdr_ops, + .dv_ops = &db_ops, + .postblend_ops = &s7_postblend_ops, + .video_ops = &video_ops, .osd_formats = &osd_formats, .video_formats = &video_formats, }; @@ -543,6 +555,8 @@ static const struct of_device_id am_meson_vpu_driver_dt_match[] = { .data = &vpu_txhd2_data,}, {.compatible = "amlogic, meson-t5m-vpu", .data = &vpu_t5m_data,}, + {.compatible = "amlogic, meson-s7-vpu", + .data = &vpu_s7_data,}, #endif {.compatible = "amlogic, meson-s1a-vpu", .data = &vpu_s1a_data,}, diff --git a/drivers/drm/meson_vpu_pipeline.h b/drivers/drm/meson_vpu_pipeline.h index bd1e63483..6ab6a5fc0 100644 --- a/drivers/drm/meson_vpu_pipeline.h +++ b/drivers/drm/meson_vpu_pipeline.h @@ -350,6 +350,7 @@ struct meson_vpu_afbc { struct afbc_osd_reg_s *afbc_regs; struct afbc_status_reg_s *status_regs; u32 num_of_4k_osd; + int shift_bits; }; struct meson_vpu_afbc_state { @@ -725,6 +726,8 @@ extern struct meson_vpu_block_ops s5_postblend_ops; extern struct meson_vpu_block_ops slice2ppc_ops; extern struct meson_vpu_block_ops t3x_osdblend_ops; extern struct meson_vpu_block_ops t3x_afbc_ops; +extern struct meson_vpu_block_ops s7_afbc_ops; +extern struct meson_vpu_block_ops s7_postblend_ops; extern struct meson_vpu_block_ops txhd2_osdblend_ops; extern struct meson_vpu_block_ops txhd2_postblend_ops; diff --git a/drivers/drm/vpu-hw/meson_osd_afbc.c b/drivers/drm/vpu-hw/meson_osd_afbc.c index 1c1136803..a04195a1d 100644 --- a/drivers/drm/vpu-hw/meson_osd_afbc.c +++ b/drivers/drm/vpu-hw/meson_osd_afbc.c @@ -611,8 +611,13 @@ static void g12a_osd_afbc_set_state(struct meson_vpu_block *vblk, line_stride, 0, 12); /* set frame addr */ - reg_ops->rdma_write_reg(osd_reg->viu_osd_blk1_cfg_w4, - out_addr & 0xffffffff); + if (afbc->shift_bits) { + reg_ops->rdma_write_reg(osd_reg->viu_osd_blk1_cfg_w4, + (out_addr >> 4) & 0xffffffff); + } else { + reg_ops->rdma_write_reg(osd_reg->viu_osd_blk1_cfg_w4, + out_addr & 0xffffffff); + } /* set afbc color reorder and mali src*/ reg_ops->rdma_write_reg_bits(osd_reg->viu_osd_mali_unpack_ctrl, @@ -1550,6 +1555,23 @@ static void osd_afbc_hw_init(struct meson_vpu_block *vblk) } #ifndef CONFIG_AMLOGIC_ZAPPER_CUT +static void s7_osd_afbc_hw_init(struct meson_vpu_block *vblk) +{ + struct meson_vpu_pipeline *pipeline = vblk->pipeline; + struct meson_vpu_afbc *afbc = to_afbc_block(vblk); + + afbc->afbc_regs = &afbc_osd_regs[vblk->index]; + afbc->status_regs = &afbc_status_regs; + afbc->shift_bits = 1; + + pipeline->subs[0].reg_ops->rdma_write_reg_bits(MALI_AFBCD_TOP_CTRL, 0, 23, 1); + + /* disable osd1 afbc */ + osd_afbc_enable(vblk, pipeline->subs[0].reg_ops, vblk->index, 0); + + DRM_DEBUG("%s hw_init called.\n", afbc->base.name); +} + static void t7_osd_afbc_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_afbc *afbc = to_afbc_block(vblk); @@ -1656,6 +1678,15 @@ struct meson_vpu_block_ops afbc_ops = { }; #ifndef CONFIG_AMLOGIC_ZAPPER_CUT +struct meson_vpu_block_ops s7_afbc_ops = { + .check_state = osd_afbc_check_state, + .update_state = g12a_osd_afbc_set_state, + .enable = osd_afbc_hw_enable, + .disable = osd_afbc_hw_disable, + .dump_register = osd_afbc_dump_register, + .init = s7_osd_afbc_hw_init, +}; + struct meson_vpu_block_ops t7_afbc_ops = { .check_state = osd_afbc_check_state, .update_state = t7_osd_afbc_set_state, diff --git a/drivers/drm/vpu-hw/meson_vpu_postblend.c b/drivers/drm/vpu-hw/meson_vpu_postblend.c index 8fe9510ea..3d7fd2aeb 100644 --- a/drivers/drm/vpu-hw/meson_vpu_postblend.c +++ b/drivers/drm/vpu-hw/meson_vpu_postblend.c @@ -1159,6 +1159,31 @@ static void txhd2_postblend_hw_init(struct meson_vpu_block *vblk) MESON_DRM_BLOCK("%s hw_init called.\n", postblend->base.name); } +static void s7_postblend_hw_init(struct meson_vpu_block *vblk) +{ + struct meson_vpu_postblend *postblend = to_postblend_block(vblk); + struct rdma_reg_ops *reg_ops = vblk->pipeline->subs[0].reg_ops; + //s7 pxp bringup VPU workaround + reg_ops->rdma_write_reg(VPU_RDARB_MODE_L2C1, 0x0); + //s7 pxp bringup enable dolby bypass + reg_ops->rdma_write_reg(DOLBY_PATH_CTRL, 0x0c880c0f); + //s7 pxp bringup HDR workaround + reg_ops->rdma_write_reg(OSD1_HDR2_CTRL, 0x00010000); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_COEF00_01, 0x00bb0275); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_COEF02_10, 0x003f1f99); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_COEF11_12, 0x1ea601c2); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_COEF20_21, 0x01c21e67); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_COEF22, 0x00001fd7); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_OFFSET0_1, 0x00400200); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_OFFSET2, 0x00000200); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_PRE_OFFSET0_1, 0x00000000); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_PRE_OFFSET2, 0x00000000); + reg_ops->rdma_write_reg(OSD1_HDR2_MATRIXI_EN_CTRL, 0x1); + + postblend->reg = &postblend_reg; + DRM_DEBUG("%s hw_init called.\n", postblend->base.name); +} + static void t7_postblend_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_postblend *postblend = to_postblend_block(vblk); @@ -1237,6 +1262,15 @@ struct meson_vpu_block_ops g12b_postblend_ops = { .init = postblend_hw_init, }; +struct meson_vpu_block_ops s7_postblend_ops = { + .check_state = postblend_check_state, + .update_state = postblend_set_state, + .enable = postblend_hw_enable, + .disable = postblend_hw_disable, + .dump_register = postblend_dump_register, + .init = s7_postblend_hw_init, +}; + struct meson_vpu_block_ops t7_postblend_ops = { .check_state = postblend_check_state, .update_state = t7_postblend_set_state, diff --git a/drivers/drm/vpu-hw/meson_vpu_postblend.h b/drivers/drm/vpu-hw/meson_vpu_postblend.h index e80c4eccb..6a2f68d92 100644 --- a/drivers/drm/vpu-hw/meson_vpu_postblend.h +++ b/drivers/drm/vpu-hw/meson_vpu_postblend.h @@ -108,6 +108,18 @@ #define VPP_RO_CRCSUM 0x1db2 #define VPP_CRC_CHK 0x1db3 +/* s7 pxp bring hdr register about workaround */ +#define OSD1_HDR2_MATRIXI_COEF00_01 0x38a2 +#define OSD1_HDR2_MATRIXI_COEF02_10 0x38a3 +#define OSD1_HDR2_MATRIXI_COEF11_12 0x38a4 +#define OSD1_HDR2_MATRIXI_COEF20_21 0x38a5 +#define OSD1_HDR2_MATRIXI_COEF22 0x38a6 +#define OSD1_HDR2_MATRIXI_OFFSET0_1 0x38aa +#define OSD1_HDR2_MATRIXI_OFFSET2 0x38ab +#define OSD1_HDR2_MATRIXI_PRE_OFFSET0_1 0x38ac +#define OSD1_HDR2_MATRIXI_PRE_OFFSET2 0x38ad +#define OSD1_HDR2_MATRIXI_EN_CTRL 0x38db + #define VPP_POST_BLEND_REF_ZORDER 128 /* txhd2 loopback register */ diff --git a/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c b/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c index 6ff08f95d..832ed01ef 100644 --- a/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c +++ b/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c @@ -456,7 +456,10 @@ static void video_set_state(struct meson_vpu_block *vblk, vf_info.release_fence = video->fence; video_vfm_convert_to_vfminfo(mvvs, &vf_info); vf_info.phy_addr[0] = mvvs->phy_addr[0]; - vf_info.phy_addr[1] = mvvs->phy_addr[1]; + if (!mvvs->phy_addr[1]) + vf_info.phy_addr[1] = mvvs->phy_addr[0] + byte_stride * src_h; + else + vf_info.phy_addr[1] = mvvs->phy_addr[1]; vf_info.reserved[0] = video_type_get(pixel_format); dma_resv_add_excl_fence(vf_info.dmabuf->resv, vf_info.release_fence); #ifdef CONFIG_AMLOGIC_VIDEO_COMPOSER