页次: 1
查阅大量资料花了好几天有点头绪了,分享一下/*MCU手册写TCON Register List
Module Name Base Address
TCON 0x01C0C000
代码中定义#define SUNXI_LCD0_BASE 0x01c0C000
则lcdc指针就是指向TCON寄存器*/,然后我查看手册5.1.4. TCON Register List
Module Name Base Address
TCON 0x01C0C000
Register Name Offset Description
TCON_CTRL_REG 0x000 TCON Control Register
TCON_INT_REG0 0x004 TCON Interrupt Register 0
TCON_INT_REG1 0x008 TCON Interrupt Register 1
TCON_FRM_CTRL_REG 0x010 TCON FRM Control Register
TCON_FRM_SEED0_R_REG 0x014 TCON FRM Seed0 Red Register
TCON_FRM_SEED0_G_REG 0x018 TCON FRM Seed0 Green Register
TCON_FRM_SEED0_B_REG 0x01C TCON FRM Seed0 Blue Register
TCON_FRM_SEED1_R_REG 0x020 TCON FRM Seed1 Red Register
TCON_FRM_SEED1_G_REG 0x024 TCON FRM Seed1 Green Register
TCON_FRM_SEED1_B_REG 0x028 TCON FRM Seed1 Blue Register
TCON_FRM_TBL_REG0 0x02C TCON FRM Table Register 0
TCON_FRM_TBL_REG1 0x030 TCON FRM Table Register 1
TCON_FRM_TBL_REG2 0x034 TCON FRM Table Register 2
TCON_FRM_TBL_REG3 0x038 TCON FRM Table Register 3
TCON0_CTRL_REG 0x040 TCON0 Control Register
TCON_CLK_CTRL_REG 0x044 TCON Clock Control Register
TCON0_BASIC_TIMING_REG0 0x048 TCON0 Basic Timing Register 0
TCON0_BASIC_TIMING _REG1 0x04C TCON0 Basic Timing Register 1
TCON0_BASIC_TIMING _REG2 0x050 TCON0 Basic Timing Register 2
TCON0_BASIC_TIMING _REG3 0x054 TCON0 Basic Timing Register 3
TCON0_HV_TIMING_REG 0x058 TCON0 HV Timing Register
TCON0_ CPU_IF_REG 0X060 TCON0 CPU Interface Control Register
TCON0_CPU_WR_REG 0x064 TCON0 CPU Mode Write Register
TCON0_CPU_RD_REG 0x068 TCON0 CPU Mode Read Register
TCON0_CPU_RD_NX_REG 0x06C TCON0 CPU Mode Read NX Register
TCON0_IO_CTRL_REG0 0x088 TCON0 IO Control Register 0
TCON0_IO_CTRL_REG1 0x08C TCON0 IO Control Register 1
TCON1_CTRL_REG 0x090 TCON1 Control Register
TCON1_BASIC_REG0 0x094 TCON1 Basic Timing Register 0
TCON1_BASIC_REG1 0x098 TCON1 Basic Timing Register 1
TCON1_BASIC_REG2 0x09C TCON1 Basic Timing Register 2
TCON1_BASIC_REG3 0x0A0 TCON1 Basic Timing Register 3
TCON1_BASIC_REG4 0x0A4 TCON1 Basic Timing Register 4
TCON1_BASIC_REG5 0x0A8 TCON1 Basic Timing Register 5
TCON1_IO_CTRL_REG0 0x0F0 TCON1 IO Control Register 0
TCON1_IO_CTRL_REG1 0x0F4 TCON1 IO Control Register 1
TCON_DEBUG_INFO_REG 0x0FC TCON Debug Information Register
For Allwinner Tech Ent,我又去源码查看/*MCU手册写TCON Register List
Module Name Base Address
TCON 0x01C0C000
代码中定义#define SUNXI_LCD0_BASE 0x01c0C000
则lcdc指针就是指向TCON寄存器*/
static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
bool for_ext_vga_dac)
{
struct sunxi_lcdc_reg * const lcdc =
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
struct sunxi_ccm_reg * const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int clk_div, clk_double, pin;
struct display_timing timing;
#if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS
for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) {
#else
for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) {
#endif
#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
#endif
#ifdef CONFIG_VIDEO_LCD_IF_LVDS
sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
#endif
#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
sunxi_gpio_set_drv(pin, 3);
#endif
}
lcdc_pll_set(ccm, 0, mode->pixclock_khz, &clk_div, &clk_double,
sunxi_is_composite());
sunxi_ctfb_mode_to_display_timing(mode, &timing);
lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
}调用了lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);第一个参数就是TCONO的寄存器基地址0x01C0C000 ,那再看源码中struct sunxi_lcdc_reg {
u32 ctrl; /* 0x00 */
u32 int0; /* 0x04 */
u32 int1; /* 0x08 */
u8 res0[0x04]; /* 0x0c */
u32 tcon0_frm_ctrl; /* 0x10 */
u32 tcon0_frm_seed[6]; /* 0x14 */
u32 tcon0_frm_table[4]; /* 0x2c */
u8 res1[4]; /* 0x3c */
u32 tcon0_ctrl; /* 0x40 */
u32 tcon0_dclk; /* 0x44 */
u32 tcon0_timing_active; /* 0x48 */
u32 tcon0_timing_h; /* 0x4c */
u32 tcon0_timing_v; /* 0x50 */
u32 tcon0_timing_sync; /* 0x54 */
u32 tcon0_hv_intf; /* 0x58 */
u8 res2[0x04]; /* 0x5c */
u32 tcon0_cpu_intf; /* 0x60 */
u32 tcon0_cpu_wr_dat; /* 0x64 */
u32 tcon0_cpu_rd_dat0; /* 0x68 */
u32 tcon0_cpu_rd_dat1; /* 0x6c */
u32 tcon0_ttl_timing0; /* 0x70 */
u32 tcon0_ttl_timing1; /* 0x74 */
u32 tcon0_ttl_timing2; /* 0x78 */
u32 tcon0_ttl_timing3; /* 0x7c */
u32 tcon0_ttl_timing4; /* 0x80 */
u32 tcon0_lvds_intf; /* 0x84 */
u32 tcon0_io_polarity; /* 0x88 */
u32 tcon0_io_tristate; /* 0x8c */
u32 tcon1_ctrl; /* 0x90 */
u32 tcon1_timing_source; /* 0x94 */
u32 tcon1_timing_scale; /* 0x98 */
u32 tcon1_timing_out; /* 0x9c */
u32 tcon1_timing_h; /* 0xa0 */
u32 tcon1_timing_v; /* 0xa4 */
u32 tcon1_timing_sync; /* 0xa8 */
u8 res3[0x44]; /* 0xac */
u32 tcon1_io_polarity; /* 0xf0 */
u32 tcon1_io_tristate; /* 0xf4 */
u8 res4[0x108]; /* 0xf8 */
u32 mux_ctrl; /* 0x200 */
u8 res5[0x1c]; /* 0x204 */
u32 lvds_ana0; /* 0x220 */
u32 lvds_ana1; /* 0x224 */
};可以确认, u32 tcon0_ctrl; /* 0x40 */就是我们一直找的5.1.5.15. TCON0 Control Register
Offset: 0x040 Register Name: TCON0_CTRL_REG寄存器,再看源码void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc,
const struct display_timing *mode,
int clk_div, bool for_ext_vga_dac,
int depth, int dclk_phase)
{
int bp, clk_delay, total, val;
#ifndef CONFIG_SUNXI_DE2
/* Use tcon0 */
clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
SUNXI_LCDC_CTRL_IO_MAP_TCON0);
#endif
clk_delay = lcdc_get_clk_delay(mode, 0);
writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
writel(SUNXI_LCDC_TCON0_DCLK_ENABLE |
SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk);
writel(SUNXI_LCDC_X(mode->hactive.typ) |
SUNXI_LCDC_Y(mode->vactive.typ), &lcdc->tcon0_timing_active);
bp = mode->hsync_len.typ + mode->hback_porch.typ;
total = mode->hactive.typ + mode->hfront_porch.typ + bp;
writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) |
SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h);
bp = mode->vsync_len.typ + mode->vback_porch.typ;
total = mode->vactive.typ + mode->vfront_porch.typ + bp;
writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
#if defined(CONFIG_VIDEO_LCD_IF_PARALLEL) || defined(CONFIG_VIDEO_DE2)
writel(SUNXI_LCDC_X(mode->hsync_len.typ) |
SUNXI_LCDC_Y(mode->vsync_len.typ), &lcdc->tcon0_timing_sync);
writel(0, &lcdc->tcon0_hv_intf);
writel(0, &lcdc->tcon0_cpu_intf);
#endif
#ifdef CONFIG_VIDEO_LCD_IF_LVDS
val = (depth == 18) ? 1 : 0;
writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) |
SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf);
#endif
if (depth == 18 || depth == 16) {
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[1]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[2]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[3]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[4]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[5]);
writel(SUNXI_LCDC_TCON0_FRM_TAB0, &lcdc->tcon0_frm_table[0]);
writel(SUNXI_LCDC_TCON0_FRM_TAB1, &lcdc->tcon0_frm_table[1]);
writel(SUNXI_LCDC_TCON0_FRM_TAB2, &lcdc->tcon0_frm_table[2]);
writel(SUNXI_LCDC_TCON0_FRM_TAB3, &lcdc->tcon0_frm_table[3]);
writel(((depth == 18) ?
SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 :
SUNXI_LCDC_TCON0_FRM_CTRL_RGB565),
&lcdc->tcon0_frm_ctrl);
}
val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(dclk_phase);
if (mode->flags & DISPLAY_FLAGS_HSYNC_LOW)
val |= SUNXI_LCDC_TCON_HSYNC_MASK;
if (mode->flags & DISPLAY_FLAGS_VSYNC_LOW)
val |= SUNXI_LCDC_TCON_VSYNC_MASK;
#ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
if (for_ext_vga_dac)
val = 0;
#endif
writel(val, &lcdc->tcon0_io_polarity);
//把 TCON0 的所有 IO 从高阻态变为正常输出,这是“启用引脚”的最后一步。
writel(0, &lcdc->tcon0_io_tristate);
},只有此处writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);设置TCON0开启和延时,那么lcdc->tcon0_ctrl的26:24 R/W 0 I/F: panel interface type select
00: HV(Sync+DE)
01: 8080 I/F
1x: reserved默认应该还是0,也就是 HV(Sync+DE),是通用40pin RGB LCD,可以改成I8080模式了
页次: 1