1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#pragma once 6 7#include <assert.h> 8#include <stdint.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12#include <ddk/device.h> 13#include <ddk/io-buffer.h> 14#include <ddk/protocol/platform-device.h> 15#include <zircon/listnode.h> 16#include <zircon/types.h> 17#include <threads.h> 18#include "vpu.h" 19#include "dwc-hdmi.h" 20 21__BEGIN_CDECLS 22 23#define DISPLAY_MASK(start, count) (((1 << (count)) - 1) << (start)) 24#define DISPLAY_SET_MASK(mask, start, count, value) \ 25 ((mask & ~DISPLAY_MASK(start, count)) | \ 26 (((value) << (start)) & DISPLAY_MASK(start, count))) 27 28#define READ32_PRESET_REG(a) readl((uint8_t*)io_buffer_virt(&display->mmio_preset) + a) 29#define WRITE32_PRESET_REG(a, v) writel(v, (uint8_t*)io_buffer_virt(&display->mmio_preset) + a) 30 31#define READ32_HDMITX_REG(a) readl((uint8_t*)io_buffer_virt(&display->mmio_hdmitx) + a) 32#define WRITE32_HDMITX_REG(a, v) writel(v, (uint8_t*)io_buffer_virt(&display->mmio_hdmitx) + a) 33 34#define READ32_HHI_REG(a) readl((uint8_t*)io_buffer_virt(&display->mmio_hiu) + a) 35#define WRITE32_HHI_REG(a, v) writel(v, (uint8_t*)io_buffer_virt(&display->mmio_hiu) + a) 36 37#define READ32_VPU_REG(a) readl((uint8_t*)io_buffer_virt(&display->mmio_vpu) + a) 38#define WRITE32_VPU_REG(a, v) writel(v, (uint8_t*)io_buffer_virt(&display->mmio_vpu) + a) 39 40#define READ32_HDMITX_SEC_REG(a) readl((uint8_t*)io_buffer_virt(&display->mmio_hdmitx_sec) + a) 41#define WRITE32_HDMITX_SEC_REG(a, v) writel(v, (uint8_t*)io_buffer_virt(&display->mmio_hdmitx_sec) + a) 42 43#define READ32_CBUS_REG(a) readl((uint8_t*)io_buffer_virt(&display->mmio_cbus) + 0x400 + a) 44#define WRITE32_CBUS_REG(a, v) writel(v, (uint8_t*)io_buffer_virt(&display->mmio_cbus) + 0x400+ a) 45 46#define SET_BIT32(x, dest, value, count, start) \ 47 WRITE32_##x##_REG(dest, (READ32_##x##_REG(dest) & ~DISPLAY_MASK(start, count)) | \ 48 (((value) << (start)) & DISPLAY_MASK(start, count))) 49 50#define WRITE32_REG(x, a, v) WRITE32_##x##_REG(a, v) 51#define READ32_REG(x, a) READ32_##x##_REG(a) 52 53#define SEC_OFFSET (0x1UL << 24) 54#define TOP_OFFSET_MASK (0x0UL << 24) 55#define TOP_SEC_OFFSET_MASK ((TOP_OFFSET_MASK) | (SEC_OFFSET)) 56#define DWC_OFFSET_MASK (0x10UL << 24) 57#define DWC_SEC_OFFSET_MASK ((DWC_OFFSET_MASK) | (SEC_OFFSET)) 58 59#define DMC_CAV_LUT_DATAL (0x12 << 2) 60#define DMC_CAV_LUT_DATAH (0x13 << 2) 61#define DMC_CAV_LUT_ADDR (0x14 << 2) 62 63#define DMC_CAV_ADDR_LMASK 0x1fffffff 64#define DMC_CAV_WIDTH_LMASK 0x7 65#define DMC_CAV_WIDTH_LWID 3 66#define DMC_CAV_WIDTH_LBIT 29 67 68#define DMC_CAV_WIDTH_HMASK 0x1ff 69#define DMC_CAV_WIDTH_HBIT 0 70#define DMC_CAV_HEIGHT_MASK 0x1fff 71#define DMC_CAV_HEIGHT_BIT 9 72 73#define DMC_CAV_LUT_ADDR_INDEX_MASK 0x7 74#define DMC_CAV_LUT_ADDR_RD_EN (1 << 8) 75#define DMC_CAV_LUT_ADDR_WR_EN (2 << 8) 76 77 78// P RESET 79#define PRESET_REGISTER (0x400) 80#define PRESET0_REGISTER (0x404) 81#define PRESET2_REGISTER (0x40C) 82 83// HDMITX ADDRESS and DATA PORTS 84#define HDMITX_ADDR_PORT (0x00) 85#define HDMITX_DATA_PORT (0x04) 86#define HDMITX_CTRL_PORT (0x08) 87 88 89// HDMI TOP 90#define HDMITX_TOP_SW_RESET (TOP_OFFSET_MASK + 0x000) 91#define HDMITX_TOP_CLK_CNTL (TOP_OFFSET_MASK + 0x001) 92#define HDMITX_TOP_HPD_FILTER (TOP_OFFSET_MASK + 0x002) 93#define HDMITX_TOP_INTR_MASKN (TOP_OFFSET_MASK + 0x003) 94#define HDMITX_TOP_INTR_STAT (TOP_OFFSET_MASK + 0x004) 95#define HDMITX_TOP_INTR_STAT_CLR (TOP_OFFSET_MASK + 0x005) 96#define HDMITX_TOP_BIST_CNTL (TOP_OFFSET_MASK + 0x006) 97#define HDMITX_TOP_SHIFT_PTTN_012 (TOP_OFFSET_MASK + 0x007) 98#define HDMITX_TOP_SHIFT_PTTN_345 (TOP_OFFSET_MASK + 0x008) 99#define HDMITX_TOP_SHIFT_PTTN_67 (TOP_OFFSET_MASK + 0x009) 100#define HDMITX_TOP_TMDS_CLK_PTTN_01 (TOP_OFFSET_MASK + 0x00A) 101#define HDMITX_TOP_TMDS_CLK_PTTN_23 (TOP_OFFSET_MASK + 0x00B) 102#define HDMITX_TOP_TMDS_CLK_PTTN_CNTL (TOP_OFFSET_MASK + 0x00C) 103#define HDMITX_TOP_REVOCMEM_STAT (TOP_OFFSET_MASK + 0x00D) 104#define HDMITX_TOP_STAT0 (TOP_OFFSET_MASK + 0x00E) 105#define HDMITX_TOP_SKP_CNTL_STAT (TOP_SEC_OFFSET_MASK + 0x010) 106#define HDMITX_TOP_NONCE_0 (TOP_SEC_OFFSET_MASK + 0x011) 107#define HDMITX_TOP_NONCE_1 (TOP_SEC_OFFSET_MASK + 0x012) 108#define HDMITX_TOP_NONCE_2 (TOP_SEC_OFFSET_MASK + 0x013) 109#define HDMITX_TOP_NONCE_3 (TOP_SEC_OFFSET_MASK + 0x014) 110#define HDMITX_TOP_PKF_0 (TOP_SEC_OFFSET_MASK + 0x015) 111#define HDMITX_TOP_PKF_1 (TOP_SEC_OFFSET_MASK + 0x016) 112#define HDMITX_TOP_PKF_2 (TOP_SEC_OFFSET_MASK + 0x017) 113#define HDMITX_TOP_PKF_3 (TOP_SEC_OFFSET_MASK + 0x018) 114#define HDMITX_TOP_DUK_0 (TOP_SEC_OFFSET_MASK + 0x019) 115#define HDMITX_TOP_DUK_1 (TOP_SEC_OFFSET_MASK + 0x01A) 116#define HDMITX_TOP_DUK_2 (TOP_SEC_OFFSET_MASK + 0x01B) 117#define HDMITX_TOP_DUK_3 (TOP_SEC_OFFSET_MASK + 0x01C) 118#define HDMITX_TOP_INFILTER (TOP_OFFSET_MASK + 0x01D) 119#define HDMITX_TOP_NSEC_SCRATCH (TOP_OFFSET_MASK + 0x01E) 120#define HDMITX_TOP_SEC_SCRATCH (TOP_SEC_OFFSET_MASK + 0x01F) 121#define HDMITX_TOP_DONT_TOUCH0 (TOP_OFFSET_MASK + 0x0FE) 122#define HDMITX_TOP_DONT_TOUCH1 (TOP_OFFSET_MASK + 0x0FF) 123 124 125 126 127#define PAD_PULL_UP_EN_REG1 (0x49 << 2) 128#define PAD_PULL_UP_REG1 (0x3d << 2) 129#define P_PREG_PAD_GPIO1_EN_N (0x0f << 2) 130#define PERIPHS_PIN_MUX_6 (0x32 << 2) 131 132struct reg_val_pair { 133 uint32_t reg; 134 uint32_t val; 135}; 136 137static const struct reg_val_pair ENC_LUT_GEN[] = { 138 {VPU_ENCP_VIDEO_EN, 0,}, 139 {VPU_ENCI_VIDEO_EN, 0,}, 140 {VPU_ENCP_VIDEO_MODE, 0x4040,}, 141 {VPU_ENCP_VIDEO_MODE_ADV, 0x18,}, 142 {VPU_VPU_VIU_VENC_MUX_CTRL, 0xA}, 143 {VPU_ENCP_VIDEO_VSO_BEGIN, 16}, 144 {VPU_ENCP_VIDEO_VSO_END, 32}, 145 {VPU_ENCI_VIDEO_EN, 0}, 146 {VPU_ENCP_VIDEO_EN, 1}, 147 { 0xFFFFFFFF, 0}, 148}; 149 150struct cea_timing { 151 bool interlace_mode; 152 uint32_t pfreq; 153 uint8_t ln; 154 uint8_t pixel_repeat; 155 uint8_t venc_pixel_repeat; 156 157 uint32_t hfreq; 158 uint32_t hactive; 159 uint32_t htotal; 160 uint32_t hblank; 161 uint32_t hfront; 162 uint32_t hsync; 163 uint32_t hback; 164 bool hpol; 165 166 uint32_t vfreq; 167 uint32_t vactive; 168 uint32_t vtotal; 169 uint32_t vblank0; // in case of interlace 170 uint32_t vblank1; // vblank0 + 1 for interlace 171 uint32_t vfront; 172 uint32_t vsync; 173 uint32_t vback; 174 bool vpol; 175}; 176 177#define VID_PLL_DIV_1 0 178#define VID_PLL_DIV_2 1 179#define VID_PLL_DIV_3 2 180#define VID_PLL_DIV_3p5 3 181#define VID_PLL_DIV_3p75 4 182#define VID_PLL_DIV_4 5 183#define VID_PLL_DIV_5 6 184#define VID_PLL_DIV_6 7 185#define VID_PLL_DIV_6p25 8 186#define VID_PLL_DIV_7 9 187#define VID_PLL_DIV_7p5 10 188#define VID_PLL_DIV_12 11 189#define VID_PLL_DIV_14 12 190#define VID_PLL_DIV_15 13 191#define VID_PLL_DIV_2p5 14 192 193enum viu_type { 194 VIU_ENCL = 0, 195 VIU_ENCI, 196 VIU_ENCP, 197 VIU_ENCT, 198}; 199 200struct pll_param { 201 uint32_t mode; 202 uint32_t viu_channel; 203 uint32_t viu_type; 204 uint32_t hpll_clk_out; 205 uint32_t od1; 206 uint32_t od2; 207 uint32_t od3; 208 uint32_t vid_pll_div; 209 uint32_t vid_clk_div; 210 uint32_t hdmi_tx_pixel_div; 211 uint32_t encp_div; 212 uint32_t enci_div; 213}; 214 215struct hdmi_param { 216 uint16_t vic; 217 uint8_t aspect_ratio; 218 uint8_t colorimetry; 219 uint8_t phy_mode; 220 struct pll_param pll_p_24b; 221 struct cea_timing timings; 222 bool is4K; 223}; 224 225#define HDMI_COLOR_DEPTH_24B 4 226#define HDMI_COLOR_DEPTH_30B 5 227#define HDMI_COLOR_DEPTH_36B 6 228#define HDMI_COLOR_DEPTH_48B 7 229 230#define HDMI_COLOR_FORMAT_RGB 0 231#define HDMI_COLOR_FORMAT_444 1 232 233#define HDMI_ASPECT_RATIO_NONE 0 234#define HDMI_ASPECT_RATIO_4x3 1 235#define HDMI_ASPECT_RATIO_16x9 2 236 237#define HDMI_COLORIMETRY_ITU601 1 238#define HDMI_COLORIMETRY_ITU709 2 239 240/* VIC lookup */ 241 #define VIC_720x480p_60Hz_4x3 2 242 #define VIC_720x480p_60Hz_16x9 3 243 #define VIC_1280x720p_60Hz_16x9 4 244 #define VIC_1920x1080i_60Hz_16x9 5 245 #define VIC_720x480i_60Hz_4x3 6 246 #define VIC_720x480i_60Hz_16x9 7 247 #define VIC_720x240p_60Hz_4x3 8 248 #define VIC_720x240p_60Hz_16x9 9 249 #define VIC_2880x480i_60Hz_4x3 10 250 #define VIC_2880x480i_60Hz_16x9 11 251 #define VIC_2880x240p_60Hz_4x3 12 252 #define VIC_2880x240p_60Hz_16x9 13 253 #define VIC_1440x480p_60Hz_4x3 14 254 #define VIC_1440x480p_60Hz_16x9 15 255 #define VIC_1920x1080p_60Hz_16x9 16 256 #define VIC_720x576p_50Hz_4x3 17 257 #define VIC_720x576p_50Hz_16x9 18 258 #define VIC_1280x720p_50Hz_16x9 19 259 #define VIC_1920x1080i_50Hz_16x9 20 260 #define VIC_720x576i_50Hz_4x3 21 261 #define VIC_720x576i_50Hz_16x9 22 262 #define VIC_720x288p_50Hz_4x3 23 263 #define VIC_720x288p_50Hz_16x9 24 264 #define VIC_2880x576i_50Hz_4x3 25 265 #define VIC_2880x576i_50Hz_16x9 26 266 #define VIC_2880x288p_50Hz_4x3 27 267 #define VIC_2880x288p_50Hz_16x9 28 268 #define VIC_1440x576p_50Hz_4x3 29 269 #define VIC_1440x576p_50Hz_16x9 30 270 #define VIC_1920x1080p_50Hz_16x9 31 271 #define VIC_1920x1080p_24Hz_16x9 32 272 #define VIC_1920x1080p_25Hz_16x9 33 273 #define VIC_1920x1080p_30Hz_16x9 34 274 #define VIC_2880x480p_60Hz_4x3 35 275 #define VIC_2880x480p_60Hz_16x9 36 276 #define VIC_2880x576p_50Hz_4x3 37 277 #define VIC_2880x576p_50Hz_16x9 38 278 #define VIC_1920x1080i_1250_50Hz_16x9 39 279 #define VIC_1920x1080i_100Hz_16x9 40 280 #define VIC_1280x720p_100Hz_16x9 41 281 #define VIC_720x576p_100Hz_4x3 42 282 #define VIC_720x576p_100Hz_16x9 43 283 #define VIC_720x576i_100Hz_4x3 44 284 #define VIC_720x576i_100Hz_16x9 45 285 #define VIC_1920x1080i_120Hz_16x9 46 286 #define VIC_1280x720p_120Hz_16x9 47 287 #define VIC_720x480p_120Hz_4x3 48 288 #define VIC_720x480p_120Hz_16x9 49 289 #define VIC_720x480i_120Hz_4x3 50 290 #define VIC_720x480i_120Hz_16x9 51 291 #define VIC_720x576p_200Hz_4x3 52 292 #define VIC_720x576p_200Hz_16x9 53 293 #define VIC_720x576i_200Hz_4x3 54 294 #define VIC_720x576i_200Hz_16x9 55 295 #define VIC_720x480p_240Hz_4x3 56 296 #define VIC_720x480p_240Hz_16x9 57 297 #define VIC_720x480i_240Hz_4x3 58 298 #define VIC_720x480i_240Hz_16x9 59 299 #define VIC_1280x720p_24Hz_16x9 60 300 #define VIC_1280x720p_25Hz_16x9 61 301 #define VIC_1280x720p_30Hz_16x9 62 302 #define VIC_1920x1080p_120Hz_16x9 63 303 #define VIC_1920x1080p_100Hz_16x9 64 304 #define VESA_OFFSET 300 305 #define VIC_VESA_640x480p_60Hz_4x3 300 306 #define VIC_VESA_1280x800p_60Hz_16x9 301 307 #define VIC_VESA_1280x1024p_60Hz_5x4 302 308 #define VIC_VESA_1920x1200p_60Hz_8x5 303 309 #define VIC_VESA_800x600p_60Hz 304 310 #define VIC_VESA_1024x768p_60Hz 305 311 312struct vim2_display; // fwd decl 313 314void hdmitx_writereg(const struct vim2_display* display, uint32_t addr, uint32_t data); 315uint32_t hdmitx_readreg(const struct vim2_display* display, uint32_t addr); 316void init_hdmi_hardware(struct vim2_display* display); 317void dump_regs(struct vim2_display* display); 318void init_hdmi_interface(struct vim2_display* display, const struct hdmi_param* p); 319void hdmi_test(struct vim2_display* display, uint32_t width); 320zx_status_t configure_pll(struct vim2_display* display, const struct hdmi_param* p, 321 const struct pll_param* pll); 322void hdmi_shutdown(struct vim2_display* display); 323 324__END_CDECLS 325