tda998x_drv.c revision bcb2481df01a9aee7a09b20d43194011edd35754
1e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* 2e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * Copyright (C) 2012 Texas Instruments 3e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * Author: Rob Clark <robdclark@gmail.com> 4e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * 5e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * This program is free software; you can redistribute it and/or modify it 6e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * under the terms of the GNU General Public License version 2 as published by 7e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * the Free Software Foundation. 8e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * 9e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * This program is distributed in the hope that it will be useful, but WITHOUT 10e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * more details. 13e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * 14e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * You should have received a copy of the GNU General Public License along with 15e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * this program. If not, see <http://www.gnu.org/licenses/>. 16e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 17e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 18e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 19e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 20e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <linux/module.h> 21e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 22e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drmP.h> 23e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_crtc_helper.h> 24e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_encoder_slave.h> 25e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_edid.h> 26e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 27e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 28e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 29e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 30e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstruct tda998x_priv { 31e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *cec; 32e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint16_t rev; 33e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t current_page; 34e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int dpms; 35e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 36e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 37e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv) 38e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 39e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* The TDA9988 series of devices use a paged register scheme.. to simplify 40e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * things we encode the page # in upper bits of the register #. To read/ 41e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * write a given register, we need to make sure CURPAGE register is set 42e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * appropriately. Which implies reads/writes are not atomic. Fun! 43e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 44e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 45e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG(page, addr) (((page) << 8) | (addr)) 46e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG2ADDR(reg) ((reg) & 0xff) 47e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG2PAGE(reg) (((reg) >> 8) & 0xff) 48e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 49e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CURPAGE 0xff /* write */ 50e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 51e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 52e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 00h: General Control */ 53e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VERSION_LSB REG(0x00, 0x00) /* read */ 54e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_MAIN_CNTRL0 REG(0x00, 0x01) /* read/write */ 55e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_SR (1 << 0) 56e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_DECS (1 << 1) 57e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_DEHS (1 << 2) 58e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_CECS (1 << 3) 59e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_CEHS (1 << 4) 60e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_SCALER (1 << 7) 61e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VERSION_MSB REG(0x00, 0x02) /* read */ 62e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SOFTRESET REG(0x00, 0x0a) /* write */ 63e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SOFTRESET_AUDIO (1 << 0) 64e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SOFTRESET_I2C_MASTER (1 << 1) 65e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_DISABLE REG(0x00, 0x0b) /* read/write */ 66e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CCLK_ON REG(0x00, 0x0c) /* read/write */ 67e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_I2C_MASTER REG(0x00, 0x0d) /* read/write */ 68e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_DIS_MM (1 << 0) 69e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_DIS_FILT (1 << 1) 70e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_APP_STRT_LAT (1 << 2) 71e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_0 REG(0x00, 0x0f) /* read/write */ 72e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_1 REG(0x00, 0x10) /* read/write */ 73e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_2 REG(0x00, 0x11) /* read/write */ 74e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define INT_FLAGS_2_EDID_BLK_RD (1 << 1) 75e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_0 REG(0x00, 0x18) /* read/write */ 76e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_1 REG(0x00, 0x19) /* read/write */ 77e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_2 REG(0x00, 0x1a) /* read/write */ 78e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_AP REG(0x00, 0x1e) /* read/write */ 79e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_0 REG(0x00, 0x20) /* write */ 80e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_MIRR_A (1 << 7) 81e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_SWAP_A(x) (((x) & 7) << 4) 82e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_MIRR_B (1 << 3) 83e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_SWAP_B(x) (((x) & 7) << 0) 84e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_1 REG(0x00, 0x21) /* write */ 85e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_MIRR_C (1 << 7) 86e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_SWAP_C(x) (((x) & 7) << 4) 87e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_MIRR_D (1 << 3) 88e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_SWAP_D(x) (((x) & 7) << 0) 89e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_2 REG(0x00, 0x22) /* write */ 90e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_MIRR_E (1 << 7) 91e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_SWAP_E(x) (((x) & 7) << 4) 92e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_MIRR_F (1 << 3) 93e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_SWAP_F(x) (((x) & 7) << 0) 94e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_3 REG(0x00, 0x23) /* write */ 95e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_X_TGL (1 << 0) 96e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_H_TGL (1 << 1) 97e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_V_TGL (1 << 2) 98e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_EMB (1 << 3) 99e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_SYNC_DE (1 << 4) 100e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_SYNC_HS (1 << 5) 101e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_DE_INT (1 << 6) 102e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_EDGE (1 << 7) 103e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_4 REG(0x00, 0x24) /* write */ 104e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_BLC(x) (((x) & 3) << 0) 105e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_BLANKIT(x) (((x) & 3) << 2) 106e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_CCIR656 (1 << 4) 107e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_656_ALT (1 << 5) 108e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_TST_656 (1 << 6) 109e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_TST_PAT (1 << 7) 110e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */ 111e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_5_CKCASE (1 << 0) 112e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1) 113bcb2481df01a9aee7a09b20d43194011edd35754Russell King#define REG_MUX_VP_VIP_OUT REG(0x00, 0x27) /* read/write */ 114e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_MAT_CONTRL REG(0x00, 0x80) /* write */ 115e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0) 116e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAT_CONTRL_MAT_BP (1 << 2) 117e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIDFORMAT REG(0x00, 0xa0) /* write */ 118e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFPIX_MSB REG(0x00, 0xa1) /* write */ 119e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFPIX_LSB REG(0x00, 0xa2) /* write */ 120e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFLINE_MSB REG(0x00, 0xa3) /* write */ 121e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFLINE_LSB REG(0x00, 0xa4) /* write */ 122e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NPIX_MSB REG(0x00, 0xa5) /* write */ 123e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NPIX_LSB REG(0x00, 0xa6) /* write */ 124e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NLINE_MSB REG(0x00, 0xa7) /* write */ 125e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NLINE_LSB REG(0x00, 0xa8) /* write */ 126e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_STRT_1_MSB REG(0x00, 0xa9) /* write */ 127e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_STRT_1_LSB REG(0x00, 0xaa) /* write */ 128e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_1_MSB REG(0x00, 0xab) /* write */ 129e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_1_LSB REG(0x00, 0xac) /* write */ 130e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_END_1_MSB REG(0x00, 0xad) /* write */ 131e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_END_1_LSB REG(0x00, 0xae) /* write */ 132e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_1_MSB REG(0x00, 0xaf) /* write */ 133e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_1_LSB REG(0x00, 0xb0) /* write */ 134e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_2_MSB REG(0x00, 0xb3) /* write */ 135e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_2_LSB REG(0x00, 0xb4) /* write */ 136e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_2_MSB REG(0x00, 0xb7) /* write */ 137e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_2_LSB REG(0x00, 0xb8) /* write */ 138e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_START_MSB REG(0x00, 0xb9) /* write */ 139e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_START_LSB REG(0x00, 0xba) /* write */ 140e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_STOP_MSB REG(0x00, 0xbb) /* write */ 141e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_STOP_LSB REG(0x00, 0xbc) /* write */ 142e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_START_1_MSB REG(0x00, 0xbd) /* write */ 143e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_START_1_LSB REG(0x00, 0xbe) /* write */ 144e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_END_1_MSB REG(0x00, 0xbf) /* write */ 145e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_END_1_LSB REG(0x00, 0xc0) /* write */ 146e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_START_MSB REG(0x00, 0xc5) /* write */ 147e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_START_LSB REG(0x00, 0xc6) /* write */ 148e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_STOP_MSB REG(0x00, 0xc7) /* write */ 149e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_STOP_LSB REG(0x00, 0xc8) /* write */ 150e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TBG_CNTRL_0 REG(0x00, 0xca) /* write */ 151e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_FRAME_DIS (1 << 5) 152e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_SYNC_MTHD (1 << 6) 153e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_SYNC_ONCE (1 << 7) 154e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TBG_CNTRL_1 REG(0x00, 0xcb) /* write */ 155e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_VH_TGL_0 (1 << 0) 156e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_VH_TGL_1 (1 << 1) 157e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_VH_TGL_2 (1 << 2) 158e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_VHX_EXT_DE (1 << 3) 159e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_VHX_EXT_HS (1 << 4) 160e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_VHX_EXT_VS (1 << 5) 161e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_DWIN_DIS (1 << 6) 162e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENABLE_SPACE REG(0x00, 0xd6) /* write */ 163e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HVF_CNTRL_0 REG(0x00, 0xe4) /* write */ 164e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_SM (1 << 7) 165e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_RWB (1 << 6) 166e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_PREFIL(x) (((x) & 3) << 2) 167e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_INTPOL(x) (((x) & 3) << 0) 168e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HVF_CNTRL_1 REG(0x00, 0xe5) /* write */ 169e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_FOR (1 << 0) 170e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_YUVBLK (1 << 1) 171e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_VQR(x) (((x) & 3) << 2) 172e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) 173e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) 174e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ 175e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 176e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 177e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 02h: PLL settings */ 178e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */ 179e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_FDN (1 << 0) 180e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) 181e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) 182e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ 183e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 3) << 0) 184e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) 185e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ 186e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_CCIR (1 << 0) 187e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_DE (1 << 2) 188e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4) 189e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SERIALIZER REG(0x02, 0x03) /* read/write */ 190e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_BUFFER_OUT REG(0x02, 0x04) /* read/write */ 191e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCG1 REG(0x02, 0x05) /* read/write */ 192e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCG2 REG(0x02, 0x06) /* read/write */ 193e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGN1 REG(0x02, 0x07) /* read/write */ 194e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGN2 REG(0x02, 0x08) /* read/write */ 195e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGR1 REG(0x02, 0x09) /* read/write */ 196e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGR2 REG(0x02, 0x0a) /* read/write */ 197e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_AUDIO_DIV REG(0x02, 0x0e) /* read/write */ 198e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SEL_CLK REG(0x02, 0x11) /* read/write */ 199e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_SEL_CLK1 (1 << 0) 200e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_SEL_VRF_CLK(x) (((x) & 3) << 1) 201e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_ENA_SC_CLK (1 << 3) 202e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ANA_GENERAL REG(0x02, 0x12) /* read/write */ 203e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 204e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 205e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 09h: EDID Control */ 206e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_EDID_DATA_0 REG(0x09, 0x00) /* read */ 207e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* next 127 successive registers are the EDID block */ 208e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_EDID_CTRL REG(0x09, 0xfa) /* read/write */ 209e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_ADDR REG(0x09, 0xfb) /* read/write */ 210e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_OFFS REG(0x09, 0xfc) /* read/write */ 211e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_SEGM_ADDR REG(0x09, 0xfd) /* read/write */ 212e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_SEGM REG(0x09, 0xfe) /* read/write */ 213e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 214e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 215e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 10h: information frames and packets */ 216e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 217e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 218e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 11h: audio settings and content info packets */ 219e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */ 220e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_RST_FIFO (1 << 0) 221e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_SWAP (1 << 1) 222e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_LAYOUT (1 << 2) 223e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_ACR_MAN (1 << 5) 224e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_RST_CTS (1 << 6) 225e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */ 226e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_RST_ENC (1 << 0) 227e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_RST_SEL (1 << 1) 228e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2) 229e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 230e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 231e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 12h: HDCP and OTP */ 232e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TX3 REG(0x12, 0x9a) /* read/write */ 233063b472fbb44ac562797a630ac3516720f588140Russell King#define REG_TX4 REG(0x12, 0x9b) /* read/write */ 234063b472fbb44ac562797a630ac3516720f588140Russell King# define TX4_PD_RAM (1 << 1) 235e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TX33 REG(0x12, 0xb8) /* read/write */ 236e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TX33_HDMI (1 << 1) 237e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 238e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 239e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 13h: Gamut related metadata packets */ 240e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 241e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 242e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 243e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* CEC registers: (not paged) 244e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 245e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_FRO_IM_CLK_CTRL 0xfb /* read/write */ 246e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7) 247e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6) 248e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1) 249e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0) 250e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_RXSHPDLEV 0xfe /* read */ 251e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_RXSHPDLEV_RXSENS (1 << 0) 252e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_RXSHPDLEV_HPD (1 << 1) 253e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 254e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_ENAMODS 0xff /* read/write */ 255e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_DIS_FRO (1 << 6) 256e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_DIS_CCLK (1 << 5) 257e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_RXSENS (1 << 2) 258e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_HDMI (1 << 1) 259e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_CEC (1 << 0) 260e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 261e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 262e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Device versions: */ 263e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA9989N2 0x0101 264e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19989 0x0201 265e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19989N2 0x0202 266e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19988 0x0301 267e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 268e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 269e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkcec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) 270e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 271e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = to_tda998x_priv(encoder)->cec; 272e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {addr, val}; 273e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 274e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 275e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 276e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 277e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr); 278e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 279e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 280e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic uint8_t 281e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkcec_read(struct drm_encoder *encoder, uint8_t addr) 282e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 283e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = to_tda998x_priv(encoder)->cec; 284e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val; 285e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 286e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 287e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, &addr, sizeof(addr)); 288e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 289e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 290e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 291e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_recv(client, &val, sizeof(val)); 292e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 293e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 294e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 295e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return val; 296e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 297e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 298e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr); 299e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 300e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 301e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 302e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 303e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkset_page(struct drm_encoder *encoder, uint16_t reg) 304e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 305e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 306e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 307e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (REG2PAGE(reg) != priv->current_page) { 308e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 309e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = { 310e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark REG_CURPAGE, REG2PAGE(reg) 311e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }; 312e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret = i2c_master_send(client, buf, sizeof(buf)); 313e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 314e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to REG_CURPAGE\n", ret); 315e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 316e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->current_page = REG2PAGE(reg); 317e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 318e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 319e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 320e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 321e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_read_range(struct drm_encoder *encoder, uint16_t reg, char *buf, int cnt) 322e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 323e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 324e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t addr = REG2ADDR(reg); 325e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 326e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 327e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark set_page(encoder, reg); 328e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 329e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, &addr, sizeof(addr)); 330e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 331e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 332e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 333e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_recv(client, buf, cnt); 334e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 335e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 336e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 337e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 338e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 339e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 340e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); 341e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 342e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 343e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 344e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic uint8_t 345e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_read(struct drm_encoder *encoder, uint16_t reg) 346e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 347e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val = 0; 348e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_read_range(encoder, reg, &val, sizeof(val)); 349e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return val; 350e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 351e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 352e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 353e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_write(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 354e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 355e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 356e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {REG2ADDR(reg), val}; 357e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 358e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 359e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark set_page(encoder, reg); 360e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 361e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 362e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 363e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 364e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 365e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 366e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 367e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_write16(struct drm_encoder *encoder, uint16_t reg, uint16_t val) 368e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 369e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 370e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; 371e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 372e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 373e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark set_page(encoder, reg); 374e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 375e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 376e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 377e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 378e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 379e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 380e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 381e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_set(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 382e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 383e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, reg, reg_read(encoder, reg) | val); 384e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 385e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 386e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 387e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_clear(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 388e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 389e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, reg, reg_read(encoder, reg) & ~val); 390e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 391e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 392e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 393e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_reset(struct drm_encoder *encoder) 394e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 395e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* reset audio and i2c master: */ 396e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); 397e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(50); 398e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); 399e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(50); 400e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 401e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* reset transmitter: */ 402e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 403e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 404e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 405e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* PLL registers common configuration */ 406e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_1, 0x00); 407e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); 408e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_3, 0x00); 409e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SERIALIZER, 0x00); 410e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_BUFFER_OUT, 0x00); 411e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCG1, 0x00); 412e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_AUDIO_DIV, 0x03); 413e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 414e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGN1, 0xfa); 415e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGN2, 0x00); 416e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGR1, 0x5b); 417e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGR2, 0x00); 418e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCG2, 0x10); 419bcb2481df01a9aee7a09b20d43194011edd35754Russell King 420bcb2481df01a9aee7a09b20d43194011edd35754Russell King /* Write the default value MUX register */ 421bcb2481df01a9aee7a09b20d43194011edd35754Russell King reg_write(encoder, REG_MUX_VP_VIP_OUT, 0x24); 422e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 423e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 424e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* DRM encoder functions */ 425e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 426e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 427e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_set_config(struct drm_encoder *encoder, void *params) 428e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 429e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 430e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 431e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 432e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_dpms(struct drm_encoder *encoder, int mode) 433e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 434e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 435e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 436e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* we only care about on or off: */ 437e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode != DRM_MODE_DPMS_ON) 438e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark mode = DRM_MODE_DPMS_OFF; 439e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 440e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode == priv->dpms) 441e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return; 442e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 443e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark switch (mode) { 444e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case DRM_MODE_DPMS_ON: 445e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* enable audio and video ports */ 446e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_AP, 0xff); 447e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_0, 0xff); 448e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_1, 0xff); 449e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_2, 0xff); 450e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set muxing after enabling ports: */ 451e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_0, 452e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3)); 453e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_1, 454e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1)); 455e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_2, 456e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5)); 457e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 458e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case DRM_MODE_DPMS_OFF: 459e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* disable audio and video ports */ 460e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_AP, 0x00); 461e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_0, 0x00); 462e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_1, 0x00); 463e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_2, 0x00); 464e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 465e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 466e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 467e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->dpms = mode; 468e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 469e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 470e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 471e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_save(struct drm_encoder *encoder) 472e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 473e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 474e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 475e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 476e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 477e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_restore(struct drm_encoder *encoder) 478e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 479e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 480e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 481e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 482e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic bool 483e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_mode_fixup(struct drm_encoder *encoder, 484e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark const struct drm_display_mode *mode, 485e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *adjusted_mode) 486e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 487e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return true; 488e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 489e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 490e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 491e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_mode_valid(struct drm_encoder *encoder, 492e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *mode) 493e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 494e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return MODE_OK; 495e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 496e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 497e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 498e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_mode_set(struct drm_encoder *encoder, 499e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *mode, 500e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *adjusted_mode) 501e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 502e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 503e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint16_t hs_start, hs_end, line_start, line_end; 504e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint16_t vwin_start, vwin_end, de_start, de_end; 505e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint16_t ref_pix, ref_line, pix_start2; 506e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t reg, div, rep; 507e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 508e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark hs_start = mode->hsync_start - mode->hdisplay; 509e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark hs_end = mode->hsync_end - mode->hdisplay; 510e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark line_start = 1; 511e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark line_end = 1 + mode->vsync_end - mode->vsync_start; 512e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark vwin_start = mode->vtotal - mode->vsync_start; 513e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark vwin_end = vwin_start + mode->vdisplay; 514e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark de_start = mode->htotal - mode->hdisplay; 515e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark de_end = mode->htotal; 516e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 517e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark pix_start2 = 0; 518e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode->flags & DRM_MODE_FLAG_INTERLACE) 519e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark pix_start2 = (mode->htotal / 2) + hs_start; 520e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 521e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* TODO how is this value calculated? It is 2 for all common 522e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * formats in the tables in out of tree nxp driver (assuming 523e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * I've properly deciphered their byzantine table system) 524e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 525e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ref_line = 2; 526e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 527e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* this might changes for other color formats from the CRTC: */ 528e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ref_pix = 3 + hs_start; 529e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 530e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark div = 148500 / mode->clock; 531e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 532e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG("clock=%d, div=%u", mode->clock, div); 533e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG("hs_start=%u, hs_end=%u, line_start=%u, line_end=%u", 534e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark hs_start, hs_end, line_start, line_end); 535e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG("vwin_start=%u, vwin_end=%u, de_start=%u, de_end=%u", 536e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark vwin_start, vwin_end, de_start, de_end); 537e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG("ref_line=%u, ref_pix=%u, pix_start2=%u", 538e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ref_line, ref_pix, pix_start2); 539e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 540e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* mute the audio FIFO: */ 541e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 542e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 543e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set HDMI HDCP mode off: */ 544e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); 545e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_TX33, TX33_HDMI); 546e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 547e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); 548e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* no pre-filter or interpolator: */ 549e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | 550e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark HVF_CNTRL_0_INTPOL(0)); 551e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); 552e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | 553e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark VIP_CNTRL_4_BLC(0)); 554e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); 555e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 556e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); 557e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); 558e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SERIALIZER, 0); 559e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); 560e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 561e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ 562e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark rep = 0; 563e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_RPT_CNTRL, 0); 564e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | 565e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 566e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 567e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | 568e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark PLL_SERIAL_2_SRL_PR(rep)); 569e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 570e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VS_PIX_STRT_2_MSB, pix_start2); 571e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VS_PIX_END_2_MSB, pix_start2); 572e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 573e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set color matrix bypass flag: */ 574e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); 575e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 576e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set BIAS tmds value: */ 577e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ANA_GENERAL, 0x09); 578e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 579e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); 580e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 581e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_3, 0); 582e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); 583e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode->flags & DRM_MODE_FLAG_NVSYNC) 584e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); 585e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 586e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode->flags & DRM_MODE_FLAG_NHSYNC) 587e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); 588e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 589e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIDFORMAT, 0x00); 590e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_NPIX_MSB, mode->hdisplay - 1); 591e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_NLINE_MSB, mode->vdisplay - 1); 592e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, line_start); 593e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VS_LINE_END_1_MSB, line_end); 594e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, hs_start); 595e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VS_PIX_END_1_MSB, hs_start); 596e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_HS_PIX_START_MSB, hs_start); 597e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_HS_PIX_STOP_MSB, hs_end); 598e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VWIN_START_1_MSB, vwin_start); 599e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_VWIN_END_1_MSB, vwin_end); 600e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_DE_START_MSB, de_start); 601e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_DE_STOP_MSB, de_end); 602e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 603e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->rev == TDA19988) { 604e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* let incoming pixels fill the active space (if any) */ 605e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENABLE_SPACE, 0x01); 606e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 607e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 608e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_REFPIX_MSB, ref_pix); 609e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write16(encoder, REG_REFLINE_MSB, ref_line); 610e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 611e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg = TBG_CNTRL_1_VHX_EXT_DE | 612e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark TBG_CNTRL_1_VHX_EXT_HS | 613e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark TBG_CNTRL_1_VHX_EXT_VS | 614e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark TBG_CNTRL_1_DWIN_DIS | /* HDCP off */ 615e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark TBG_CNTRL_1_VH_TGL_2; 616e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode->flags & (DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC)) 617e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg |= TBG_CNTRL_1_VH_TGL_0; 618e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_TBG_CNTRL_1, reg); 619e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 620e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* must be last register set: */ 621e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); 622e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 623e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 624e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic enum drm_connector_status 625e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_detect(struct drm_encoder *encoder, 626e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector) 627e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 628e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val = cec_read(encoder, REG_CEC_RXSHPDLEV); 629e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : 630e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark connector_status_disconnected; 631e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 632e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 633e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 634e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkread_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) 635e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 636e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t offset, segptr; 637e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret, i; 638e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 639e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* enable EDID read irq: */ 640e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 641e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 642e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark offset = (blk & 1) ? 128 : 0; 643e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark segptr = blk / 2; 644e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 645e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_ADDR, 0xa0); 646e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_OFFS, offset); 647e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_SEGM_ADDR, 0x60); 648e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_SEGM, segptr); 649e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 650e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* enable reading EDID: */ 651e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_EDID_CTRL, 0x1); 652e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 653e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* flag must be cleared by sw: */ 654e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_EDID_CTRL, 0x0); 655e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 656e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* wait for block read to complete: */ 657e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark for (i = 100; i > 0; i--) { 658e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val = reg_read(encoder, REG_INT_FLAGS_2); 659e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (val & INT_FLAGS_2_EDID_BLK_RD) 660e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 661e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(1); 662e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 663e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 664e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (i == 0) 665e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ETIMEDOUT; 666e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 667e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = reg_read_range(encoder, REG_EDID_DATA_0, buf, EDID_LENGTH); 668e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret != EDID_LENGTH) { 669e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(encoder->dev->dev, "failed to read edid block %d: %d", 670e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark blk, ret); 671e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 672e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 673e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 674e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 675e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 676e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 677e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 678e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 679e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic uint8_t * 680e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkdo_get_edid(struct drm_encoder *encoder) 681e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 682063b472fbb44ac562797a630ac3516720f588140Russell King struct tda998x_priv *priv = to_tda998x_priv(encoder); 683e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int j = 0, valid_extensions = 0; 684e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t *block, *new; 685e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark bool print_bad_edid = drm_debug & DRM_UT_KMS; 686e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 687e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) 688e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return NULL; 689e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 690063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 691063b472fbb44ac562797a630ac3516720f588140Russell King reg_clear(encoder, REG_TX4, TX4_PD_RAM); 692063b472fbb44ac562797a630ac3516720f588140Russell King 693e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* base block fetch */ 694e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (read_edid_block(encoder, block, 0)) 695e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 696e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 697e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!drm_edid_block_valid(block, 0, print_bad_edid)) 698e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 699e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 700e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if there's no extensions, we're done */ 701e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (block[0x7e] == 0) 702063b472fbb44ac562797a630ac3516720f588140Russell King goto done; 703e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 704e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); 705e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!new) 706e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 707e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block = new; 708e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 709e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark for (j = 1; j <= block[0x7e]; j++) { 710e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; 711e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (read_edid_block(encoder, ext_block, j)) 712e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 713e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 714e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) 715e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 716e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 717e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark valid_extensions++; 718e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 719e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 720e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (valid_extensions != block[0x7e]) { 721e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; 722e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block[0x7e] = valid_extensions; 723e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); 724e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!new) 725e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 726e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block = new; 727e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 728e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 729063b472fbb44ac562797a630ac3516720f588140Russell Kingdone: 730063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 731063b472fbb44ac562797a630ac3516720f588140Russell King reg_set(encoder, REG_TX4, TX4_PD_RAM); 732063b472fbb44ac562797a630ac3516720f588140Russell King 733e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return block; 734e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 735e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 736063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 737063b472fbb44ac562797a630ac3516720f588140Russell King reg_set(encoder, REG_TX4, TX4_PD_RAM); 738e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_warn(encoder->dev->dev, "failed to read EDID\n"); 739e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(block); 740e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return NULL; 741e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 742e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 743e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 744e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_get_modes(struct drm_encoder *encoder, 745e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector) 746e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 747e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct edid *edid = (struct edid *)do_get_edid(encoder); 748e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int n = 0; 749e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 750e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (edid) { 751e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_mode_connector_update_edid_property(connector, edid); 752e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark n = drm_add_edid_modes(connector, edid); 753e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(edid); 754e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 755e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 756e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return n; 757e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 758e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 759e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 760e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_create_resources(struct drm_encoder *encoder, 761e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector) 762e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 763e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 764e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 765e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 766e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 767e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 768e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_set_property(struct drm_encoder *encoder, 769e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector, 770e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_property *property, 771e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint64_t val) 772e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 773e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 774e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 775e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 776e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 777e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 778e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_destroy(struct drm_encoder *encoder) 779e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 780e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 781e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_i2c_encoder_destroy(encoder); 782e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(priv); 783e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 784e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 785e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct drm_encoder_slave_funcs tda998x_encoder_funcs = { 786e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .set_config = tda998x_encoder_set_config, 787e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .destroy = tda998x_encoder_destroy, 788e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .dpms = tda998x_encoder_dpms, 789e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .save = tda998x_encoder_save, 790e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .restore = tda998x_encoder_restore, 791e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .mode_fixup = tda998x_encoder_mode_fixup, 792e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .mode_valid = tda998x_encoder_mode_valid, 793e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .mode_set = tda998x_encoder_mode_set, 794e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .detect = tda998x_encoder_detect, 795e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .get_modes = tda998x_encoder_get_modes, 796e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .create_resources = tda998x_encoder_create_resources, 797e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .set_property = tda998x_encoder_set_property, 798e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 799e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 800e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* I2C driver functions */ 801e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 802e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 803e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) 804e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 805e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 806e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 807e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 808e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 809e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_remove(struct i2c_client *client) 810e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 811e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 812e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 813e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 814e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 815e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_init(struct i2c_client *client, 816e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_device *dev, 817e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_encoder_slave *encoder_slave) 818e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 819e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_encoder *encoder = &encoder_slave->base; 820e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv; 821e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 822e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv = kzalloc(sizeof(*priv), GFP_KERNEL); 823e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!priv) 824e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ENOMEM; 825e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 826e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->current_page = 0; 827e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->cec = i2c_new_dummy(client->adapter, 0x34); 828e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->dpms = DRM_MODE_DPMS_OFF; 829e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 830e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_priv = priv; 831e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_funcs = &tda998x_encoder_funcs; 832e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 833e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* wake up the device: */ 834e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark cec_write(encoder, REG_CEC_ENAMODS, 835e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); 836e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 837e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark tda998x_reset(encoder); 838e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 839e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* read version: */ 840e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->rev = reg_read(encoder, REG_VERSION_LSB) | 841e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_read(encoder, REG_VERSION_MSB) << 8; 842e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 843e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* mask off feature bits: */ 844e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->rev &= ~0x30; /* not-hdcp and not-scalar bit */ 845e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 846e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark switch (priv->rev) { 847e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA9989N2: dev_info(dev->dev, "found TDA9989 n2"); break; 848e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA19989: dev_info(dev->dev, "found TDA19989"); break; 849e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA19989N2: dev_info(dev->dev, "found TDA19989 n2"); break; 850e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA19988: dev_info(dev->dev, "found TDA19988"); break; 851e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark default: 852e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG("found unsupported device: %04x", priv->rev); 853e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 854e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 855e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 856e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* after reset, enable DDC: */ 857e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_DISABLE, 0x00); 858e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 859e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set clock on DDC channel: */ 860e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_TX3, 39); 861e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 862e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if necessary, disable multi-master: */ 863e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->rev == TDA19989) 864e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_I2C_MASTER, I2C_MASTER_DIS_MM); 865e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 866e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, 867e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); 868e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 869e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 870e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 871e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 872e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if encoder_init fails, the encoder slave is never registered, 873e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * so cleanup here: 874e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 875e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->cec) 876e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark i2c_unregister_device(priv->cec); 877e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(priv); 878e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_priv = NULL; 879e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_funcs = NULL; 880e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ENXIO; 881e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 882e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 883e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct i2c_device_id tda998x_ids[] = { 884e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark { "tda998x", 0 }, 885e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark { } 886e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 887e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_DEVICE_TABLE(i2c, tda998x_ids); 888e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 889e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct drm_i2c_encoder_driver tda998x_driver = { 890e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .i2c_driver = { 891e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .probe = tda998x_probe, 892e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .remove = tda998x_remove, 893e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .driver = { 894e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .name = "tda998x", 895e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }, 896e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .id_table = tda998x_ids, 897e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }, 898e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .encoder_init = tda998x_encoder_init, 899e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 900e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 901e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Module initialization */ 902e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 903e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int __init 904e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_init(void) 905e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 906e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 907e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return drm_i2c_encoder_register(THIS_MODULE, &tda998x_driver); 908e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 909e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 910e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void __exit 911e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_exit(void) 912e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 913e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 914e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_i2c_encoder_unregister(&tda998x_driver); 915e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 916e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 917e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 918e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_DESCRIPTION("NXP Semiconductors TDA998X HDMI Encoder"); 919e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_LICENSE("GPL"); 920e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 921e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkmodule_init(tda998x_init); 922e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkmodule_exit(tda998x_exit); 923