diff options
| -rw-r--r-- | Documentation/devicetree/bindings/gpu/st,stih4xx.txt | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/Makefile | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_compositor.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_drm_crtc.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_drm_plane.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_hqvdp.c | 1072 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_hqvdp.h | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_hqvdp_lut.h | 373 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_layer.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_layer.h | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/sti/sti_mixer.c | 2 |
12 files changed, 1513 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/gpu/st,stih4xx.txt b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt index 32cfc7b7631b..c99eb34e640b 100644 --- a/Documentation/devicetree/bindings/gpu/st,stih4xx.txt +++ b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt | |||
| @@ -83,6 +83,22 @@ sti-hda: | |||
| 83 | - clock-names: names of the clocks listed in clocks property in the same | 83 | - clock-names: names of the clocks listed in clocks property in the same |
| 84 | order. | 84 | order. |
| 85 | 85 | ||
| 86 | sti-hqvdp: | ||
| 87 | must be a child of sti-display-subsystem | ||
| 88 | Required properties: | ||
| 89 | - compatible: "st,stih<chip>-hqvdp" | ||
| 90 | - reg: Physical base address of the IP registers and length of memory mapped region. | ||
| 91 | - clocks: from common clock binding: handle hardware IP needed clocks, the | ||
| 92 | number of clocks may depend of the SoC type. | ||
| 93 | See ../clocks/clock-bindings.txt for details. | ||
| 94 | - clock-names: names of the clocks listed in clocks property in the same | ||
| 95 | order. | ||
| 96 | - resets: resets to be used by the device | ||
| 97 | See ../reset/reset.txt for details. | ||
| 98 | - reset-names: names of the resets listed in resets property in the same | ||
| 99 | order. | ||
| 100 | - st,vtg: phandle on vtg main device node. | ||
| 101 | |||
| 86 | Example: | 102 | Example: |
| 87 | 103 | ||
| 88 | / { | 104 | / { |
| @@ -183,6 +199,16 @@ Example: | |||
| 183 | clocks = <&clockgen_c_vcc CLK_S_PIX_HD>, <&clockgen_c_vcc CLK_S_HDDAC>; | 199 | clocks = <&clockgen_c_vcc CLK_S_PIX_HD>, <&clockgen_c_vcc CLK_S_HDDAC>; |
| 184 | }; | 200 | }; |
| 185 | }; | 201 | }; |
| 202 | |||
| 203 | sti-hqvdp@9c000000 { | ||
| 204 | compatible = "st,stih407-hqvdp"; | ||
| 205 | reg = <0x9C00000 0x100000>; | ||
| 206 | clock-names = "hqvdp", "pix_main"; | ||
| 207 | clocks = <&clk_s_c0_flexgen CLK_MAIN_DISP>, <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>; | ||
| 208 | reset-names = "hqvdp"; | ||
| 209 | resets = <&softreset STIH407_HDQVDP_SOFTRESET>; | ||
| 210 | st,vtg = <&vtg_main>; | ||
| 211 | }; | ||
| 186 | }; | 212 | }; |
| 187 | ... | 213 | ... |
| 188 | }; | 214 | }; |
diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig index ae8850f3e63b..d6d6b705b8c1 100644 --- a/drivers/gpu/drm/sti/Kconfig +++ b/drivers/gpu/drm/sti/Kconfig | |||
| @@ -5,6 +5,7 @@ config DRM_STI | |||
| 5 | select DRM_KMS_HELPER | 5 | select DRM_KMS_HELPER |
| 6 | select DRM_GEM_CMA_HELPER | 6 | select DRM_GEM_CMA_HELPER |
| 7 | select DRM_KMS_CMA_HELPER | 7 | select DRM_KMS_CMA_HELPER |
| 8 | select FW_LOADER_USER_HELPER_FALLBACK | ||
| 8 | help | 9 | help |
| 9 | Choose this option to enable DRM on STM stiH41x chipset | 10 | Choose this option to enable DRM on STM stiH41x chipset |
| 10 | 11 | ||
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile index d6128f7fa12c..6ba9d27c1b90 100644 --- a/drivers/gpu/drm/sti/Makefile +++ b/drivers/gpu/drm/sti/Makefile | |||
| @@ -19,4 +19,5 @@ obj-$(CONFIG_DRM_STI) = \ | |||
| 19 | sti_hda.o \ | 19 | sti_hda.o \ |
| 20 | sti_tvout.o \ | 20 | sti_tvout.o \ |
| 21 | sticompositor.o \ | 21 | sticompositor.o \ |
| 22 | sti_drm_drv.o \ No newline at end of file | 22 | sti_hqvdp.o \ |
| 23 | sti_drm_drv.o | ||
diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c index b9415b3f3720..c5cf4aea9694 100644 --- a/drivers/gpu/drm/sti/sti_compositor.c +++ b/drivers/gpu/drm/sti/sti_compositor.c | |||
| @@ -122,6 +122,7 @@ static int sti_compositor_bind(struct device *dev, struct device *master, | |||
| 122 | plane++; | 122 | plane++; |
| 123 | break; | 123 | break; |
| 124 | case STI_BCK: | 124 | case STI_BCK: |
| 125 | case STI_VDP: | ||
| 125 | break; | 126 | break; |
| 126 | } | 127 | } |
| 127 | 128 | ||
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.c b/drivers/gpu/drm/sti/sti_drm_crtc.c index 928b44fd3717..4c651c200f20 100644 --- a/drivers/gpu/drm/sti/sti_drm_crtc.c +++ b/drivers/gpu/drm/sti/sti_drm_crtc.c | |||
| @@ -148,7 +148,8 @@ sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
| 148 | w = crtc->primary->fb->width - x; | 148 | w = crtc->primary->fb->width - x; |
| 149 | h = crtc->primary->fb->height - y; | 149 | h = crtc->primary->fb->height - y; |
| 150 | 150 | ||
| 151 | return sti_layer_prepare(layer, crtc->primary->fb, &crtc->mode, | 151 | return sti_layer_prepare(layer, crtc, |
| 152 | crtc->primary->fb, &crtc->mode, | ||
| 152 | mixer->id, 0, 0, w, h, x, y, w, h); | 153 | mixer->id, 0, 0, w, h, x, y, w, h); |
| 153 | } | 154 | } |
| 154 | 155 | ||
| @@ -175,7 +176,8 @@ static int sti_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 175 | w = crtc->primary->fb->width - crtc->x; | 176 | w = crtc->primary->fb->width - crtc->x; |
| 176 | h = crtc->primary->fb->height - crtc->y; | 177 | h = crtc->primary->fb->height - crtc->y; |
| 177 | 178 | ||
| 178 | ret = sti_layer_prepare(layer, crtc->primary->fb, &crtc->mode, | 179 | ret = sti_layer_prepare(layer, crtc, |
| 180 | crtc->primary->fb, &crtc->mode, | ||
| 179 | mixer->id, 0, 0, w, h, | 181 | mixer->id, 0, 0, w, h, |
| 180 | crtc->x, crtc->y, w, h); | 182 | crtc->x, crtc->y, w, h); |
| 181 | if (ret) { | 183 | if (ret) { |
diff --git a/drivers/gpu/drm/sti/sti_drm_plane.c b/drivers/gpu/drm/sti/sti_drm_plane.c index f4118d4cac22..c9dd0e57cac1 100644 --- a/drivers/gpu/drm/sti/sti_drm_plane.c +++ b/drivers/gpu/drm/sti/sti_drm_plane.c | |||
| @@ -45,7 +45,8 @@ sti_drm_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | /* src_x are in 16.16 format. */ | 47 | /* src_x are in 16.16 format. */ |
| 48 | res = sti_layer_prepare(layer, fb, &crtc->mode, mixer->id, | 48 | res = sti_layer_prepare(layer, crtc, fb, |
| 49 | &crtc->mode, mixer->id, | ||
| 49 | crtc_x, crtc_y, crtc_w, crtc_h, | 50 | crtc_x, crtc_y, crtc_w, crtc_h, |
| 50 | src_x >> 16, src_y >> 16, | 51 | src_x >> 16, src_y >> 16, |
| 51 | src_w >> 16, src_h >> 16); | 52 | src_w >> 16, src_h >> 16); |
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c new file mode 100644 index 000000000000..200d02014575 --- /dev/null +++ b/drivers/gpu/drm/sti/sti_hqvdp.c | |||
| @@ -0,0 +1,1072 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) STMicroelectronics SA 2014 | ||
| 3 | * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics. | ||
| 4 | * License terms: GNU General Public License (GPL), version 2 | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/clk.h> | ||
| 8 | #include <linux/component.h> | ||
| 9 | #include <linux/firmware.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/reset.h> | ||
| 13 | |||
| 14 | #include <drm/drmP.h> | ||
| 15 | |||
| 16 | #include "sti_drm_plane.h" | ||
| 17 | #include "sti_hqvdp.h" | ||
| 18 | #include "sti_hqvdp_lut.h" | ||
| 19 | #include "sti_layer.h" | ||
| 20 | #include "sti_vtg.h" | ||
| 21 | |||
| 22 | /* Firmware name */ | ||
| 23 | #define HQVDP_FMW_NAME "hqvdp-stih407.bin" | ||
| 24 | |||
| 25 | /* Regs address */ | ||
| 26 | #define HQVDP_DMEM 0x00000000 /* 0x00000000 */ | ||
| 27 | #define HQVDP_PMEM 0x00040000 /* 0x00040000 */ | ||
| 28 | #define HQVDP_RD_PLUG 0x000E0000 /* 0x000E0000 */ | ||
| 29 | #define HQVDP_RD_PLUG_CONTROL (HQVDP_RD_PLUG + 0x1000) /* 0x000E1000 */ | ||
| 30 | #define HQVDP_RD_PLUG_PAGE_SIZE (HQVDP_RD_PLUG + 0x1004) /* 0x000E1004 */ | ||
| 31 | #define HQVDP_RD_PLUG_MIN_OPC (HQVDP_RD_PLUG + 0x1008) /* 0x000E1008 */ | ||
| 32 | #define HQVDP_RD_PLUG_MAX_OPC (HQVDP_RD_PLUG + 0x100C) /* 0x000E100C */ | ||
| 33 | #define HQVDP_RD_PLUG_MAX_CHK (HQVDP_RD_PLUG + 0x1010) /* 0x000E1010 */ | ||
| 34 | #define HQVDP_RD_PLUG_MAX_MSG (HQVDP_RD_PLUG + 0x1014) /* 0x000E1014 */ | ||
| 35 | #define HQVDP_RD_PLUG_MIN_SPACE (HQVDP_RD_PLUG + 0x1018) /* 0x000E1018 */ | ||
| 36 | #define HQVDP_WR_PLUG 0x000E2000 /* 0x000E2000 */ | ||
| 37 | #define HQVDP_WR_PLUG_CONTROL (HQVDP_WR_PLUG + 0x1000) /* 0x000E3000 */ | ||
| 38 | #define HQVDP_WR_PLUG_PAGE_SIZE (HQVDP_WR_PLUG + 0x1004) /* 0x000E3004 */ | ||
| 39 | #define HQVDP_WR_PLUG_MIN_OPC (HQVDP_WR_PLUG + 0x1008) /* 0x000E3008 */ | ||
| 40 | #define HQVDP_WR_PLUG_MAX_OPC (HQVDP_WR_PLUG + 0x100C) /* 0x000E300C */ | ||
| 41 | #define HQVDP_WR_PLUG_MAX_CHK (HQVDP_WR_PLUG + 0x1010) /* 0x000E3010 */ | ||
| 42 | #define HQVDP_WR_PLUG_MAX_MSG (HQVDP_WR_PLUG + 0x1014) /* 0x000E3014 */ | ||
| 43 | #define HQVDP_WR_PLUG_MIN_SPACE (HQVDP_WR_PLUG + 0x1018) /* 0x000E3018 */ | ||
| 44 | #define HQVDP_MBX 0x000E4000 /* 0x000E4000 */ | ||
| 45 | #define HQVDP_MBX_IRQ_TO_XP70 (HQVDP_MBX + 0x0000) /* 0x000E4000 */ | ||
| 46 | #define HQVDP_MBX_INFO_HOST (HQVDP_MBX + 0x0004) /* 0x000E4004 */ | ||
| 47 | #define HQVDP_MBX_IRQ_TO_HOST (HQVDP_MBX + 0x0008) /* 0x000E4008 */ | ||
| 48 | #define HQVDP_MBX_INFO_XP70 (HQVDP_MBX + 0x000C) /* 0x000E400C */ | ||
| 49 | #define HQVDP_MBX_SW_RESET_CTRL (HQVDP_MBX + 0x0010) /* 0x000E4010 */ | ||
| 50 | #define HQVDP_MBX_STARTUP_CTRL1 (HQVDP_MBX + 0x0014) /* 0x000E4014 */ | ||
| 51 | #define HQVDP_MBX_STARTUP_CTRL2 (HQVDP_MBX + 0x0018) /* 0x000E4018 */ | ||
| 52 | #define HQVDP_MBX_GP_STATUS (HQVDP_MBX + 0x001C) /* 0x000E401C */ | ||
| 53 | #define HQVDP_MBX_NEXT_CMD (HQVDP_MBX + 0x0020) /* 0x000E4020 */ | ||
| 54 | #define HQVDP_MBX_CURRENT_CMD (HQVDP_MBX + 0x0024) /* 0x000E4024 */ | ||
| 55 | #define HQVDP_MBX_SOFT_VSYNC (HQVDP_MBX + 0x0028) /* 0x000E4028 */ | ||
| 56 | |||
| 57 | /* Plugs config */ | ||
| 58 | #define PLUG_CONTROL_ENABLE 0x00000001 | ||
| 59 | #define PLUG_PAGE_SIZE_256 0x00000002 | ||
| 60 | #define PLUG_MIN_OPC_8 0x00000003 | ||
| 61 | #define PLUG_MAX_OPC_64 0x00000006 | ||
| 62 | #define PLUG_MAX_CHK_2X 0x00000001 | ||
| 63 | #define PLUG_MAX_MSG_1X 0x00000000 | ||
| 64 | #define PLUG_MIN_SPACE_1 0x00000000 | ||
| 65 | |||
| 66 | /* SW reset CTRL */ | ||
| 67 | #define SW_RESET_CTRL_FULL BIT(0) | ||
| 68 | #define SW_RESET_CTRL_CORE BIT(1) | ||
| 69 | |||
| 70 | /* Startup ctrl 1 */ | ||
| 71 | #define STARTUP_CTRL1_RST_DONE BIT(0) | ||
| 72 | #define STARTUP_CTRL1_AUTH_IDLE BIT(2) | ||
| 73 | |||
| 74 | /* Startup ctrl 2 */ | ||
| 75 | #define STARTUP_CTRL2_FETCH_EN BIT(1) | ||
| 76 | |||
| 77 | /* Info xP70 */ | ||
| 78 | #define INFO_XP70_FW_READY BIT(15) | ||
| 79 | #define INFO_XP70_FW_PROCESSING BIT(14) | ||
| 80 | #define INFO_XP70_FW_INITQUEUES BIT(13) | ||
| 81 | |||
| 82 | /* SOFT_VSYNC */ | ||
| 83 | #define SOFT_VSYNC_HW 0x00000000 | ||
| 84 | #define SOFT_VSYNC_SW_CMD 0x00000001 | ||
| 85 | #define SOFT_VSYNC_SW_CTRL_IRQ 0x00000003 | ||
| 86 | |||
| 87 | /* Reset & boot poll config */ | ||
| 88 | #define POLL_MAX_ATTEMPT 50 | ||
| 89 | #define POLL_DELAY_MS 20 | ||
| 90 | |||
| 91 | #define SCALE_FACTOR 8192 | ||
| 92 | #define SCALE_MAX_FOR_LEG_LUT_F 4096 | ||
| 93 | #define SCALE_MAX_FOR_LEG_LUT_E 4915 | ||
| 94 | #define SCALE_MAX_FOR_LEG_LUT_D 6654 | ||
| 95 | #define SCALE_MAX_FOR_LEG_LUT_C 8192 | ||
| 96 | |||
| 97 | enum sti_hvsrc_orient { | ||
| 98 | HVSRC_HORI, | ||
| 99 | HVSRC_VERT | ||
| 100 | }; | ||
| 101 | |||
| 102 | /* Command structures */ | ||
| 103 | struct sti_hqvdp_top { | ||
| 104 | u32 config; | ||
| 105 | u32 mem_format; | ||
| 106 | u32 current_luma; | ||
| 107 | u32 current_enh_luma; | ||
| 108 | u32 current_right_luma; | ||
| 109 | u32 current_enh_right_luma; | ||
| 110 | u32 current_chroma; | ||
| 111 | u32 current_enh_chroma; | ||
| 112 | u32 current_right_chroma; | ||
| 113 | u32 current_enh_right_chroma; | ||
| 114 | u32 output_luma; | ||
| 115 | u32 output_chroma; | ||
| 116 | u32 luma_src_pitch; | ||
| 117 | u32 luma_enh_src_pitch; | ||
| 118 | u32 luma_right_src_pitch; | ||
| 119 | u32 luma_enh_right_src_pitch; | ||
| 120 | u32 chroma_src_pitch; | ||
| 121 | u32 chroma_enh_src_pitch; | ||
| 122 | u32 chroma_right_src_pitch; | ||
| 123 | u32 chroma_enh_right_src_pitch; | ||
| 124 | u32 luma_processed_pitch; | ||
| 125 | u32 chroma_processed_pitch; | ||
| 126 | u32 input_frame_size; | ||
| 127 | u32 input_viewport_ori; | ||
| 128 | u32 input_viewport_ori_right; | ||
| 129 | u32 input_viewport_size; | ||
| 130 | u32 left_view_border_width; | ||
| 131 | u32 right_view_border_width; | ||
| 132 | u32 left_view_3d_offset_width; | ||
| 133 | u32 right_view_3d_offset_width; | ||
| 134 | u32 side_stripe_color; | ||
| 135 | u32 crc_reset_ctrl; | ||
| 136 | }; | ||
| 137 | |||
| 138 | /* Configs for interlaced : no IT, no pass thru, 3 fields */ | ||
| 139 | #define TOP_CONFIG_INTER_BTM 0x00000000 | ||
| 140 | #define TOP_CONFIG_INTER_TOP 0x00000002 | ||
| 141 | |||
| 142 | /* Config for progressive : no IT, no pass thru, 3 fields */ | ||
| 143 | #define TOP_CONFIG_PROGRESSIVE 0x00000001 | ||
| 144 | |||
| 145 | /* Default MemFormat: in=420_raster_dual out=444_raster;opaque Mem2Tv mode */ | ||
| 146 | #define TOP_MEM_FORMAT_DFLT 0x00018060 | ||
| 147 | |||
| 148 | /* Min/Max size */ | ||
| 149 | #define MAX_WIDTH 0x1FFF | ||
| 150 | #define MAX_HEIGHT 0x0FFF | ||
| 151 | #define MIN_WIDTH 0x0030 | ||
| 152 | #define MIN_HEIGHT 0x0010 | ||
| 153 | |||
| 154 | struct sti_hqvdp_vc1re { | ||
| 155 | u32 ctrl_prv_csdi; | ||
| 156 | u32 ctrl_cur_csdi; | ||
| 157 | u32 ctrl_nxt_csdi; | ||
| 158 | u32 ctrl_cur_fmd; | ||
| 159 | u32 ctrl_nxt_fmd; | ||
| 160 | }; | ||
| 161 | |||
| 162 | struct sti_hqvdp_fmd { | ||
| 163 | u32 config; | ||
| 164 | u32 viewport_ori; | ||
| 165 | u32 viewport_size; | ||
| 166 | u32 next_next_luma; | ||
| 167 | u32 next_next_right_luma; | ||
| 168 | u32 next_next_next_luma; | ||
| 169 | u32 next_next_next_right_luma; | ||
| 170 | u32 threshold_scd; | ||
| 171 | u32 threshold_rfd; | ||
| 172 | u32 threshold_move; | ||
| 173 | u32 threshold_cfd; | ||
| 174 | }; | ||
| 175 | |||
| 176 | struct sti_hqvdp_csdi { | ||
| 177 | u32 config; | ||
| 178 | u32 config2; | ||
| 179 | u32 dcdi_config; | ||
| 180 | u32 prev_luma; | ||
| 181 | u32 prev_enh_luma; | ||
| 182 | u32 prev_right_luma; | ||
| 183 | u32 prev_enh_right_luma; | ||
| 184 | u32 next_luma; | ||
| 185 | u32 next_enh_luma; | ||
| 186 | u32 next_right_luma; | ||
| 187 | u32 next_enh_right_luma; | ||
| 188 | u32 prev_chroma; | ||
| 189 | u32 prev_enh_chroma; | ||
| 190 | u32 prev_right_chroma; | ||
| 191 | u32 prev_enh_right_chroma; | ||
| 192 | u32 next_chroma; | ||
| 193 | u32 next_enh_chroma; | ||
| 194 | u32 next_right_chroma; | ||
| 195 | u32 next_enh_right_chroma; | ||
| 196 | u32 prev_motion; | ||
| 197 | u32 prev_right_motion; | ||
| 198 | u32 cur_motion; | ||
| 199 | u32 cur_right_motion; | ||
| 200 | u32 next_motion; | ||
| 201 | u32 next_right_motion; | ||
| 202 | }; | ||
| 203 | |||
| 204 | /* Config for progressive: by pass */ | ||
| 205 | #define CSDI_CONFIG_PROG 0x00000000 | ||
| 206 | /* Config for directional deinterlacing without motion */ | ||
| 207 | #define CSDI_CONFIG_INTER_DIR 0x00000016 | ||
| 208 | /* Additional configs for fader, blender, motion,... deinterlace algorithms */ | ||
| 209 | #define CSDI_CONFIG2_DFLT 0x000001B3 | ||
| 210 | #define CSDI_DCDI_CONFIG_DFLT 0x00203803 | ||
| 211 | |||
| 212 | struct sti_hqvdp_hvsrc { | ||
| 213 | u32 hor_panoramic_ctrl; | ||
| 214 | u32 output_picture_size; | ||
| 215 | u32 init_horizontal; | ||
| 216 | u32 init_vertical; | ||
| 217 | u32 param_ctrl; | ||
| 218 | u32 yh_coef[NB_COEF]; | ||
| 219 | u32 ch_coef[NB_COEF]; | ||
| 220 | u32 yv_coef[NB_COEF]; | ||
| 221 | u32 cv_coef[NB_COEF]; | ||
| 222 | u32 hori_shift; | ||
| 223 | u32 vert_shift; | ||
| 224 | }; | ||
| 225 | |||
| 226 | /* Default ParamCtrl: all controls enabled */ | ||
| 227 | #define HVSRC_PARAM_CTRL_DFLT 0xFFFFFFFF | ||
| 228 | |||
| 229 | struct sti_hqvdp_iqi { | ||
| 230 | u32 config; | ||
| 231 | u32 demo_wind_size; | ||
| 232 | u32 pk_config; | ||
| 233 | u32 coeff0_coeff1; | ||
| 234 | u32 coeff2_coeff3; | ||
| 235 | u32 coeff4; | ||
| 236 | u32 pk_lut; | ||
| 237 | u32 pk_gain; | ||
| 238 | u32 pk_coring_level; | ||
| 239 | u32 cti_config; | ||
| 240 | u32 le_config; | ||
| 241 | u32 le_lut[64]; | ||
| 242 | u32 con_bri; | ||
| 243 | u32 sat_gain; | ||
| 244 | u32 pxf_conf; | ||
| 245 | u32 default_color; | ||
| 246 | }; | ||
| 247 | |||
| 248 | /* Default Config : IQI bypassed */ | ||
| 249 | #define IQI_CONFIG_DFLT 0x00000001 | ||
| 250 | /* Default Contrast & Brightness gain = 256 */ | ||
| 251 | #define IQI_CON_BRI_DFLT 0x00000100 | ||
| 252 | /* Default Saturation gain = 256 */ | ||
| 253 | #define IQI_SAT_GAIN_DFLT 0x00000100 | ||
| 254 | /* Default PxfConf : P2I bypassed */ | ||
| 255 | #define IQI_PXF_CONF_DFLT 0x00000001 | ||
| 256 | |||
| 257 | struct sti_hqvdp_top_status { | ||
| 258 | u32 processing_time; | ||
| 259 | u32 input_y_crc; | ||
| 260 | u32 input_uv_crc; | ||
| 261 | }; | ||
| 262 | |||
| 263 | struct sti_hqvdp_fmd_status { | ||
| 264 | u32 fmd_repeat_move_status; | ||
| 265 | u32 fmd_scene_count_status; | ||
| 266 | u32 cfd_sum; | ||
| 267 | u32 field_sum; | ||
| 268 | u32 next_y_fmd_crc; | ||
| 269 | u32 next_next_y_fmd_crc; | ||
| 270 | u32 next_next_next_y_fmd_crc; | ||
| 271 | }; | ||
| 272 | |||
| 273 | struct sti_hqvdp_csdi_status { | ||
| 274 | u32 prev_y_csdi_crc; | ||
| 275 | u32 cur_y_csdi_crc; | ||
| 276 | u32 next_y_csdi_crc; | ||
| 277 | u32 prev_uv_csdi_crc; | ||
| 278 | u32 cur_uv_csdi_crc; | ||
| 279 | u32 next_uv_csdi_crc; | ||
| 280 | u32 y_csdi_crc; | ||
| 281 | u32 uv_csdi_crc; | ||
| 282 | u32 uv_cup_crc; | ||
| 283 | u32 mot_csdi_crc; | ||
| 284 | u32 mot_cur_csdi_crc; | ||
| 285 | u32 mot_prev_csdi_crc; | ||
| 286 | }; | ||
| 287 | |||
| 288 | struct sti_hqvdp_hvsrc_status { | ||
| 289 | u32 y_hvsrc_crc; | ||
| 290 | u32 u_hvsrc_crc; | ||
| 291 | u32 v_hvsrc_crc; | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct sti_hqvdp_iqi_status { | ||
| 295 | u32 pxf_it_status; | ||
| 296 | u32 y_iqi_crc; | ||
| 297 | u32 u_iqi_crc; | ||
| 298 | u32 v_iqi_crc; | ||
| 299 | }; | ||
| 300 | |||
| 301 | /* Main commands. We use 2 commands one being processed by the firmware, one | ||
| 302 | * ready to be fetched upon next Vsync*/ | ||
| 303 | #define NB_VDP_CMD 2 | ||
| 304 | |||
| 305 | struct sti_hqvdp_cmd { | ||
| 306 | struct sti_hqvdp_top top; | ||
| 307 | struct sti_hqvdp_vc1re vc1re; | ||
| 308 | struct sti_hqvdp_fmd fmd; | ||
| 309 | struct sti_hqvdp_csdi csdi; | ||
| 310 | struct sti_hqvdp_hvsrc hvsrc; | ||
| 311 | struct sti_hqvdp_iqi iqi; | ||
| 312 | struct sti_hqvdp_top_status top_status; | ||
| 313 | struct sti_hqvdp_fmd_status fmd_status; | ||
| 314 | struct sti_hqvdp_csdi_status csdi_status; | ||
| 315 | struct sti_hqvdp_hvsrc_status hvsrc_status; | ||
| 316 | struct sti_hqvdp_iqi_status iqi_status; | ||
| 317 | }; | ||
| 318 | |||
| 319 | /* | ||
| 320 | * STI HQVDP structure | ||
| 321 | * | ||
| 322 | * @dev: driver device | ||
| 323 | * @drm_dev: the drm device | ||
| 324 | * @regs: registers | ||
| 325 | * @layer: layer structure for hqvdp it self | ||
| 326 | * @vid_plane: VID plug used as link with compositor IP | ||
| 327 | * @clk: IP clock | ||
| 328 | * @clk_pix_main: pix main clock | ||
| 329 | * @reset: reset control | ||
| 330 | * @vtg_nb: notifier to handle VTG Vsync | ||
| 331 | * @btm_field_pending: is there any bottom field (interlaced frame) to display | ||
| 332 | * @curr_field_count: number of field updates | ||
| 333 | * @last_field_count: number of field updates since last fps measure | ||
| 334 | * @hqvdp_cmd: buffer of commands | ||
| 335 | * @hqvdp_cmd_paddr: physical address of hqvdp_cmd | ||
| 336 | * @vtg: vtg for main data path | ||
| 337 | */ | ||
| 338 | struct sti_hqvdp { | ||
| 339 | struct device *dev; | ||
| 340 | struct drm_device *drm_dev; | ||
| 341 | void __iomem *regs; | ||
| 342 | struct sti_layer layer; | ||
| 343 | struct drm_plane *vid_plane; | ||
| 344 | struct clk *clk; | ||
| 345 | struct clk *clk_pix_main; | ||
| 346 | struct reset_control *reset; | ||
| 347 | struct notifier_block vtg_nb; | ||
| 348 | bool btm_field_pending; | ||
| 349 | unsigned int curr_field_count; | ||
| 350 | unsigned int last_field_count; | ||
| 351 | void *hqvdp_cmd; | ||
| 352 | dma_addr_t hqvdp_cmd_paddr; | ||
| 353 | struct sti_vtg *vtg; | ||
| 354 | }; | ||
| 355 | |||
| 356 | #define to_sti_hqvdp(x) container_of(x, struct sti_hqvdp, layer) | ||
| 357 | |||
| 358 | static const uint32_t hqvdp_supported_formats[] = { | ||
| 359 | DRM_FORMAT_NV12, | ||
| 360 | }; | ||
| 361 | |||
| 362 | static const uint32_t *sti_hqvdp_get_formats(struct sti_layer *layer) | ||
| 363 | { | ||
| 364 | return hqvdp_supported_formats; | ||
| 365 | } | ||
| 366 | |||
| 367 | static unsigned int sti_hqvdp_get_nb_formats(struct sti_layer *layer) | ||
| 368 | { | ||
| 369 | return ARRAY_SIZE(hqvdp_supported_formats); | ||
| 370 | } | ||
| 371 | |||
| 372 | /** | ||
| 373 | * sti_hqvdp_get_free_cmd | ||
| 374 | * @hqvdp: hqvdp structure | ||
| 375 | * | ||
| 376 | * Look for a hqvdp_cmd that is not being used (or about to be used) by the FW. | ||
| 377 | * | ||
| 378 | * RETURNS: | ||
| 379 | * the offset of the command to be used. | ||
| 380 | * -1 in error cases | ||
| 381 | */ | ||
| 382 | static int sti_hqvdp_get_free_cmd(struct sti_hqvdp *hqvdp) | ||
| 383 | { | ||
| 384 | int curr_cmd, next_cmd; | ||
| 385 | dma_addr_t cmd = hqvdp->hqvdp_cmd_paddr; | ||
| 386 | int i; | ||
| 387 | |||
| 388 | curr_cmd = readl(hqvdp->regs + HQVDP_MBX_CURRENT_CMD); | ||
| 389 | next_cmd = readl(hqvdp->regs + HQVDP_MBX_NEXT_CMD); | ||
| 390 | |||
| 391 | for (i = 0; i < NB_VDP_CMD; i++) { | ||
| 392 | if ((cmd != curr_cmd) && (cmd != next_cmd)) | ||
| 393 | return i * sizeof(struct sti_hqvdp_cmd); | ||
| 394 | cmd += sizeof(struct sti_hqvdp_cmd); | ||
| 395 | } | ||
| 396 | |||
| 397 | return -1; | ||
| 398 | } | ||
| 399 | |||
| 400 | /** | ||
| 401 | * sti_hqvdp_get_curr_cmd | ||
| 402 | * @hqvdp: hqvdp structure | ||
| 403 | * | ||
| 404 | * Look for the hqvdp_cmd that is being used by the FW. | ||
| 405 | * | ||
| 406 | * RETURNS: | ||
| 407 | * the offset of the command to be used. | ||
| 408 | * -1 in error cases | ||
| 409 | */ | ||
| 410 | static int sti_hqvdp_get_curr_cmd(struct sti_hqvdp *hqvdp) | ||
| 411 | { | ||
| 412 | int curr_cmd; | ||
| 413 | dma_addr_t cmd = hqvdp->hqvdp_cmd_paddr; | ||
| 414 | unsigned int i; | ||
| 415 | |||
| 416 | curr_cmd = readl(hqvdp->regs + HQVDP_MBX_CURRENT_CMD); | ||
| 417 | |||
| 418 | for (i = 0; i < NB_VDP_CMD; i++) { | ||
| 419 | if (cmd == curr_cmd) | ||
| 420 | return i * sizeof(struct sti_hqvdp_cmd); | ||
| 421 | |||
| 422 | cmd += sizeof(struct sti_hqvdp_cmd); | ||
| 423 | } | ||
| 424 | |||
| 425 | return -1; | ||
| 426 | } | ||
| 427 | |||
| 428 | /** | ||
| 429 | * sti_hqvdp_update_hvsrc | ||
| 430 | * @orient: horizontal or vertical | ||
| 431 | * @scale: scaling/zoom factor | ||
| 432 | * @hvsrc: the structure containing the LUT coef | ||
| 433 | * | ||
| 434 | * Update the Y and C Lut coef, as well as the shift param | ||
| 435 | * | ||
| 436 | * RETURNS: | ||
| 437 | * None. | ||
| 438 | */ | ||
| 439 | static void sti_hqvdp_update_hvsrc(enum sti_hvsrc_orient orient, int scale, | ||
| 440 | struct sti_hqvdp_hvsrc *hvsrc) | ||
| 441 | { | ||
| 442 | const int *coef_c, *coef_y; | ||
| 443 | int shift_c, shift_y; | ||
| 444 | |||
| 445 | /* Get the appropriate coef tables */ | ||
| 446 | if (scale < SCALE_MAX_FOR_LEG_LUT_F) { | ||
| 447 | coef_y = coef_lut_f_y_legacy; | ||
| 448 | coef_c = coef_lut_f_c_legacy; | ||
| 449 | shift_y = SHIFT_LUT_F_Y_LEGACY; | ||
| 450 | shift_c = SHIFT_LUT_F_C_LEGACY; | ||
| 451 | } else if (scale < SCALE_MAX_FOR_LEG_LUT_E) { | ||
| 452 | coef_y = coef_lut_e_y_legacy; | ||
| 453 | coef_c = coef_lut_e_c_legacy; | ||
| 454 | shift_y = SHIFT_LUT_E_Y_LEGACY; | ||
| 455 | shift_c = SHIFT_LUT_E_C_LEGACY; | ||
| 456 | } else if (scale < SCALE_MAX_FOR_LEG_LUT_D) { | ||
| 457 | coef_y = coef_lut_d_y_legacy; | ||
| 458 | coef_c = coef_lut_d_c_legacy; | ||
| 459 | shift_y = SHIFT_LUT_D_Y_LEGACY; | ||
| 460 | shift_c = SHIFT_LUT_D_C_LEGACY; | ||
| 461 | } else if (scale < SCALE_MAX_FOR_LEG_LUT_C) { | ||
| 462 | coef_y = coef_lut_c_y_legacy; | ||
| 463 | coef_c = coef_lut_c_c_legacy; | ||
| 464 | shift_y = SHIFT_LUT_C_Y_LEGACY; | ||
| 465 | shift_c = SHIFT_LUT_C_C_LEGACY; | ||
| 466 | } else if (scale == SCALE_MAX_FOR_LEG_LUT_C) { | ||
| 467 | coef_y = coef_c = coef_lut_b; | ||
| 468 | shift_y = shift_c = SHIFT_LUT_B; | ||
| 469 | } else { | ||
| 470 | coef_y = coef_c = coef_lut_a_legacy; | ||
| 471 | shift_y = shift_c = SHIFT_LUT_A_LEGACY; | ||
| 472 | } | ||
| 473 | |||
| 474 | if (orient == HVSRC_HORI) { | ||
| 475 | hvsrc->hori_shift = (shift_c << 16) | shift_y; | ||
| 476 | memcpy(hvsrc->yh_coef, coef_y, sizeof(hvsrc->yh_coef)); | ||
| 477 | memcpy(hvsrc->ch_coef, coef_c, sizeof(hvsrc->ch_coef)); | ||
| 478 | } else { | ||
| 479 | hvsrc->vert_shift = (shift_c << 16) | shift_y; | ||
| 480 | memcpy(hvsrc->yv_coef, coef_y, sizeof(hvsrc->yv_coef)); | ||
| 481 | memcpy(hvsrc->cv_coef, coef_c, sizeof(hvsrc->cv_coef)); | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 485 | /** | ||
| 486 | * sti_hqvdp_check_hw_scaling | ||
| 487 | * @layer: hqvdp layer | ||
| 488 | * | ||
| 489 | * Check if the HW is able to perform the scaling request | ||
| 490 | * The firmware scaling limitation is "CEIL(1/Zy) <= FLOOR(LFW)" where: | ||
| 491 | * Zy = OutputHeight / InputHeight | ||
| 492 | * LFW = (Tx * IPClock) / (MaxNbCycles * Cp) | ||
| 493 | * Tx : Total video mode horizontal resolution | ||
| 494 | * IPClock : HQVDP IP clock (Mhz) | ||
| 495 | * MaxNbCycles: max(InputWidth, OutputWidth) | ||
| 496 | * Cp: Video mode pixel clock (Mhz) | ||
| 497 | * | ||
| 498 | * RETURNS: | ||
| 499 | * True if the HW can scale. | ||
| 500 | */ | ||
| 501 | static bool sti_hqvdp_check_hw_scaling(struct sti_layer *layer) | ||
| 502 | { | ||
| 503 | struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); | ||
| 504 | unsigned long lfw; | ||
| 505 | unsigned int inv_zy; | ||
| 506 | |||
| 507 | lfw = layer->mode->htotal * (clk_get_rate(hqvdp->clk) / 1000000); | ||
| 508 | lfw /= max(layer->src_w, layer->dst_w) * layer->mode->clock / 1000; | ||
| 509 | |||
| 510 | inv_zy = DIV_ROUND_UP(layer->src_h, layer->dst_h); | ||
| 511 | |||
| 512 | return (inv_zy <= lfw) ? true : false; | ||
| 513 | } | ||
| 514 | |||
| 515 | /** | ||
| 516 | * sti_hqvdp_prepare_layer | ||
| 517 | * @layer: hqvdp layer | ||
| 518 | * @first_prepare: true if it is the first time this function is called | ||
| 519 | * | ||
| 520 | * Prepares a command for the firmware | ||
| 521 | * | ||
| 522 | * RETURNS: | ||
| 523 | * 0 on success. | ||
| 524 | */ | ||
| 525 | static int sti_hqvdp_prepare_layer(struct sti_layer *layer, bool first_prepare) | ||
| 526 | { | ||
| 527 | struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); | ||
| 528 | struct sti_hqvdp_cmd *cmd; | ||
| 529 | int scale_h, scale_v; | ||
| 530 | int cmd_offset; | ||
| 531 | |||
| 532 | dev_dbg(hqvdp->dev, "%s %s\n", __func__, sti_layer_to_str(layer)); | ||
| 533 | |||
| 534 | /* prepare and commit VID plane */ | ||
| 535 | hqvdp->vid_plane->funcs->update_plane(hqvdp->vid_plane, | ||
| 536 | layer->crtc, layer->fb, | ||
| 537 | layer->dst_x, layer->dst_y, | ||
| 538 | layer->dst_w, layer->dst_h, | ||
| 539 | layer->src_x, layer->src_y, | ||
| 540 | layer->src_w, layer->src_h); | ||
| 541 | |||
| 542 | cmd_offset = sti_hqvdp_get_free_cmd(hqvdp); | ||
| 543 | if (cmd_offset == -1) { | ||
| 544 | DRM_ERROR("No available hqvdp_cmd now\n"); | ||
| 545 | return -EBUSY; | ||
| 546 | } | ||
| 547 | cmd = hqvdp->hqvdp_cmd + cmd_offset; | ||
| 548 | |||
| 549 | if (!sti_hqvdp_check_hw_scaling(layer)) { | ||
| 550 | DRM_ERROR("Scaling beyond HW capabilities\n"); | ||
| 551 | return -EINVAL; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* Static parameters, defaulting to progressive mode */ | ||
| 555 | cmd->top.config = TOP_CONFIG_PROGRESSIVE; | ||
| 556 | cmd->top.mem_format = TOP_MEM_FORMAT_DFLT; | ||
| 557 | cmd->hvsrc.param_ctrl = HVSRC_PARAM_CTRL_DFLT; | ||
| 558 | cmd->csdi.config = CSDI_CONFIG_PROG; | ||
| 559 | |||
| 560 | /* VC1RE, FMD bypassed : keep everything set to 0 | ||
| 561 | * IQI/P2I bypassed */ | ||
| 562 | cmd->iqi.config = IQI_CONFIG_DFLT; | ||
| 563 | cmd->iqi.con_bri = IQI_CON_BRI_DFLT; | ||
| 564 | cmd->iqi.sat_gain = IQI_SAT_GAIN_DFLT; | ||
| 565 | cmd->iqi.pxf_conf = IQI_PXF_CONF_DFLT; | ||
| 566 | |||
| 567 | /* Buffer planes address */ | ||
| 568 | cmd->top.current_luma = (u32) layer->paddr + layer->offsets[0]; | ||
| 569 | cmd->top.current_chroma = (u32) layer->paddr + layer->offsets[1]; | ||
| 570 | |||
| 571 | /* Pitches */ | ||
| 572 | cmd->top.luma_processed_pitch = cmd->top.luma_src_pitch = | ||
| 573 | layer->pitches[0]; | ||
| 574 | cmd->top.chroma_processed_pitch = cmd->top.chroma_src_pitch = | ||
| 575 | layer->pitches[1]; | ||
| 576 | |||
| 577 | /* Input / output size | ||
| 578 | * Align to upper even value */ | ||
| 579 | layer->dst_w = ALIGN(layer->dst_w, 2); | ||
| 580 | layer->dst_h = ALIGN(layer->dst_h, 2); | ||
| 581 | |||
| 582 | if ((layer->src_w > MAX_WIDTH) || (layer->src_w < MIN_WIDTH) || | ||
| 583 | (layer->src_h > MAX_HEIGHT) || (layer->src_h < MIN_HEIGHT) || | ||
| 584 | (layer->dst_w > MAX_WIDTH) || (layer->dst_w < MIN_WIDTH) || | ||
| 585 | (layer->dst_h > MAX_HEIGHT) || (layer->dst_h < MIN_HEIGHT)) { | ||
| 586 | DRM_ERROR("Invalid in/out size %dx%d -> %dx%d\n", | ||
| 587 | layer->src_w, layer->src_h, | ||
| 588 | layer->dst_w, layer->dst_h); | ||
| 589 | return -EINVAL; | ||
| 590 | } | ||
| 591 | cmd->top.input_viewport_size = cmd->top.input_frame_size = | ||
| 592 | layer->src_h << 16 | layer->src_w; | ||
| 593 | cmd->hvsrc.output_picture_size = layer->dst_h << 16 | layer->dst_w; | ||
| 594 | cmd->top.input_viewport_ori = layer->src_y << 16 | layer->src_x; | ||
| 595 | |||
| 596 | /* Handle interlaced */ | ||
| 597 | if (layer->fb->flags & DRM_MODE_FB_INTERLACED) { | ||
| 598 | /* Top field to display */ | ||
| 599 | cmd->top.config = TOP_CONFIG_INTER_TOP; | ||
| 600 | |||
| 601 | /* Update pitches and vert size */ | ||
| 602 | cmd->top.input_frame_size = (layer->src_h / 2) << 16 | | ||
| 603 | layer->src_w; | ||
| 604 | cmd->top.luma_processed_pitch *= 2; | ||
| 605 | cmd->top.luma_src_pitch *= 2; | ||
| 606 | cmd->top.chroma_processed_pitch *= 2; | ||
| 607 | cmd->top.chroma_src_pitch *= 2; | ||
| 608 | |||
| 609 | /* Enable directional deinterlacing processing */ | ||
| 610 | cmd->csdi.config = CSDI_CONFIG_INTER_DIR; | ||
| 611 | cmd->csdi.config2 = CSDI_CONFIG2_DFLT; | ||
| 612 | cmd->csdi.dcdi_config = CSDI_DCDI_CONFIG_DFLT; | ||
| 613 | } | ||
| 614 | |||
| 615 | /* Update hvsrc lut coef */ | ||
| 616 | scale_h = SCALE_FACTOR * layer->dst_w / layer->src_w; | ||
| 617 | sti_hqvdp_update_hvsrc(HVSRC_HORI, scale_h, &cmd->hvsrc); | ||
| 618 | |||
| 619 | scale_v = SCALE_FACTOR * layer->dst_h / layer->src_h; | ||
| 620 | sti_hqvdp_update_hvsrc(HVSRC_VERT, scale_v, &cmd->hvsrc); | ||
| 621 | |||
| 622 | if (first_prepare) { | ||
| 623 | /* Prevent VTG shutdown */ | ||
| 624 | if (clk_prepare_enable(hqvdp->clk_pix_main)) { | ||
| 625 | DRM_ERROR("Failed to prepare/enable pix main clk\n"); | ||
| 626 | return -ENXIO; | ||
| 627 | } | ||
| 628 | |||
| 629 | /* Register VTG Vsync callback to handle bottom fields */ | ||
| 630 | if ((layer->fb->flags & DRM_MODE_FB_INTERLACED) && | ||
| 631 | sti_vtg_register_client(hqvdp->vtg, | ||
| 632 | &hqvdp->vtg_nb, layer->mixer_id)) { | ||
| 633 | DRM_ERROR("Cannot register VTG notifier\n"); | ||
| 634 | return -ENXIO; | ||
| 635 | } | ||
| 636 | } | ||
| 637 | |||
| 638 | return 0; | ||
| 639 | } | ||
| 640 | |||
| 641 | static int sti_hqvdp_commit_layer(struct sti_layer *layer) | ||
| 642 | { | ||
| 643 | struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); | ||
| 644 | int cmd_offset; | ||
| 645 | |||
| 646 | dev_dbg(hqvdp->dev, "%s %s\n", __func__, sti_layer_to_str(layer)); | ||
| 647 | |||
| 648 | cmd_offset = sti_hqvdp_get_free_cmd(hqvdp); | ||
| 649 | if (cmd_offset == -1) { | ||
| 650 | DRM_ERROR("No available hqvdp_cmd now\n"); | ||
| 651 | return -EBUSY; | ||
| 652 | } | ||
| 653 | |||
| 654 | writel(hqvdp->hqvdp_cmd_paddr + cmd_offset, | ||
| 655 | hqvdp->regs + HQVDP_MBX_NEXT_CMD); | ||
| 656 | |||
| 657 | hqvdp->curr_field_count++; | ||
| 658 | |||
| 659 | /* Interlaced : get ready to display the bottom field at next Vsync */ | ||
| 660 | if (layer->fb->flags & DRM_MODE_FB_INTERLACED) | ||
| 661 | hqvdp->btm_field_pending = true; | ||
| 662 | |||
| 663 | dev_dbg(hqvdp->dev, "%s Posted command:0x%x\n", | ||
| 664 | __func__, hqvdp->hqvdp_cmd_paddr + cmd_offset); | ||
| 665 | |||
| 666 | return 0; | ||
| 667 | } | ||
| 668 | |||
| 669 | static int sti_hqvdp_disable_layer(struct sti_layer *layer) | ||
| 670 | { | ||
| 671 | struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); | ||
| 672 | int i; | ||
| 673 | |||
| 674 | DRM_DEBUG_DRIVER("%s\n", sti_layer_to_str(layer)); | ||
| 675 | |||
| 676 | /* Unregister VTG Vsync callback */ | ||
| 677 | if ((layer->fb->flags & DRM_MODE_FB_INTERLACED) && | ||
| 678 | sti_vtg_unregister_client(hqvdp->vtg, &hqvdp->vtg_nb)) | ||
| 679 | DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n"); | ||
| 680 | |||
| 681 | /* Set next cmd to NULL */ | ||
| 682 | writel(0, hqvdp->regs + HQVDP_MBX_NEXT_CMD); | ||
| 683 | |||
| 684 | for (i = 0; i < POLL_MAX_ATTEMPT; i++) { | ||
| 685 | if (readl(hqvdp->regs + HQVDP_MBX_INFO_XP70) | ||
| 686 | & INFO_XP70_FW_READY) | ||
| 687 | break; | ||
| 688 | msleep(POLL_DELAY_MS); | ||
| 689 | } | ||
| 690 | |||
| 691 | /* VTG can stop now */ | ||
| 692 | clk_disable_unprepare(hqvdp->clk_pix_main); | ||
| 693 | |||
| 694 | if (i == POLL_MAX_ATTEMPT) { | ||
| 695 | DRM_ERROR("XP70 could not revert to idle\n"); | ||
| 696 | return -ENXIO; | ||
| 697 | } | ||
| 698 | |||
| 699 | /* disable VID plane */ | ||
| 700 | hqvdp->vid_plane->funcs->disable_plane(hqvdp->vid_plane); | ||
| 701 | |||
| 702 | return 0; | ||
| 703 | } | ||
| 704 | |||
| 705 | /** | ||
| 706 | * sti_vdp_vtg_cb | ||
| 707 | * @nb: notifier block | ||
| 708 | * @evt: event message | ||
| 709 | * @data: private data | ||
| 710 | * | ||
| 711 | * Handle VTG Vsync event, display pending bottom field | ||
| 712 | * | ||
| 713 | * RETURNS: | ||
| 714 | * 0 on success. | ||
| 715 | */ | ||
| 716 | int sti_hqvdp_vtg_cb(struct notifier_block *nb, unsigned long evt, void *data) | ||
| 717 | { | ||
| 718 | struct sti_hqvdp *hqvdp = container_of(nb, struct sti_hqvdp, vtg_nb); | ||
| 719 | int btm_cmd_offset, top_cmd_offest; | ||
| 720 | struct sti_hqvdp_cmd *btm_cmd, *top_cmd; | ||
| 721 | |||
| 722 | if ((evt != VTG_TOP_FIELD_EVENT) && (evt != VTG_BOTTOM_FIELD_EVENT)) { | ||
| 723 | DRM_DEBUG_DRIVER("Unknown event\n"); | ||
| 724 | return 0; | ||
| 725 | } | ||
| 726 | |||
| 727 | if (hqvdp->btm_field_pending) { | ||
| 728 | /* Create the btm field command from the current one */ | ||
| 729 | btm_cmd_offset = sti_hqvdp_get_free_cmd(hqvdp); | ||
| 730 | top_cmd_offest = sti_hqvdp_get_curr_cmd(hqvdp); | ||
| 731 | if ((btm_cmd_offset == -1) || (top_cmd_offest == -1)) { | ||
| 732 | DRM_ERROR("Cannot get cmds, skip btm field\n"); | ||
| 733 | return -EBUSY; | ||
| 734 | } | ||
| 735 | |||
| 736 | btm_cmd = hqvdp->hqvdp_cmd + btm_cmd_offset; | ||
| 737 | top_cmd = hqvdp->hqvdp_cmd + top_cmd_offest; | ||
| 738 | |||
| 739 | memcpy(btm_cmd, top_cmd, sizeof(*btm_cmd)); | ||
| 740 | |||
| 741 | btm_cmd->top.config = TOP_CONFIG_INTER_BTM; | ||
| 742 | btm_cmd->top.current_luma += | ||
| 743 | btm_cmd->top.luma_src_pitch / 2; | ||
| 744 | btm_cmd->top.current_chroma += | ||
| 745 | btm_cmd->top.chroma_src_pitch / 2; | ||
| 746 | |||
| 747 | /* Post the command to mailbox */ | ||
| 748 | writel(hqvdp->hqvdp_cmd_paddr + btm_cmd_offset, | ||
| 749 | hqvdp->regs + HQVDP_MBX_NEXT_CMD); | ||
| 750 | |||
| 751 | hqvdp->curr_field_count++; | ||
| 752 | hqvdp->btm_field_pending = false; | ||
| 753 | |||
| 754 | dev_dbg(hqvdp->dev, "%s Posted command:0x%x\n", | ||
| 755 | __func__, hqvdp->hqvdp_cmd_paddr); | ||
| 756 | } | ||
| 757 | |||
| 758 | return 0; | ||
| 759 | } | ||
| 760 | |||
| 761 | static struct drm_plane *sti_hqvdp_find_vid(struct drm_device *dev, int id) | ||
| 762 | { | ||
| 763 | struct drm_plane *plane; | ||
| 764 | |||
| 765 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { | ||
| 766 | struct sti_layer *layer = to_sti_layer(plane); | ||
| 767 | |||
| 768 | if (layer->desc == id) | ||
| 769 | return plane; | ||
| 770 | } | ||
| 771 | |||
| 772 | return NULL; | ||
| 773 | } | ||
| 774 | |||
| 775 | static void sti_hqvd_init(struct sti_layer *layer) | ||
| 776 | { | ||
| 777 | struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); | ||
| 778 | int size; | ||
| 779 | |||
| 780 | /* find the plane macthing with vid 0 */ | ||
| 781 | hqvdp->vid_plane = sti_hqvdp_find_vid(hqvdp->drm_dev, STI_VID_0); | ||
| 782 | if (!hqvdp->vid_plane) { | ||
| 783 | DRM_ERROR("Cannot find Main video layer\n"); | ||
| 784 | return; | ||
| 785 | } | ||
| 786 | |||
| 787 | hqvdp->vtg_nb.notifier_call = sti_hqvdp_vtg_cb; | ||
| 788 | |||
| 789 | /* Allocate memory for the VDP commands */ | ||
| 790 | size = NB_VDP_CMD * sizeof(struct sti_hqvdp_cmd); | ||
| 791 | hqvdp->hqvdp_cmd = dma_alloc_writecombine(hqvdp->dev, size, | ||
| 792 | &hqvdp->hqvdp_cmd_paddr, | ||
| 793 | GFP_KERNEL | GFP_DMA); | ||
| 794 | if (!hqvdp->hqvdp_cmd) { | ||
| 795 | DRM_ERROR("Failed to allocate memory for VDP cmd\n"); | ||
| 796 | return; | ||
| 797 | } | ||
| 798 | |||
| 799 | memset(hqvdp->hqvdp_cmd, 0, size); | ||
| 800 | } | ||
| 801 | |||
| 802 | static const struct sti_layer_funcs hqvdp_ops = { | ||
| 803 | .get_formats = sti_hqvdp_get_formats, | ||
| 804 | .get_nb_formats = sti_hqvdp_get_nb_formats, | ||
| 805 | .init = sti_hqvd_init, | ||
| 806 | .prepare = sti_hqvdp_prepare_layer, | ||
| 807 | .commit = sti_hqvdp_commit_layer, | ||
| 808 | .disable = sti_hqvdp_disable_layer, | ||
| 809 | }; | ||
| 810 | |||
| 811 | struct sti_layer *sti_hqvdp_create(struct device *dev) | ||
| 812 | { | ||
| 813 | struct sti_hqvdp *hqvdp = dev_get_drvdata(dev); | ||
| 814 | |||
| 815 | hqvdp->layer.ops = &hqvdp_ops; | ||
| 816 | |||
| 817 | return &hqvdp->layer; | ||
| 818 | } | ||
| 819 | |||
| 820 | static void sti_hqvdp_init_plugs(struct sti_hqvdp *hqvdp) | ||
| 821 | { | ||
| 822 | /* Configure Plugs (same for RD & WR) */ | ||
| 823 | writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_RD_PLUG_PAGE_SIZE); | ||
| 824 | writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_RD_PLUG_MIN_OPC); | ||
| 825 | writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_RD_PLUG_MAX_OPC); | ||
| 826 | writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_RD_PLUG_MAX_CHK); | ||
| 827 | writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_RD_PLUG_MAX_MSG); | ||
| 828 | writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_RD_PLUG_MIN_SPACE); | ||
| 829 | writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_RD_PLUG_CONTROL); | ||
| 830 | |||
| 831 | writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_WR_PLUG_PAGE_SIZE); | ||
| 832 | writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_WR_PLUG_MIN_OPC); | ||
| 833 | writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_WR_PLUG_MAX_OPC); | ||
| 834 | writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_WR_PLUG_MAX_CHK); | ||
| 835 | writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_WR_PLUG_MAX_MSG); | ||
| 836 | writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_WR_PLUG_MIN_SPACE); | ||
| 837 | writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_WR_PLUG_CONTROL); | ||
| 838 | } | ||
| 839 | |||
| 840 | /** | ||
| 841 | * sti_hqvdp_start_xp70 | ||
| 842 | * @firmware: firmware found | ||
| 843 | * @ctxt: hqvdp structure | ||
| 844 | * | ||
| 845 | * Run the xP70 initialization sequence | ||
| 846 | */ | ||
| 847 | static void sti_hqvdp_start_xp70(const struct firmware *firmware, void *ctxt) | ||
| 848 | { | ||
| 849 | struct sti_hqvdp *hqvdp = ctxt; | ||
| 850 | u32 *fw_rd_plug, *fw_wr_plug, *fw_pmem, *fw_dmem; | ||
| 851 | u8 *data; | ||
| 852 | int i; | ||
| 853 | struct fw_header { | ||
| 854 | int rd_size; | ||
| 855 | int wr_size; | ||
| 856 | int pmem_size; | ||
| 857 | int dmem_size; | ||
| 858 | } *header; | ||
| 859 | |||
| 860 | DRM_DEBUG_DRIVER("\n"); | ||
| 861 | /* Check firmware parts */ | ||
| 862 | if (!firmware) { | ||
| 863 | DRM_ERROR("Firmware not available\n"); | ||
| 864 | return; | ||
| 865 | } | ||
| 866 | |||
| 867 | header = (struct fw_header *) firmware->data; | ||
| 868 | if (firmware->size < sizeof(*header)) { | ||
| 869 | DRM_ERROR("Invalid firmware size (%d)\n", firmware->size); | ||
| 870 | goto out; | ||
| 871 | } | ||
| 872 | if ((sizeof(*header) + header->rd_size + header->wr_size + | ||
| 873 | header->pmem_size + header->dmem_size) != firmware->size) { | ||
| 874 | DRM_ERROR("Invalid fmw structure (%d+%d+%d+%d+%d != %d)\n", | ||
| 875 | sizeof(*header), header->rd_size, header->wr_size, | ||
| 876 | header->pmem_size, header->dmem_size, | ||
| 877 | firmware->size); | ||
| 878 | goto out; | ||
| 879 | } | ||
| 880 | |||
| 881 | data = (u8 *) firmware->data; | ||
| 882 | data += sizeof(*header); | ||
| 883 | fw_rd_plug = (void *) data; | ||
| 884 | data += header->rd_size; | ||
| 885 | fw_wr_plug = (void *) data; | ||
| 886 | data += header->wr_size; | ||
| 887 | fw_pmem = (void *) data; | ||
| 888 | data += header->pmem_size; | ||
| 889 | fw_dmem = (void *) data; | ||
| 890 | |||
| 891 | /* Enable clock */ | ||
| 892 | if (clk_prepare_enable(hqvdp->clk)) | ||
| 893 | DRM_ERROR("Failed to prepare/enable HQVDP clk\n"); | ||
| 894 | |||
| 895 | /* Reset */ | ||
| 896 | writel(SW_RESET_CTRL_FULL, hqvdp->regs + HQVDP_MBX_SW_RESET_CTRL); | ||
| 897 | |||
| 898 | for (i = 0; i < POLL_MAX_ATTEMPT; i++) { | ||
| 899 | if (readl(hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1) | ||
| 900 | & STARTUP_CTRL1_RST_DONE) | ||
| 901 | break; | ||
| 902 | msleep(POLL_DELAY_MS); | ||
| 903 | } | ||
| 904 | if (i == POLL_MAX_ATTEMPT) { | ||
| 905 | DRM_ERROR("Could not reset\n"); | ||
| 906 | goto out; | ||
| 907 | } | ||
| 908 | |||
| 909 | /* Init Read & Write plugs */ | ||
| 910 | for (i = 0; i < header->rd_size / 4; i++) | ||
| 911 | writel(fw_rd_plug[i], hqvdp->regs + HQVDP_RD_PLUG + i * 4); | ||
| 912 | for (i = 0; i < header->wr_size / 4; i++) | ||
| 913 | writel(fw_wr_plug[i], hqvdp->regs + HQVDP_WR_PLUG + i * 4); | ||
| 914 | |||
| 915 | sti_hqvdp_init_plugs(hqvdp); | ||
| 916 | |||
| 917 | /* Authorize Idle Mode */ | ||
| 918 | writel(STARTUP_CTRL1_AUTH_IDLE, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1); | ||
| 919 | |||
| 920 | /* Prevent VTG interruption during the boot */ | ||
| 921 | writel(SOFT_VSYNC_SW_CTRL_IRQ, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC); | ||
| 922 | writel(0, hqvdp->regs + HQVDP_MBX_NEXT_CMD); | ||
| 923 | |||
| 924 | /* Download PMEM & DMEM */ | ||
| 925 | for (i = 0; i < header->pmem_size / 4; i++) | ||
| 926 | writel(fw_pmem[i], hqvdp->regs + HQVDP_PMEM + i * 4); | ||
| 927 | for (i = 0; i < header->dmem_size / 4; i++) | ||
| 928 | writel(fw_dmem[i], hqvdp->regs + HQVDP_DMEM + i * 4); | ||
| 929 | |||
| 930 | /* Enable fetch */ | ||
| 931 | writel(STARTUP_CTRL2_FETCH_EN, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL2); | ||
| 932 | |||
| 933 | /* Wait end of boot */ | ||
| 934 | for (i = 0; i < POLL_MAX_ATTEMPT; i++) { | ||
| 935 | if (readl(hqvdp->regs + HQVDP_MBX_INFO_XP70) | ||
| 936 | & INFO_XP70_FW_READY) | ||
| 937 | break; | ||
| 938 | msleep(POLL_DELAY_MS); | ||
| 939 | } | ||
| 940 | if (i == POLL_MAX_ATTEMPT) { | ||
| 941 | DRM_ERROR("Could not boot\n"); | ||
| 942 | goto out; | ||
| 943 | } | ||
| 944 | |||
| 945 | /* Launch Vsync */ | ||
| 946 | writel(SOFT_VSYNC_HW, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC); | ||
| 947 | |||
| 948 | DRM_INFO("HQVDP XP70 started\n"); | ||
| 949 | out: | ||
| 950 | release_firmware(firmware); | ||
| 951 | } | ||
| 952 | |||
| 953 | int sti_hqvdp_bind(struct device *dev, struct device *master, void *data) | ||
| 954 | { | ||
| 955 | struct sti_hqvdp *hqvdp = dev_get_drvdata(dev); | ||
| 956 | struct drm_device *drm_dev = data; | ||
| 957 | struct sti_layer *layer; | ||
| 958 | int err; | ||
| 959 | |||
| 960 | DRM_DEBUG_DRIVER("\n"); | ||
| 961 | |||
| 962 | hqvdp->drm_dev = drm_dev; | ||
| 963 | |||
| 964 | /* Request for firmware */ | ||
| 965 | err = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
| 966 | HQVDP_FMW_NAME, hqvdp->dev, | ||
| 967 | GFP_KERNEL, hqvdp, sti_hqvdp_start_xp70); | ||
| 968 | if (err) { | ||
| 969 | DRM_ERROR("Can't get HQVDP firmware\n"); | ||
| 970 | return err; | ||
| 971 | } | ||
| 972 | |||
| 973 | layer = sti_layer_create(hqvdp->dev, STI_HQVDP_0, hqvdp->regs); | ||
| 974 | if (!layer) { | ||
| 975 | DRM_ERROR("Can't create HQVDP plane\n"); | ||
| 976 | return -ENOMEM; | ||
| 977 | } | ||
| 978 | |||
| 979 | sti_drm_plane_init(drm_dev, layer, 1, DRM_PLANE_TYPE_OVERLAY); | ||
| 980 | |||
| 981 | return 0; | ||
| 982 | } | ||
| 983 | |||
| 984 | static void sti_hqvdp_unbind(struct device *dev, | ||
| 985 | struct device *master, void *data) | ||
| 986 | { | ||
| 987 | /* do nothing */ | ||
| 988 | } | ||
| 989 | |||
| 990 | static const struct component_ops sti_hqvdp_ops = { | ||
| 991 | .bind = sti_hqvdp_bind, | ||
| 992 | .unbind = sti_hqvdp_unbind, | ||
| 993 | }; | ||
| 994 | |||
| 995 | static int sti_hqvdp_probe(struct platform_device *pdev) | ||
| 996 | { | ||
| 997 | struct device *dev = &pdev->dev; | ||
| 998 | struct device_node *vtg_np; | ||
| 999 | struct sti_hqvdp *hqvdp; | ||
| 1000 | struct resource *res; | ||
| 1001 | |||
| 1002 | DRM_DEBUG_DRIVER("\n"); | ||
| 1003 | |||
| 1004 | hqvdp = devm_kzalloc(dev, sizeof(*hqvdp), GFP_KERNEL); | ||
| 1005 | if (!hqvdp) { | ||
| 1006 | DRM_ERROR("Failed to allocate HQVDP context\n"); | ||
| 1007 | return -ENOMEM; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | hqvdp->dev = dev; | ||
| 1011 | |||
| 1012 | /* Get Memory resources */ | ||
| 1013 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 1014 | if (res == NULL) { | ||
| 1015 | DRM_ERROR("Get memory resource failed\n"); | ||
| 1016 | return -ENXIO; | ||
| 1017 | } | ||
| 1018 | hqvdp->regs = devm_ioremap(dev, res->start, resource_size(res)); | ||
| 1019 | if (hqvdp->regs == NULL) { | ||
| 1020 | DRM_ERROR("Register mapping failed\n"); | ||
| 1021 | return -ENXIO; | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | /* Get clock resources */ | ||
| 1025 | hqvdp->clk = devm_clk_get(dev, "hqvdp"); | ||
| 1026 | hqvdp->clk_pix_main = devm_clk_get(dev, "pix_main"); | ||
| 1027 | if (IS_ERR(hqvdp->clk) || IS_ERR(hqvdp->clk)) { | ||
| 1028 | DRM_ERROR("Cannot get clocks\n"); | ||
| 1029 | return -ENXIO; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | /* Get reset resources */ | ||
| 1033 | hqvdp->reset = devm_reset_control_get(dev, "hqvdp"); | ||
| 1034 | if (!IS_ERR(hqvdp->reset)) | ||
| 1035 | reset_control_deassert(hqvdp->reset); | ||
| 1036 | |||
| 1037 | vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 0); | ||
| 1038 | if (vtg_np) | ||
| 1039 | hqvdp->vtg = of_vtg_find(vtg_np); | ||
| 1040 | |||
| 1041 | platform_set_drvdata(pdev, hqvdp); | ||
| 1042 | |||
| 1043 | return component_add(&pdev->dev, &sti_hqvdp_ops); | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | static int sti_hqvdp_remove(struct platform_device *pdev) | ||
| 1047 | { | ||
| 1048 | component_del(&pdev->dev, &sti_hqvdp_ops); | ||
| 1049 | return 0; | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | static struct of_device_id hqvdp_of_match[] = { | ||
| 1053 | { .compatible = "st,stih407-hqvdp", }, | ||
| 1054 | { /* end node */ } | ||
| 1055 | }; | ||
| 1056 | MODULE_DEVICE_TABLE(of, hqvdp_of_match); | ||
| 1057 | |||
| 1058 | struct platform_driver sti_hqvdp_driver = { | ||
| 1059 | .driver = { | ||
| 1060 | .name = "sti-hqvdp", | ||
| 1061 | .owner = THIS_MODULE, | ||
| 1062 | .of_match_table = hqvdp_of_match, | ||
| 1063 | }, | ||
| 1064 | .probe = sti_hqvdp_probe, | ||
| 1065 | .remove = sti_hqvdp_remove, | ||
| 1066 | }; | ||
| 1067 | |||
| 1068 | module_platform_driver(sti_hqvdp_driver); | ||
| 1069 | |||
| 1070 | MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>"); | ||
| 1071 | MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver"); | ||
| 1072 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.h b/drivers/gpu/drm/sti/sti_hqvdp.h new file mode 100644 index 000000000000..cd5ecd0a6dea --- /dev/null +++ b/drivers/gpu/drm/sti/sti_hqvdp.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) STMicroelectronics SA 2014 | ||
| 3 | * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics. | ||
| 4 | * License terms: GNU General Public License (GPL), version 2 | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef _STI_HQVDP_H_ | ||
| 8 | #define _STI_HQVDP_H_ | ||
| 9 | |||
| 10 | struct sti_layer *sti_hqvdp_create(struct device *dev); | ||
| 11 | |||
| 12 | #endif | ||
diff --git a/drivers/gpu/drm/sti/sti_hqvdp_lut.h b/drivers/gpu/drm/sti/sti_hqvdp_lut.h new file mode 100644 index 000000000000..619af7f4384e --- /dev/null +++ b/drivers/gpu/drm/sti/sti_hqvdp_lut.h | |||
| @@ -0,0 +1,373 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) STMicroelectronics SA 2014 | ||
| 3 | * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics. | ||
| 4 | * License terms: GNU General Public License (GPL), version 2 | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef _STI_HQVDP_LUT_H_ | ||
| 8 | #define _STI_HQVDP_LUT_H_ | ||
| 9 | |||
| 10 | #define NB_COEF 128 | ||
| 11 | |||
| 12 | #define SHIFT_LUT_A_LEGACY 8 | ||
| 13 | #define SHIFT_LUT_B 8 | ||
| 14 | #define SHIFT_LUT_C_Y_LEGACY 8 | ||
| 15 | #define SHIFT_LUT_C_C_LEGACY 8 | ||
| 16 | #define SHIFT_LUT_D_Y_LEGACY 8 | ||
| 17 | #define SHIFT_LUT_D_C_LEGACY 8 | ||
| 18 | #define SHIFT_LUT_E_Y_LEGACY 8 | ||
| 19 | #define SHIFT_LUT_E_C_LEGACY 8 | ||
| 20 | #define SHIFT_LUT_F_Y_LEGACY 8 | ||
| 21 | #define SHIFT_LUT_F_C_LEGACY 8 | ||
| 22 | |||
| 23 | static const u32 coef_lut_a_legacy[NB_COEF] = { | ||
| 24 | 0x0000ffff, 0x00010000, 0x000100ff, 0x00000000, | ||
| 25 | 0x00000000, 0x00050000, 0xfffc00ff, 0x00000000, | ||
| 26 | 0x00000000, 0x00090000, 0xfff900fe, 0x00000000, | ||
| 27 | 0x00000000, 0x0010ffff, 0xfff600fb, 0x00000000, | ||
| 28 | 0x00000000, 0x0017fffe, 0xfff400f7, 0x00000000, | ||
| 29 | 0x00000000, 0x001ffffd, 0xfff200f2, 0x00000000, | ||
| 30 | 0x00000000, 0x0027fffc, 0xfff100ec, 0x00000000, | ||
| 31 | 0x00000000, 0x0030fffb, 0xfff000e5, 0x00000000, | ||
| 32 | 0x00000000, 0x003afffa, 0xffee00de, 0x00000000, | ||
| 33 | 0x00000000, 0x0044fff9, 0xffed00d6, 0x00000000, | ||
| 34 | 0x00000000, 0x004efff8, 0xffed00cd, 0x00000000, | ||
| 35 | 0x00000000, 0x0059fff6, 0xffed00c4, 0x00000000, | ||
| 36 | 0x00000000, 0x0064fff5, 0xffed00ba, 0x00000000, | ||
| 37 | 0x00000000, 0x006ffff3, 0xffee00b0, 0x00000000, | ||
| 38 | 0x00000000, 0x007afff2, 0xffee00a6, 0x00000000, | ||
| 39 | 0x00000000, 0x0085fff1, 0xffef009b, 0x00000000, | ||
| 40 | 0x00000000, 0x0090fff0, 0xfff00090, 0x00000000, | ||
| 41 | 0x00000000, 0x009bffef, 0xfff10085, 0x00000000, | ||
| 42 | 0x00000000, 0x00a6ffee, 0xfff2007a, 0x00000000, | ||
| 43 | 0x00000000, 0x00b0ffee, 0xfff3006f, 0x00000000, | ||
| 44 | 0x00000000, 0x00baffed, 0xfff50064, 0x00000000, | ||
| 45 | 0x00000000, 0x00c4ffed, 0xfff60059, 0x00000000, | ||
| 46 | 0x00000000, 0x00cdffed, 0xfff8004e, 0x00000000, | ||
| 47 | 0x00000000, 0x00d6ffed, 0xfff90044, 0x00000000, | ||
| 48 | 0x00000000, 0x00deffee, 0xfffa003a, 0x00000000, | ||
| 49 | 0x00000000, 0x00e5fff0, 0xfffb0030, 0x00000000, | ||
| 50 | 0x00000000, 0x00ecfff1, 0xfffc0027, 0x00000000, | ||
| 51 | 0x00000000, 0x00f2fff2, 0xfffd001f, 0x00000000, | ||
| 52 | 0x00000000, 0x00f7fff4, 0xfffe0017, 0x00000000, | ||
| 53 | 0x00000000, 0x00fbfff6, 0xffff0010, 0x00000000, | ||
| 54 | 0x00000000, 0x00fefff9, 0x00000009, 0x00000000, | ||
| 55 | 0x00000000, 0x00fffffc, 0x00000005, 0x00000000 | ||
| 56 | }; | ||
| 57 | |||
| 58 | static const u32 coef_lut_b[NB_COEF] = { | ||
| 59 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 60 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 61 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 62 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 63 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 64 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 65 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 66 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 67 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 68 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 69 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 70 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 71 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 72 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 73 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 74 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 75 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 76 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 77 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 78 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 79 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 80 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 81 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 82 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 83 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 84 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 85 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 86 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 87 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 88 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 89 | 0x00000000, 0x00000000, 0x00000100, 0x00000000, | ||
| 90 | 0x00000000, 0x00000000, 0x00000100, 0x00000000 | ||
| 91 | }; | ||
| 92 | |||
| 93 | static const u32 coef_lut_c_y_legacy[NB_COEF] = { | ||
| 94 | 0x00060004, 0x0038ffe1, 0x003800be, 0x0006ffe1, | ||
| 95 | 0x00050005, 0x0042ffe1, 0x003800b3, 0x0007ffe1, | ||
| 96 | 0x00040006, 0x0046ffe1, 0x003300b2, 0x0008ffe2, | ||
| 97 | 0x00030007, 0x004cffe1, 0x002e00b1, 0x0008ffe2, | ||
| 98 | 0x00020006, 0x0051ffe2, 0x002900b0, 0x0009ffe3, | ||
| 99 | 0x00010008, 0x0056ffe2, 0x002400ae, 0x0009ffe4, | ||
| 100 | 0xffff0008, 0x005cffe3, 0x001f00ad, 0x000affe4, | ||
| 101 | 0xfffe0008, 0x0062ffe4, 0x001a00ab, 0x000affe5, | ||
| 102 | 0xfffd000a, 0x0066ffe5, 0x001500a8, 0x000bffe6, | ||
| 103 | 0xfffc0009, 0x006bffe7, 0x001100a5, 0x000bffe8, | ||
| 104 | 0xfffa000a, 0x0070ffe8, 0x000d00a3, 0x000bffe9, | ||
| 105 | 0xfff9000b, 0x0076ffea, 0x0008009f, 0x000bffea, | ||
| 106 | 0xfff7000b, 0x007affec, 0x0005009b, 0x000cffec, | ||
| 107 | 0xfff6000b, 0x007effef, 0x00010098, 0x000cffed, | ||
| 108 | 0xfff4000b, 0x0084fff1, 0xfffd0095, 0x000cffee, | ||
| 109 | 0xfff3000b, 0x0088fff4, 0xfffa0090, 0x000cfff0, | ||
| 110 | 0xfff1000b, 0x008dfff7, 0xfff7008d, 0x000bfff1, | ||
| 111 | 0xfff0000c, 0x0090fffa, 0xfff40088, 0x000bfff3, | ||
| 112 | 0xffee000c, 0x0095fffd, 0xfff10084, 0x000bfff4, | ||
| 113 | 0xffed000c, 0x00980001, 0xffef007e, 0x000bfff6, | ||
| 114 | 0xffec000c, 0x009b0005, 0xffec007a, 0x000bfff7, | ||
| 115 | 0xffea000b, 0x009f0008, 0xffea0076, 0x000bfff9, | ||
| 116 | 0xffe9000b, 0x00a3000d, 0xffe80070, 0x000afffa, | ||
| 117 | 0xffe8000b, 0x00a50011, 0xffe7006b, 0x0009fffc, | ||
| 118 | 0xffe6000b, 0x00a80015, 0xffe50066, 0x000afffd, | ||
| 119 | 0xffe5000a, 0x00ab001a, 0xffe40062, 0x0008fffe, | ||
| 120 | 0xffe4000a, 0x00ad001f, 0xffe3005c, 0x0008ffff, | ||
| 121 | 0xffe40009, 0x00ae0024, 0xffe20056, 0x00080001, | ||
| 122 | 0xffe30009, 0x00b00029, 0xffe20051, 0x00060002, | ||
| 123 | 0xffe20008, 0x00b1002e, 0xffe1004c, 0x00070003, | ||
| 124 | 0xffe20008, 0x00b20033, 0xffe10046, 0x00060004, | ||
| 125 | 0xffe10007, 0x00b30038, 0xffe10042, 0x00050005 | ||
| 126 | }; | ||
| 127 | |||
| 128 | static const u32 coef_lut_c_c_legacy[NB_COEF] = { | ||
| 129 | 0x0001fff3, 0x003afffb, 0x003a00a1, 0x0001fffb, | ||
| 130 | 0x0001fff5, 0x0041fffb, 0x0038009a, 0x0001fffb, | ||
| 131 | 0x0001fff5, 0x0046fffb, 0x00340099, 0x0001fffb, | ||
| 132 | 0x0001fff7, 0x0049fffb, 0x00300098, 0x0001fffb, | ||
| 133 | 0x0001fff9, 0x004cfffb, 0x002d0096, 0x0001fffb, | ||
| 134 | 0x0001fffa, 0x004ffffc, 0x00290095, 0x0001fffb, | ||
| 135 | 0x0001fff9, 0x0054fffd, 0x00250093, 0x0001fffc, | ||
| 136 | 0x0001fffa, 0x0058fffd, 0x00220092, 0x0000fffc, | ||
| 137 | 0x0001fffb, 0x005bfffe, 0x001f0090, 0x0000fffc, | ||
| 138 | 0x0001fffd, 0x005effff, 0x001c008c, 0x0000fffd, | ||
| 139 | 0x0001fffd, 0x00620000, 0x0019008a, 0x0000fffd, | ||
| 140 | 0x0001fffe, 0x00660001, 0x00160088, 0xfffffffd, | ||
| 141 | 0x0000fffe, 0x006a0003, 0x00130085, 0xfffffffe, | ||
| 142 | 0x0000fffe, 0x006e0004, 0x00100083, 0xfffffffe, | ||
| 143 | 0x0000fffe, 0x00710006, 0x000e007f, 0xffffffff, | ||
| 144 | 0x0000fffe, 0x00750008, 0x000c007c, 0xfffeffff, | ||
| 145 | 0xfffffffe, 0x0079000a, 0x000a0079, 0xfffeffff, | ||
| 146 | 0xfffffffe, 0x007c000c, 0x00080075, 0xfffe0000, | ||
| 147 | 0xffffffff, 0x007f000e, 0x00060071, 0xfffe0000, | ||
| 148 | 0xfffeffff, 0x00830010, 0x0004006e, 0xfffe0000, | ||
| 149 | 0xfffeffff, 0x00850013, 0x0003006a, 0xfffe0000, | ||
| 150 | 0xfffdffff, 0x00880016, 0x00010066, 0xfffe0001, | ||
| 151 | 0xfffd0000, 0x008a0019, 0x00000062, 0xfffd0001, | ||
| 152 | 0xfffd0000, 0x008c001c, 0xffff005e, 0xfffd0001, | ||
| 153 | 0xfffc0000, 0x0090001f, 0xfffe005b, 0xfffb0001, | ||
| 154 | 0xfffc0000, 0x00920022, 0xfffd0058, 0xfffa0001, | ||
| 155 | 0xfffc0001, 0x00930025, 0xfffd0054, 0xfff90001, | ||
| 156 | 0xfffb0001, 0x00950029, 0xfffc004f, 0xfffa0001, | ||
| 157 | 0xfffb0001, 0x0096002d, 0xfffb004c, 0xfff90001, | ||
| 158 | 0xfffb0001, 0x00980030, 0xfffb0049, 0xfff70001, | ||
| 159 | 0xfffb0001, 0x00990034, 0xfffb0046, 0xfff50001, | ||
| 160 | 0xfffb0001, 0x009a0038, 0xfffb0041, 0xfff50001 | ||
| 161 | }; | ||
| 162 | |||
| 163 | static const u32 coef_lut_d_y_legacy[NB_COEF] = { | ||
| 164 | 0xfff80009, 0x0046ffec, 0x004600a3, 0xfff8ffec, | ||
| 165 | 0xfff70009, 0x004effed, 0x0044009d, 0xfff9ffeb, | ||
| 166 | 0xfff6000a, 0x0052ffee, 0x003f009d, 0xfffaffea, | ||
| 167 | 0xfff50009, 0x0057ffef, 0x003b009d, 0xfffbffe9, | ||
| 168 | 0xfff50008, 0x005bfff0, 0x0037009c, 0xfffcffe9, | ||
| 169 | 0xfff40008, 0x005ffff2, 0x0033009b, 0xfffcffe9, | ||
| 170 | 0xfff30007, 0x0064fff3, 0x002f009b, 0xfffdffe8, | ||
| 171 | 0xfff20007, 0x0068fff5, 0x002b0099, 0xfffeffe8, | ||
| 172 | 0xfff10008, 0x006bfff7, 0x00270097, 0xffffffe8, | ||
| 173 | 0xfff00007, 0x006ffff9, 0x00230097, 0xffffffe8, | ||
| 174 | 0xffef0006, 0x0073fffb, 0x00200095, 0x0000ffe8, | ||
| 175 | 0xffee0005, 0x0077fffe, 0x001c0093, 0x0000ffe9, | ||
| 176 | 0xffee0005, 0x007a0000, 0x00180091, 0x0001ffe9, | ||
| 177 | 0xffed0005, 0x007d0003, 0x0015008e, 0x0002ffe9, | ||
| 178 | 0xffec0005, 0x00800006, 0x0012008b, 0x0002ffea, | ||
| 179 | 0xffeb0004, 0x00840008, 0x000e008a, 0x0003ffea, | ||
| 180 | 0xffeb0003, 0x0087000b, 0x000b0087, 0x0003ffeb, | ||
| 181 | 0xffea0003, 0x008a000e, 0x00080084, 0x0004ffeb, | ||
| 182 | 0xffea0002, 0x008b0012, 0x00060080, 0x0005ffec, | ||
| 183 | 0xffe90002, 0x008e0015, 0x0003007d, 0x0005ffed, | ||
| 184 | 0xffe90001, 0x00910018, 0x0000007a, 0x0005ffee, | ||
| 185 | 0xffe90000, 0x0093001c, 0xfffe0077, 0x0005ffee, | ||
| 186 | 0xffe80000, 0x00950020, 0xfffb0073, 0x0006ffef, | ||
| 187 | 0xffe8ffff, 0x00970023, 0xfff9006f, 0x0007fff0, | ||
| 188 | 0xffe8ffff, 0x00970027, 0xfff7006b, 0x0008fff1, | ||
| 189 | 0xffe8fffe, 0x0099002b, 0xfff50068, 0x0007fff2, | ||
| 190 | 0xffe8fffd, 0x009b002f, 0xfff30064, 0x0007fff3, | ||
| 191 | 0xffe9fffc, 0x009b0033, 0xfff2005f, 0x0008fff4, | ||
| 192 | 0xffe9fffc, 0x009c0037, 0xfff0005b, 0x0008fff5, | ||
| 193 | 0xffe9fffb, 0x009d003b, 0xffef0057, 0x0009fff5, | ||
| 194 | 0xffeafffa, 0x009d003f, 0xffee0052, 0x000afff6, | ||
| 195 | 0xffebfff9, 0x009d0044, 0xffed004e, 0x0009fff7 | ||
| 196 | }; | ||
| 197 | |||
| 198 | static const u32 coef_lut_d_c_legacy[NB_COEF] = { | ||
| 199 | 0xfffeffff, 0x003fffff, 0x003f0089, 0xfffeffff, | ||
| 200 | 0xfffe0000, 0x00460000, 0x0042007d, 0xfffffffe, | ||
| 201 | 0xfffe0000, 0x00490001, 0x003f007d, 0xfffffffd, | ||
| 202 | 0xfffd0001, 0x004b0002, 0x003c007d, 0x0000fffc, | ||
| 203 | 0xfffd0001, 0x004e0003, 0x0039007c, 0x0000fffc, | ||
| 204 | 0xfffc0001, 0x00510005, 0x0036007c, 0x0000fffb, | ||
| 205 | 0xfffc0001, 0x00540006, 0x0033007b, 0x0001fffa, | ||
| 206 | 0xfffc0003, 0x00550008, 0x00310078, 0x0001fffa, | ||
| 207 | 0xfffb0003, 0x00580009, 0x002e0078, 0x0001fffa, | ||
| 208 | 0xfffb0002, 0x005b000b, 0x002b0077, 0x0002fff9, | ||
| 209 | 0xfffa0003, 0x005e000d, 0x00280075, 0x0002fff9, | ||
| 210 | 0xfffa0002, 0x0060000f, 0x00260074, 0x0002fff9, | ||
| 211 | 0xfffa0004, 0x00610011, 0x00230072, 0x0002fff9, | ||
| 212 | 0xfffa0004, 0x00640013, 0x00200070, 0x0002fff9, | ||
| 213 | 0xfff90004, 0x00660015, 0x001e006e, 0x0003fff9, | ||
| 214 | 0xfff90004, 0x00680017, 0x001c006c, 0x0003fff9, | ||
| 215 | 0xfff90003, 0x006b0019, 0x0019006b, 0x0003fff9, | ||
| 216 | 0xfff90003, 0x006c001c, 0x00170068, 0x0004fff9, | ||
| 217 | 0xfff90003, 0x006e001e, 0x00150066, 0x0004fff9, | ||
| 218 | 0xfff90002, 0x00700020, 0x00130064, 0x0004fffa, | ||
| 219 | 0xfff90002, 0x00720023, 0x00110061, 0x0004fffa, | ||
| 220 | 0xfff90002, 0x00740026, 0x000f0060, 0x0002fffa, | ||
| 221 | 0xfff90002, 0x00750028, 0x000d005e, 0x0003fffa, | ||
| 222 | 0xfff90002, 0x0077002b, 0x000b005b, 0x0002fffb, | ||
| 223 | 0xfffa0001, 0x0078002e, 0x00090058, 0x0003fffb, | ||
| 224 | 0xfffa0001, 0x00780031, 0x00080055, 0x0003fffc, | ||
| 225 | 0xfffa0001, 0x007b0033, 0x00060054, 0x0001fffc, | ||
| 226 | 0xfffb0000, 0x007c0036, 0x00050051, 0x0001fffc, | ||
| 227 | 0xfffc0000, 0x007c0039, 0x0003004e, 0x0001fffd, | ||
| 228 | 0xfffc0000, 0x007d003c, 0x0002004b, 0x0001fffd, | ||
| 229 | 0xfffdffff, 0x007d003f, 0x00010049, 0x0000fffe, | ||
| 230 | 0xfffeffff, 0x007d0042, 0x00000046, 0x0000fffe | ||
| 231 | }; | ||
| 232 | |||
| 233 | static const u32 coef_lut_e_y_legacy[NB_COEF] = { | ||
| 234 | 0xfff10001, 0x00490004, 0x00490083, 0xfff10004, | ||
| 235 | 0xfff10000, 0x00500006, 0x004b007b, 0xfff10002, | ||
| 236 | 0xfff10000, 0x00530007, 0x0048007b, 0xfff10001, | ||
| 237 | 0xfff10000, 0x00550009, 0x0046007a, 0xfff10000, | ||
| 238 | 0xfff1fffe, 0x0058000b, 0x0043007b, 0xfff2fffe, | ||
| 239 | 0xfff1ffff, 0x005a000d, 0x0040007a, 0xfff2fffd, | ||
| 240 | 0xfff1fffd, 0x005d000f, 0x003e007a, 0xfff2fffc, | ||
| 241 | 0xfff1fffd, 0x005f0011, 0x003b0079, 0xfff3fffb, | ||
| 242 | 0xfff1fffc, 0x00610013, 0x00390079, 0xfff3fffa, | ||
| 243 | 0xfff1fffb, 0x00640015, 0x00360079, 0xfff3fff9, | ||
| 244 | 0xfff1fffa, 0x00660017, 0x00340078, 0xfff4fff8, | ||
| 245 | 0xfff1fffb, 0x00680019, 0x00310077, 0xfff4fff7, | ||
| 246 | 0xfff2fff9, 0x006a001b, 0x002f0076, 0xfff5fff6, | ||
| 247 | 0xfff2fff9, 0x006c001e, 0x002c0075, 0xfff5fff5, | ||
| 248 | 0xfff2fff9, 0x006d0020, 0x002a0073, 0xfff6fff5, | ||
| 249 | 0xfff3fff7, 0x00700022, 0x00270073, 0xfff6fff4, | ||
| 250 | 0xfff3fff7, 0x00710025, 0x00250071, 0xfff7fff3, | ||
| 251 | 0xfff4fff6, 0x00730027, 0x00220070, 0xfff7fff3, | ||
| 252 | 0xfff5fff6, 0x0073002a, 0x0020006d, 0xfff9fff2, | ||
| 253 | 0xfff5fff5, 0x0075002c, 0x001e006c, 0xfff9fff2, | ||
| 254 | 0xfff6fff5, 0x0076002f, 0x001b006a, 0xfff9fff2, | ||
| 255 | 0xfff7fff4, 0x00770031, 0x00190068, 0xfffbfff1, | ||
| 256 | 0xfff8fff4, 0x00780034, 0x00170066, 0xfffafff1, | ||
| 257 | 0xfff9fff3, 0x00790036, 0x00150064, 0xfffbfff1, | ||
| 258 | 0xfffafff3, 0x00790039, 0x00130061, 0xfffcfff1, | ||
| 259 | 0xfffbfff3, 0x0079003b, 0x0011005f, 0xfffdfff1, | ||
| 260 | 0xfffcfff2, 0x007a003e, 0x000f005d, 0xfffdfff1, | ||
| 261 | 0xfffdfff2, 0x007a0040, 0x000d005a, 0xfffffff1, | ||
| 262 | 0xfffefff2, 0x007b0043, 0x000b0058, 0xfffefff1, | ||
| 263 | 0x0000fff1, 0x007a0046, 0x00090055, 0x0000fff1, | ||
| 264 | 0x0001fff1, 0x007b0048, 0x00070053, 0x0000fff1, | ||
| 265 | 0x0002fff1, 0x007b004b, 0x00060050, 0x0000fff1 | ||
| 266 | }; | ||
| 267 | |||
| 268 | static const u32 coef_lut_e_c_legacy[NB_COEF] = { | ||
| 269 | 0xfffa0001, 0x003f0010, 0x003f006d, 0xfffa0010, | ||
| 270 | 0xfffb0002, 0x00440011, 0x00440062, 0xfffa000e, | ||
| 271 | 0xfffb0001, 0x00460013, 0x00420062, 0xfffa000d, | ||
| 272 | 0xfffb0000, 0x00480014, 0x00410062, 0xfffa000c, | ||
| 273 | 0xfffb0001, 0x00490015, 0x003f0061, 0xfffb000b, | ||
| 274 | 0xfffb0000, 0x004b0017, 0x003d0061, 0xfffb000a, | ||
| 275 | 0xfffb0000, 0x004d0018, 0x003b0062, 0xfffb0008, | ||
| 276 | 0xfffcffff, 0x004f001a, 0x00390061, 0xfffb0007, | ||
| 277 | 0xfffc0000, 0x004f001c, 0x00380060, 0xfffb0006, | ||
| 278 | 0xfffcffff, 0x0052001d, 0x00360060, 0xfffb0005, | ||
| 279 | 0xfffdfffe, 0x0053001f, 0x00340060, 0xfffb0004, | ||
| 280 | 0xfffdfffe, 0x00540021, 0x0032005e, 0xfffc0004, | ||
| 281 | 0xfffeffff, 0x00550022, 0x0030005d, 0xfffc0003, | ||
| 282 | 0xfffeffff, 0x00560024, 0x002f005c, 0xfffc0002, | ||
| 283 | 0xfffffffd, 0x00580026, 0x002d005c, 0xfffc0001, | ||
| 284 | 0xfffffffd, 0x005a0027, 0x002b005c, 0xfffc0000, | ||
| 285 | 0x0000fffd, 0x005a0029, 0x0029005a, 0xfffd0000, | ||
| 286 | 0x0000fffc, 0x005c002b, 0x0027005a, 0xfffdffff, | ||
| 287 | 0x0001fffc, 0x005c002d, 0x00260058, 0xfffdffff, | ||
| 288 | 0x0002fffc, 0x005c002f, 0x00240056, 0xfffffffe, | ||
| 289 | 0x0003fffc, 0x005d0030, 0x00220055, 0xfffffffe, | ||
| 290 | 0x0004fffc, 0x005e0032, 0x00210054, 0xfffefffd, | ||
| 291 | 0x0004fffb, 0x00600034, 0x001f0053, 0xfffefffd, | ||
| 292 | 0x0005fffb, 0x00600036, 0x001d0052, 0xfffffffc, | ||
| 293 | 0x0006fffb, 0x00600038, 0x001c004f, 0x0000fffc, | ||
| 294 | 0x0007fffb, 0x00610039, 0x001a004f, 0xfffffffc, | ||
| 295 | 0x0008fffb, 0x0062003b, 0x0018004d, 0x0000fffb, | ||
| 296 | 0x000afffb, 0x0061003d, 0x0017004b, 0x0000fffb, | ||
| 297 | 0x000bfffb, 0x0061003f, 0x00150049, 0x0001fffb, | ||
| 298 | 0x000cfffa, 0x00620041, 0x00140048, 0x0000fffb, | ||
| 299 | 0x000dfffa, 0x00620042, 0x00130046, 0x0001fffb, | ||
| 300 | 0x000efffa, 0x00620044, 0x00110044, 0x0002fffb | ||
| 301 | }; | ||
| 302 | |||
| 303 | static const u32 coef_lut_f_y_legacy[NB_COEF] = { | ||
| 304 | 0xfff6fff0, 0x00490012, 0x0049006e, 0xfff60012, | ||
| 305 | 0xfff7fff1, 0x004e0013, 0x00490068, 0xfff60010, | ||
| 306 | 0xfff7fff2, 0x004f0015, 0x00470067, 0xfff6000f, | ||
| 307 | 0xfff7fff5, 0x004f0017, 0x00450065, 0xfff6000e, | ||
| 308 | 0xfff8fff5, 0x00500018, 0x00440065, 0xfff6000c, | ||
| 309 | 0xfff8fff6, 0x0051001a, 0x00420064, 0xfff6000b, | ||
| 310 | 0xfff8fff6, 0x0052001c, 0x00400064, 0xfff6000a, | ||
| 311 | 0xfff9fff6, 0x0054001d, 0x003e0064, 0xfff60008, | ||
| 312 | 0xfff9fff8, 0x0054001f, 0x003c0063, 0xfff60007, | ||
| 313 | 0xfffafff8, 0x00550021, 0x003a0062, 0xfff60006, | ||
| 314 | 0xfffbfff7, 0x00560022, 0x00390062, 0xfff60005, | ||
| 315 | 0xfffbfff8, 0x00570024, 0x00370061, 0xfff60004, | ||
| 316 | 0xfffcfff8, 0x00580026, 0x00350060, 0xfff60003, | ||
| 317 | 0xfffdfff8, 0x00590028, 0x0033005f, 0xfff60002, | ||
| 318 | 0xfffdfff7, 0x005b002a, 0x0031005f, 0xfff60001, | ||
| 319 | 0xfffefff7, 0x005c002c, 0x002f005e, 0xfff60000, | ||
| 320 | 0xfffffff6, 0x005e002d, 0x002d005e, 0xfff6ffff, | ||
| 321 | 0x0000fff6, 0x005e002f, 0x002c005c, 0xfff7fffe, | ||
| 322 | 0x0001fff6, 0x005f0031, 0x002a005b, 0xfff7fffd, | ||
| 323 | 0x0002fff6, 0x005f0033, 0x00280059, 0xfff8fffd, | ||
| 324 | 0x0003fff6, 0x00600035, 0x00260058, 0xfff8fffc, | ||
| 325 | 0x0004fff6, 0x00610037, 0x00240057, 0xfff8fffb, | ||
| 326 | 0x0005fff6, 0x00620039, 0x00220056, 0xfff7fffb, | ||
| 327 | 0x0006fff6, 0x0062003a, 0x00210055, 0xfff8fffa, | ||
| 328 | 0x0007fff6, 0x0063003c, 0x001f0054, 0xfff8fff9, | ||
| 329 | 0x0008fff6, 0x0064003e, 0x001d0054, 0xfff6fff9, | ||
| 330 | 0x000afff6, 0x00640040, 0x001c0052, 0xfff6fff8, | ||
| 331 | 0x000bfff6, 0x00640042, 0x001a0051, 0xfff6fff8, | ||
| 332 | 0x000cfff6, 0x00650044, 0x00180050, 0xfff5fff8, | ||
| 333 | 0x000efff6, 0x00650045, 0x0017004f, 0xfff5fff7, | ||
| 334 | 0x000ffff6, 0x00670047, 0x0015004f, 0xfff2fff7, | ||
| 335 | 0x0010fff6, 0x00680049, 0x0013004e, 0xfff1fff7 | ||
| 336 | }; | ||
| 337 | |||
| 338 | static const u32 coef_lut_f_c_legacy[NB_COEF] = { | ||
| 339 | 0x0000fffb, 0x003a001a, 0x003a005d, 0x0000001a, | ||
| 340 | 0x0001fffb, 0x003f001b, 0x00400051, 0x00000019, | ||
| 341 | 0x0001fffc, 0x0040001c, 0x003f0051, 0x00000017, | ||
| 342 | 0x0002fffb, 0x0042001d, 0x003e0051, 0xffff0016, | ||
| 343 | 0x0002fffb, 0x0043001e, 0x003d0051, 0xffff0015, | ||
| 344 | 0x0003fffc, 0x00430020, 0x003b0050, 0xffff0014, | ||
| 345 | 0x0003fffb, 0x00450021, 0x003a0051, 0xfffe0013, | ||
| 346 | 0x0004fffc, 0x00450022, 0x00390050, 0xfffe0012, | ||
| 347 | 0x0005fffc, 0x00460023, 0x0038004f, 0xfffe0011, | ||
| 348 | 0x0005fffb, 0x00480025, 0x00360050, 0xfffd0010, | ||
| 349 | 0x0006fffc, 0x00480026, 0x0035004f, 0xfffd000f, | ||
| 350 | 0x0006fffc, 0x00490027, 0x0034004f, 0xfffd000e, | ||
| 351 | 0x0007fffd, 0x00490028, 0x0033004e, 0xfffd000d, | ||
| 352 | 0x0008fffc, 0x004a002a, 0x0031004d, 0xfffd000d, | ||
| 353 | 0x0009fffd, 0x004a002b, 0x0030004d, 0xfffc000c, | ||
| 354 | 0x0009fffc, 0x004c002c, 0x002f004d, 0xfffc000b, | ||
| 355 | 0x000afffc, 0x004c002e, 0x002e004c, 0xfffc000a, | ||
| 356 | 0x000bfffc, 0x004d002f, 0x002c004c, 0xfffc0009, | ||
| 357 | 0x000cfffc, 0x004d0030, 0x002b004a, 0xfffd0009, | ||
| 358 | 0x000dfffd, 0x004d0031, 0x002a004a, 0xfffc0008, | ||
| 359 | 0x000dfffd, 0x004e0033, 0x00280049, 0xfffd0007, | ||
| 360 | 0x000efffd, 0x004f0034, 0x00270049, 0xfffc0006, | ||
| 361 | 0x000ffffd, 0x004f0035, 0x00260048, 0xfffc0006, | ||
| 362 | 0x0010fffd, 0x00500036, 0x00250048, 0xfffb0005, | ||
| 363 | 0x0011fffe, 0x004f0038, 0x00230046, 0xfffc0005, | ||
| 364 | 0x0012fffe, 0x00500039, 0x00220045, 0xfffc0004, | ||
| 365 | 0x0013fffe, 0x0051003a, 0x00210045, 0xfffb0003, | ||
| 366 | 0x0014ffff, 0x0050003b, 0x00200043, 0xfffc0003, | ||
| 367 | 0x0015ffff, 0x0051003d, 0x001e0043, 0xfffb0002, | ||
| 368 | 0x0016ffff, 0x0051003e, 0x001d0042, 0xfffb0002, | ||
| 369 | 0x00170000, 0x0051003f, 0x001c0040, 0xfffc0001, | ||
| 370 | 0x00190000, 0x00510040, 0x001b003f, 0xfffb0001 | ||
| 371 | }; | ||
| 372 | |||
| 373 | #endif | ||
diff --git a/drivers/gpu/drm/sti/sti_layer.c b/drivers/gpu/drm/sti/sti_layer.c index 5051b4cfc46b..480ec1c974e2 100644 --- a/drivers/gpu/drm/sti/sti_layer.c +++ b/drivers/gpu/drm/sti/sti_layer.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "sti_compositor.h" | 13 | #include "sti_compositor.h" |
| 14 | #include "sti_cursor.h" | 14 | #include "sti_cursor.h" |
| 15 | #include "sti_gdp.h" | 15 | #include "sti_gdp.h" |
| 16 | #include "sti_hqvdp.h" | ||
| 16 | #include "sti_layer.h" | 17 | #include "sti_layer.h" |
| 17 | #include "sti_vid.h" | 18 | #include "sti_vid.h" |
| 18 | 19 | ||
| @@ -33,6 +34,8 @@ const char *sti_layer_to_str(struct sti_layer *layer) | |||
| 33 | return "VID1"; | 34 | return "VID1"; |
| 34 | case STI_CURSOR: | 35 | case STI_CURSOR: |
| 35 | return "CURSOR"; | 36 | return "CURSOR"; |
| 37 | case STI_HQVDP_0: | ||
| 38 | return "HQVDP0"; | ||
| 36 | default: | 39 | default: |
| 37 | return "<UNKNOWN LAYER>"; | 40 | return "<UNKNOWN LAYER>"; |
| 38 | } | 41 | } |
| @@ -54,6 +57,9 @@ struct sti_layer *sti_layer_create(struct device *dev, int desc, | |||
| 54 | case STI_CUR: | 57 | case STI_CUR: |
| 55 | layer = sti_cursor_create(dev); | 58 | layer = sti_cursor_create(dev); |
| 56 | break; | 59 | break; |
| 60 | case STI_VDP: | ||
| 61 | layer = sti_hqvdp_create(dev); | ||
| 62 | break; | ||
| 57 | } | 63 | } |
| 58 | 64 | ||
| 59 | if (!layer) { | 65 | if (!layer) { |
| @@ -72,7 +78,9 @@ struct sti_layer *sti_layer_create(struct device *dev, int desc, | |||
| 72 | return layer; | 78 | return layer; |
| 73 | } | 79 | } |
| 74 | 80 | ||
| 75 | int sti_layer_prepare(struct sti_layer *layer, struct drm_framebuffer *fb, | 81 | int sti_layer_prepare(struct sti_layer *layer, |
| 82 | struct drm_crtc *crtc, | ||
| 83 | struct drm_framebuffer *fb, | ||
| 76 | struct drm_display_mode *mode, int mixer_id, | 84 | struct drm_display_mode *mode, int mixer_id, |
| 77 | int dest_x, int dest_y, int dest_w, int dest_h, | 85 | int dest_x, int dest_y, int dest_w, int dest_h, |
| 78 | int src_x, int src_y, int src_w, int src_h) | 86 | int src_x, int src_y, int src_w, int src_h) |
| @@ -92,6 +100,7 @@ int sti_layer_prepare(struct sti_layer *layer, struct drm_framebuffer *fb, | |||
| 92 | return 1; | 100 | return 1; |
| 93 | } | 101 | } |
| 94 | 102 | ||
| 103 | layer->crtc = crtc; | ||
| 95 | layer->fb = fb; | 104 | layer->fb = fb; |
| 96 | layer->mode = mode; | 105 | layer->mode = mode; |
| 97 | layer->mixer_id = mixer_id; | 106 | layer->mixer_id = mixer_id; |
diff --git a/drivers/gpu/drm/sti/sti_layer.h b/drivers/gpu/drm/sti/sti_layer.h index 68bfdca4d738..ceff497f557e 100644 --- a/drivers/gpu/drm/sti/sti_layer.h +++ b/drivers/gpu/drm/sti/sti_layer.h | |||
| @@ -22,7 +22,8 @@ enum sti_layer_type { | |||
| 22 | STI_GDP = 1 << STI_LAYER_TYPE_SHIFT, | 22 | STI_GDP = 1 << STI_LAYER_TYPE_SHIFT, |
| 23 | STI_VID = 2 << STI_LAYER_TYPE_SHIFT, | 23 | STI_VID = 2 << STI_LAYER_TYPE_SHIFT, |
| 24 | STI_CUR = 3 << STI_LAYER_TYPE_SHIFT, | 24 | STI_CUR = 3 << STI_LAYER_TYPE_SHIFT, |
| 25 | STI_BCK = 4 << STI_LAYER_TYPE_SHIFT | 25 | STI_BCK = 4 << STI_LAYER_TYPE_SHIFT, |
| 26 | STI_VDP = 5 << STI_LAYER_TYPE_SHIFT | ||
| 26 | }; | 27 | }; |
| 27 | 28 | ||
| 28 | enum sti_layer_id_of_type { | 29 | enum sti_layer_id_of_type { |
| @@ -39,6 +40,7 @@ enum sti_layer_desc { | |||
| 39 | STI_GDP_3 = STI_GDP | STI_ID_3, | 40 | STI_GDP_3 = STI_GDP | STI_ID_3, |
| 40 | STI_VID_0 = STI_VID | STI_ID_0, | 41 | STI_VID_0 = STI_VID | STI_ID_0, |
| 41 | STI_VID_1 = STI_VID | STI_ID_1, | 42 | STI_VID_1 = STI_VID | STI_ID_1, |
| 43 | STI_HQVDP_0 = STI_VDP | STI_ID_0, | ||
| 42 | STI_CURSOR = STI_CUR, | 44 | STI_CURSOR = STI_CUR, |
| 43 | STI_BACK = STI_BCK | 45 | STI_BACK = STI_BCK |
| 44 | }; | 46 | }; |
| @@ -67,6 +69,7 @@ struct sti_layer_funcs { | |||
| 67 | * | 69 | * |
| 68 | * @plane: drm plane it is bound to (if any) | 70 | * @plane: drm plane it is bound to (if any) |
| 69 | * @fb: drm fb it is bound to | 71 | * @fb: drm fb it is bound to |
| 72 | * @crtc: crtc it is bound to | ||
| 70 | * @mode: display mode | 73 | * @mode: display mode |
| 71 | * @desc: layer type & id | 74 | * @desc: layer type & id |
| 72 | * @device: driver device | 75 | * @device: driver device |
| @@ -88,6 +91,7 @@ struct sti_layer_funcs { | |||
| 88 | struct sti_layer { | 91 | struct sti_layer { |
| 89 | struct drm_plane plane; | 92 | struct drm_plane plane; |
| 90 | struct drm_framebuffer *fb; | 93 | struct drm_framebuffer *fb; |
| 94 | struct drm_crtc *crtc; | ||
| 91 | struct drm_display_mode *mode; | 95 | struct drm_display_mode *mode; |
| 92 | enum sti_layer_desc desc; | 96 | enum sti_layer_desc desc; |
| 93 | struct device *dev; | 97 | struct device *dev; |
| @@ -109,7 +113,9 @@ struct sti_layer { | |||
| 109 | 113 | ||
| 110 | struct sti_layer *sti_layer_create(struct device *dev, int desc, | 114 | struct sti_layer *sti_layer_create(struct device *dev, int desc, |
| 111 | void __iomem *baseaddr); | 115 | void __iomem *baseaddr); |
| 112 | int sti_layer_prepare(struct sti_layer *layer, struct drm_framebuffer *fb, | 116 | int sti_layer_prepare(struct sti_layer *layer, |
| 117 | struct drm_crtc *crtc, | ||
| 118 | struct drm_framebuffer *fb, | ||
| 113 | struct drm_display_mode *mode, | 119 | struct drm_display_mode *mode, |
| 114 | int mixer_id, | 120 | int mixer_id, |
| 115 | int dest_x, int dest_y, | 121 | int dest_x, int dest_y, |
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c index 9a4ce74ac329..13a4b84deab6 100644 --- a/drivers/gpu/drm/sti/sti_mixer.c +++ b/drivers/gpu/drm/sti/sti_mixer.c | |||
| @@ -123,6 +123,7 @@ int sti_mixer_set_layer_depth(struct sti_mixer *mixer, struct sti_layer *layer) | |||
| 123 | layer_id = GAM_DEPTH_GDP3_ID; | 123 | layer_id = GAM_DEPTH_GDP3_ID; |
| 124 | break; | 124 | break; |
| 125 | case STI_VID_0: | 125 | case STI_VID_0: |
| 126 | case STI_HQVDP_0: | ||
| 126 | layer_id = GAM_DEPTH_VID0_ID; | 127 | layer_id = GAM_DEPTH_VID0_ID; |
| 127 | break; | 128 | break; |
| 128 | case STI_VID_1: | 129 | case STI_VID_1: |
| @@ -189,6 +190,7 @@ static u32 sti_mixer_get_layer_mask(struct sti_layer *layer) | |||
| 189 | case STI_GDP_3: | 190 | case STI_GDP_3: |
| 190 | return GAM_CTL_GDP3_MASK; | 191 | return GAM_CTL_GDP3_MASK; |
| 191 | case STI_VID_0: | 192 | case STI_VID_0: |
| 193 | case STI_HQVDP_0: | ||
| 192 | return GAM_CTL_VID0_MASK; | 194 | return GAM_CTL_VID0_MASK; |
| 193 | case STI_VID_1: | 195 | case STI_VID_1: |
| 194 | return GAM_CTL_VID1_MASK; | 196 | return GAM_CTL_VID1_MASK; |
