Merge branch 'master' of http://git.denx.de/u-boot-sunxi
commit
3b95288a2a
@ -0,0 +1,68 @@ |
||||
/*
|
||||
* sun9i specific clock code |
||||
* |
||||
* (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/clock.h> |
||||
#include <asm/arch/prcm.h> |
||||
#include <asm/arch/sys_proto.h> |
||||
|
||||
void clock_init_uart(void) |
||||
{ |
||||
struct sunxi_ccm_reg *const ccm = |
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE; |
||||
|
||||
/* open the clock for uart */ |
||||
setbits_le32(&ccm->apb1_gate, |
||||
CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT + |
||||
CONFIG_CONS_INDEX - 1)); |
||||
/* deassert uart reset */ |
||||
setbits_le32(&ccm->apb1_reset_cfg, |
||||
1 << (APB1_RESET_UART_SHIFT + |
||||
CONFIG_CONS_INDEX - 1)); |
||||
|
||||
/* Dup with clock_init_safe(), drop once sun9i SPL support lands */ |
||||
writel(PLL4_CFG_DEFAULT, &ccm->pll4_periph0_cfg); |
||||
} |
||||
|
||||
int clock_twi_onoff(int port, int state) |
||||
{ |
||||
struct sunxi_ccm_reg *const ccm = |
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE; |
||||
|
||||
if (port > 4) |
||||
return -1; |
||||
|
||||
/* set the apb reset and clock gate for twi */ |
||||
if (state) { |
||||
setbits_le32(&ccm->apb1_gate, |
||||
CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port)); |
||||
setbits_le32(&ccm->apb1_reset_cfg, |
||||
1 << (APB1_RESET_UART_SHIFT + port)); |
||||
} else { |
||||
clrbits_le32(&ccm->apb1_reset_cfg, |
||||
1 << (APB1_RESET_UART_SHIFT + port)); |
||||
clrbits_le32(&ccm->apb1_gate, |
||||
CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port)); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
unsigned int clock_get_pll4_periph0(void) |
||||
{ |
||||
struct sunxi_ccm_reg *const ccm = |
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE; |
||||
uint32_t rval = readl(&ccm->pll4_periph0_cfg); |
||||
int n = ((rval & CCM_PLL4_CTRL_N_MASK) >> CCM_PLL4_CTRL_N_SHIFT); |
||||
int p = ((rval & CCM_PLL4_CTRL_P_MASK) >> CCM_PLL4_CTRL_P_SHIFT); |
||||
int m = ((rval & CCM_PLL4_CTRL_M_MASK) >> CCM_PLL4_CTRL_M_SHIFT) + 1; |
||||
const int k = 1; |
||||
|
||||
return ((24000000 * n * k) >> p) / m; |
||||
} |
@ -0,0 +1,139 @@ |
||||
/*
|
||||
* sun9i clock register definitions |
||||
* |
||||
* (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _SUNXI_CLOCK_SUN9I_H |
||||
#define _SUNXI_CLOCK_SUN9I_H |
||||
|
||||
struct sunxi_ccm_reg { |
||||
u32 pll1_c0_cfg; /* 0x00 c0cpu# pll configuration */ |
||||
u32 pll2_c1_cfg; /* 0x04 c1cpu# pll configuration */ |
||||
u32 pll3_audio_cfg; /* 0x08 audio pll configuration */ |
||||
u32 pll4_periph0_cfg; /* 0x0c peripheral0 pll configuration */ |
||||
u32 pll5_ve_cfg; /* 0x10 videoengine pll configuration */ |
||||
u32 pll6_ddr_cfg; /* 0x14 ddr pll configuration */ |
||||
u32 pll7_video0_cfg; /* 0x18 video0 pll configuration */ |
||||
u32 pll8_video1_cfg; /* 0x1c video1 pll configuration */ |
||||
u32 pll9_gpu_cfg; /* 0x20 gpu pll configuration */ |
||||
u32 pll10_de_cfg; /* 0x24 displayengine pll configuration */ |
||||
u32 pll11_isp_cfg; /* 0x28 isp pll6 ontrol */ |
||||
u32 pll12_periph1_cfg; /* 0x2c peripheral1 pll configuration */ |
||||
u8 reserved1[0x20]; /* 0x30 */ |
||||
u32 cpu_clk_source; /* 0x50 cpu clk source configuration */ |
||||
u32 c0_cfg; /* 0x54 cpu cluster 0 clock configuration */ |
||||
u32 c1_cfg; /* 0x58 cpu cluster 1 clock configuration */ |
||||
u32 gtbus_cfg; /* 0x5c gtbus clock configuration */ |
||||
u32 ahb0_cfg; /* 0x60 ahb0 clock configuration */ |
||||
u32 ahb1_cfg; /* 0x64 ahb1 clock configuration */ |
||||
u32 ahb2_cfg; /* 0x68 ahb2 clock configuration */ |
||||
u8 reserved2[0x04]; /* 0x6c */ |
||||
u32 apb0_cfg; /* 0x70 apb0 clock configuration */ |
||||
u32 apb1_cfg; /* 0x74 apb1 clock configuration */ |
||||
u32 cci400_cfg; /* 0x78 cci400 clock configuration */ |
||||
u8 reserved3[0x04]; /* 0x7c */ |
||||
u32 ats_cfg; /* 0x80 ats clock configuration */ |
||||
u32 trace_cfg; /* 0x84 trace clock configuration */ |
||||
u8 reserved4[0xf8]; /* 0x88 */ |
||||
u32 clk_output_a; /* 0x180 clk_output_a */ |
||||
u32 clk_output_b; /* 0x184 clk_output_a */ |
||||
u8 reserved5[0x278]; /* 0x188 */ |
||||
|
||||
u32 nand0_clk_cfg0; /* 0x400 nand0 clock configuration0 */ |
||||
u32 nand0_clk_cfg1; /* 0x404 nand1 clock configuration */ |
||||
u8 reserved6[0x08]; /* 0x408 */ |
||||
u32 sd0_clk_cfg; /* 0x410 sd0 clock configuration */ |
||||
u32 sd1_clk_cfg; /* 0x414 sd1 clock configuration */ |
||||
u32 sd2_clk_cfg; /* 0x418 sd2 clock configuration */ |
||||
u32 sd3_clk_cfg; /* 0x41c sd3 clock configuration */ |
||||
u8 reserved7[0x08]; /* 0x420 */ |
||||
u32 ts_clk_cfg; /* 0x428 transport stream clock cfg */ |
||||
u32 ss_clk_cfg; /* 0x42c security system clock cfg */ |
||||
u32 spi0_clk_cfg; /* 0x430 spi0 clock configuration */ |
||||
u32 spi1_clk_cfg; /* 0x434 spi1 clock configuration */ |
||||
u32 spi2_clk_cfg; /* 0x438 spi2 clock configuration */ |
||||
u32 spi3_clk_cfg; /* 0x43c spi3 clock configuration */ |
||||
u8 reserved8[0x50]; /* 0x440 */ |
||||
u32 de_clk_cfg; /* 0x490 display engine clock configuration */ |
||||
u8 reserved9[0x04]; /* 0x494 */ |
||||
u32 mp_clk_cfg; /* 0x498 mp clock configuration */ |
||||
u32 lcd0_clk_cfg; /* 0x49c LCD0 module clock */ |
||||
u32 lcd1_clk_cfg; /* 0x4a0 LCD1 module clock */ |
||||
u8 reserved10[0x1c]; /* 0x4a4 */ |
||||
u32 csi_isp_clk_cfg; /* 0x4c0 CSI ISP module clock */ |
||||
u32 csi0_clk_cfg; /* 0x4c4 CSI0 module clock */ |
||||
u32 csi1_clk_cfg; /* 0x4c8 CSI1 module clock */ |
||||
u32 fd_clk_cfg; /* 0x4cc FD module clock */ |
||||
u32 ve_clk_cfg; /* 0x4d0 VE module clock */ |
||||
u32 avs_clk_cfg; /* 0x4d4 AVS module clock */ |
||||
u8 reserved11[0x18]; /* 0x4d8 */ |
||||
u32 gpu_core_clk_cfg; /* 0x4f0 GPU core clock config */ |
||||
u32 gpu_mem_clk_cfg; /* 0x4f4 GPU memory clock config */ |
||||
u32 gpu_axi_clk_cfg; /* 0x4f8 GPU AXI clock config */ |
||||
u8 reserved12[0x10]; /* 0x4fc */ |
||||
u32 gp_adc_clk_cfg; /* 0x50c General Purpose ADC clk config */ |
||||
u8 reserved13[0x70]; /* 0x510 */ |
||||
|
||||
u32 ahb_gate0; /* 0x580 AHB0 Gating Register */ |
||||
u32 ahb_gate1; /* 0x584 AHB1 Gating Register */ |
||||
u32 ahb_gate2; /* 0x588 AHB2 Gating Register */ |
||||
u8 reserved14[0x04]; /* 0x58c */ |
||||
u32 apb0_gate; /* 0x590 APB0 Clock Gating Register */ |
||||
u32 apb1_gate; /* 0x594 APB1 Clock Gating Register */ |
||||
u8 reserved15[0x08]; /* 0x598 */ |
||||
u32 ahb_reset0_cfg; /* 0x5a0 AHB0 Software Reset Register */ |
||||
u32 ahb_reset1_cfg; /* 0x5a4 AHB1 Software Reset Register */ |
||||
u32 ahb_reset2_cfg; /* 0x5a8 AHB2 Software Reset Register */ |
||||
u8 reserved16[0x04]; /* 0x5ac */ |
||||
u32 apb0_reset_cfg; /* 0x5b0 Bus Software Reset Register 3 */ |
||||
u32 apb1_reset_cfg; /* 0x5b4 Bus Software Reset Register 4 */ |
||||
}; |
||||
|
||||
/* pll4_periph0_cfg */ |
||||
#define PLL4_CFG_DEFAULT 0x90002800 /* 960 MHz */ |
||||
|
||||
#define CCM_PLL4_CTRL_N_SHIFT 8 |
||||
#define CCM_PLL4_CTRL_N_MASK (0xff << CCM_PLL4_CTRL_N_SHIFT) |
||||
#define CCM_PLL4_CTRL_P_SHIFT 16 |
||||
#define CCM_PLL4_CTRL_P_MASK (0x1 << CCM_PLL4_CTRL_P_SHIFT) |
||||
#define CCM_PLL4_CTRL_M_SHIFT 18 |
||||
#define CCM_PLL4_CTRL_M_MASK (0x1 << CCM_PLL4_CTRL_M_SHIFT) |
||||
|
||||
/* sd#_clk_cfg fields */ |
||||
#define CCM_MMC_CTRL_M(x) ((x) - 1) |
||||
#define CCM_MMC_CTRL_OCLK_DLY(x) ((x) << 8) |
||||
#define CCM_MMC_CTRL_N(x) ((x) << 16) |
||||
#define CCM_MMC_CTRL_SCLK_DLY(x) ((x) << 20) |
||||
#define CCM_MMC_CTRL_OSCM24 (0 << 24) |
||||
#define CCM_MMC_CTRL_PLL_PERIPH0 (1 << 24) |
||||
#define CCM_MMC_CTRL_ENABLE (1 << 31) |
||||
|
||||
/* ahb_gate0 fields */ |
||||
/* On sun9i all sdc-s share their ahb gate, so ignore (x) */ |
||||
#define AHB_GATE_OFFSET_MMC(x) 8 |
||||
|
||||
/* apb1_gate fields */ |
||||
#define APB1_GATE_UART_SHIFT 16 |
||||
#define APB1_GATE_UART_MASK (0xff << APB1_GATE_UART_SHIFT) |
||||
#define APB1_GATE_TWI_SHIFT 0 |
||||
#define APB1_GATE_TWI_MASK (0xf << APB1_GATE_TWI_SHIFT) |
||||
|
||||
/* ahb_reset0_cfg fields */ |
||||
/* On sun9i all sdc-s share their ahb reset, so ignore (x) */ |
||||
#define AHB_RESET_OFFSET_MMC(x) 8 |
||||
|
||||
/* apb1_reset_cfg fields */ |
||||
#define APB1_RESET_UART_SHIFT 16 |
||||
#define APB1_RESET_UART_MASK (0xff << APB1_RESET_UART_SHIFT) |
||||
#define APB1_RESET_TWI_SHIFT 0 |
||||
#define APB1_RESET_TWI_MASK (0xf << APB1_RESET_TWI_SHIFT) |
||||
|
||||
|
||||
#ifndef __ASSEMBLY__ |
||||
unsigned int clock_get_pll4_periph0(void); |
||||
#endif |
||||
|
||||
#endif /* _SUNXI_CLOCK_SUN9I_H */ |
@ -0,0 +1,154 @@ |
||||
/*
|
||||
* (C) Copyright 2007-2011 |
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com> |
||||
* Tom Cubie <tangliang@allwinnertech.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _SUNXI_CPU_SUN4I_H |
||||
#define _SUNXI_CPU_SUN4I_H |
||||
|
||||
#define SUNXI_SRAM_A1_BASE 0x00000000 |
||||
#define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */ |
||||
|
||||
#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */ |
||||
#define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */ |
||||
#define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */ |
||||
#define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */ |
||||
#define SUNXI_SRAM_B_BASE 0x00020000 /* 64 kiB (secure) */ |
||||
|
||||
#define SUNXI_SRAMC_BASE 0x01c00000 |
||||
#define SUNXI_DRAMC_BASE 0x01c01000 |
||||
#define SUNXI_DMA_BASE 0x01c02000 |
||||
#define SUNXI_NFC_BASE 0x01c03000 |
||||
#define SUNXI_TS_BASE 0x01c04000 |
||||
#define SUNXI_SPI0_BASE 0x01c05000 |
||||
#define SUNXI_SPI1_BASE 0x01c06000 |
||||
#define SUNXI_MS_BASE 0x01c07000 |
||||
#define SUNXI_TVD_BASE 0x01c08000 |
||||
#define SUNXI_CSI0_BASE 0x01c09000 |
||||
#define SUNXI_TVE0_BASE 0x01c0a000 |
||||
#define SUNXI_EMAC_BASE 0x01c0b000 |
||||
#define SUNXI_LCD0_BASE 0x01c0C000 |
||||
#define SUNXI_LCD1_BASE 0x01c0d000 |
||||
#define SUNXI_VE_BASE 0x01c0e000 |
||||
#define SUNXI_MMC0_BASE 0x01c0f000 |
||||
#define SUNXI_MMC1_BASE 0x01c10000 |
||||
#define SUNXI_MMC2_BASE 0x01c11000 |
||||
#define SUNXI_MMC3_BASE 0x01c12000 |
||||
#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I |
||||
#define SUNXI_USB0_BASE 0x01c13000 |
||||
#define SUNXI_USB1_BASE 0x01c14000 |
||||
#endif |
||||
#define SUNXI_SS_BASE 0x01c15000 |
||||
#define SUNXI_HDMI_BASE 0x01c16000 |
||||
#define SUNXI_SPI2_BASE 0x01c17000 |
||||
#define SUNXI_SATA_BASE 0x01c18000 |
||||
#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I |
||||
#define SUNXI_PATA_BASE 0x01c19000 |
||||
#define SUNXI_ACE_BASE 0x01c1a000 |
||||
#define SUNXI_TVE1_BASE 0x01c1b000 |
||||
#define SUNXI_USB2_BASE 0x01c1c000 |
||||
#else |
||||
#define SUNXI_USB0_BASE 0x01c19000 |
||||
#define SUNXI_USB1_BASE 0x01c1a000 |
||||
#define SUNXI_USB2_BASE 0x01c1b000 |
||||
#endif |
||||
#define SUNXI_CSI1_BASE 0x01c1d000 |
||||
#define SUNXI_TZASC_BASE 0x01c1e000 |
||||
#define SUNXI_SPI3_BASE 0x01c1f000 |
||||
|
||||
#define SUNXI_CCM_BASE 0x01c20000 |
||||
#define SUNXI_INTC_BASE 0x01c20400 |
||||
#define SUNXI_PIO_BASE 0x01c20800 |
||||
#define SUNXI_TIMER_BASE 0x01c20c00 |
||||
#define SUNXI_SPDIF_BASE 0x01c21000 |
||||
#define SUNXI_AC97_BASE 0x01c21400 |
||||
#define SUNXI_IR0_BASE 0x01c21800 |
||||
#define SUNXI_IR1_BASE 0x01c21c00 |
||||
|
||||
#define SUNXI_IIS_BASE 0x01c22400 |
||||
#define SUNXI_LRADC_BASE 0x01c22800 |
||||
#define SUNXI_AD_DA_BASE 0x01c22c00 |
||||
#define SUNXI_KEYPAD_BASE 0x01c23000 |
||||
#define SUNXI_TZPC_BASE 0x01c23400 |
||||
#define SUNXI_SID_BASE 0x01c23800 |
||||
#define SUNXI_SJTAG_BASE 0x01c23c00 |
||||
|
||||
#define SUNXI_TP_BASE 0x01c25000 |
||||
#define SUNXI_PMU_BASE 0x01c25400 |
||||
#define SUN7I_CPUCFG_BASE 0x01c25c00 |
||||
|
||||
#define SUNXI_UART0_BASE 0x01c28000 |
||||
#define SUNXI_UART1_BASE 0x01c28400 |
||||
#define SUNXI_UART2_BASE 0x01c28800 |
||||
#define SUNXI_UART3_BASE 0x01c28c00 |
||||
#define SUNXI_UART4_BASE 0x01c29000 |
||||
#define SUNXI_UART5_BASE 0x01c29400 |
||||
#define SUNXI_UART6_BASE 0x01c29800 |
||||
#define SUNXI_UART7_BASE 0x01c29c00 |
||||
#define SUNXI_PS2_0_BASE 0x01c2a000 |
||||
#define SUNXI_PS2_1_BASE 0x01c2a400 |
||||
|
||||
#define SUNXI_TWI0_BASE 0x01c2ac00 |
||||
#define SUNXI_TWI1_BASE 0x01c2b000 |
||||
#define SUNXI_TWI2_BASE 0x01c2b400 |
||||
|
||||
#define SUNXI_CAN_BASE 0x01c2bc00 |
||||
|
||||
#define SUNXI_SCR_BASE 0x01c2c400 |
||||
|
||||
#ifndef CONFIG_MACH_SUN6I |
||||
#define SUNXI_GPS_BASE 0x01c30000 |
||||
#define SUNXI_MALI400_BASE 0x01c40000 |
||||
#define SUNXI_GMAC_BASE 0x01c50000 |
||||
#else |
||||
#define SUNXI_GMAC_BASE 0x01c30000 |
||||
#endif |
||||
|
||||
#define SUNXI_DRAM_COM_BASE 0x01c62000 |
||||
#define SUNXI_DRAM_CTL0_BASE 0x01c63000 |
||||
#define SUNXI_DRAM_CTL1_BASE 0x01c64000 |
||||
#define SUNXI_DRAM_PHY0_BASE 0x01c65000 |
||||
#define SUNXI_DRAM_PHY1_BASE 0x01c66000 |
||||
|
||||
/* module sram */ |
||||
#define SUNXI_SRAM_C_BASE 0x01d00000 |
||||
|
||||
#define SUNXI_DE_FE0_BASE 0x01e00000 |
||||
#define SUNXI_DE_FE1_BASE 0x01e20000 |
||||
#define SUNXI_DE_BE0_BASE 0x01e60000 |
||||
#define SUNXI_DE_BE1_BASE 0x01e40000 |
||||
#define SUNXI_MP_BASE 0x01e80000 |
||||
#define SUNXI_AVG_BASE 0x01ea0000 |
||||
|
||||
#define SUNXI_RTC_BASE 0x01f00000 |
||||
#define SUNXI_PRCM_BASE 0x01f01400 |
||||
#define SUN6I_CPUCFG_BASE 0x01f01c00 |
||||
#define SUNXI_R_UART_BASE 0x01f02800 |
||||
#define SUNXI_R_PIO_BASE 0x01f02c00 |
||||
#define SUN6I_P2WI_BASE 0x01f03400 |
||||
#define SUNXI_RSB_BASE 0x01f03400 |
||||
|
||||
/* CoreSight Debug Module */ |
||||
#define SUNXI_CSDM_BASE 0x3f500000 |
||||
|
||||
#define SUNXI_DDRII_DDRIII_BASE 0x40000000 /* 2 GiB */ |
||||
|
||||
#define SUNXI_BROM_BASE 0xffff0000 /* 32 kiB */ |
||||
|
||||
#define SUNXI_CPU_CFG (SUNXI_TIMER_BASE + 0x13c) |
||||
|
||||
/* SS bonding ids used for cpu identification */ |
||||
#define SUNXI_SS_BOND_ID_A31 4 |
||||
#define SUNXI_SS_BOND_ID_A31S 5 |
||||
|
||||
#ifndef __ASSEMBLY__ |
||||
void sunxi_board_init(void); |
||||
void sunxi_reset(void); |
||||
int sunxi_get_ss_bonding_id(void); |
||||
int sunxi_get_sid(unsigned int *sid); |
||||
#endif /* __ASSEMBLY__ */ |
||||
|
||||
#endif /* _SUNXI_CPU_SUN4I_H */ |
@ -0,0 +1,108 @@ |
||||
/*
|
||||
* (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> |
||||
* (C) Copyright 2007-2013 |
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com> |
||||
* Jerry Wang <wangflord@allwinnertech.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _SUNXI_CPU_SUN9I_H |
||||
#define _SUNXI_CPU_SUN9I_H |
||||
|
||||
#define REGS_AHB0_BASE 0x01C00000 |
||||
#define REGS_AHB1_BASE 0x00800000 |
||||
#define REGS_AHB2_BASE 0x03000000 |
||||
#define REGS_APB0_BASE 0x06000000 |
||||
#define REGS_APB1_BASE 0x07000000 |
||||
#define REGS_RCPUS_BASE 0x08000000 |
||||
|
||||
#define SUNXI_SRAM_D_BASE 0x08100000 |
||||
|
||||
/* AHB0 Module */ |
||||
#define SUNXI_NFC_BASE (REGS_AHB0_BASE + 0x3000) |
||||
#define SUNXI_TSC_BASE (REGS_AHB0_BASE + 0x4000) |
||||
|
||||
#define SUNXI_MMC0_BASE (REGS_AHB0_BASE + 0x0f000) |
||||
#define SUNXI_MMC1_BASE (REGS_AHB0_BASE + 0x10000) |
||||
#define SUNXI_MMC2_BASE (REGS_AHB0_BASE + 0x11000) |
||||
#define SUNXI_MMC3_BASE (REGS_AHB0_BASE + 0x12000) |
||||
#define SUNXI_MMC_COMMON_BASE (REGS_AHB0_BASE + 0x13000) |
||||
|
||||
#define SUNXI_SPI0_BASE (REGS_AHB0_BASE + 0x1A000) |
||||
#define SUNXI_SPI1_BASE (REGS_AHB0_BASE + 0x1B000) |
||||
#define SUNXI_SPI2_BASE (REGS_AHB0_BASE + 0x1C000) |
||||
#define SUNXI_SPI3_BASE (REGS_AHB0_BASE + 0x1D000) |
||||
|
||||
#define SUNXI_GIC400_BASE (REGS_AHB0_BASE + 0x40000) |
||||
#define SUNXI_ARMA9_GIC_BASE (REGS_AHB0_BASE + 0x41000) |
||||
#define SUNXI_ARMA9_CPUIF_BASE (REGS_AHB0_BASE + 0x42000) |
||||
|
||||
/* AHB1 Module */ |
||||
#define SUNXI_DMA_BASE (REGS_AHB1_BASE + 0x002000) |
||||
#define SUNXI_USBOTG_BASE (REGS_AHB1_BASE + 0x100000) |
||||
#define SUNXI_USBEHCI0_BASE (REGS_AHB1_BASE + 0x200000) |
||||
#define SUNXI_USBEHCI1_BASE (REGS_AHB1_BASE + 0x201000) |
||||
#define SUNXI_USBEHCI2_BASE (REGS_AHB1_BASE + 0x202000) |
||||
|
||||
/* AHB2 Module */ |
||||
#define SUNXI_DE_SYS_BASE (REGS_AHB2_BASE + 0x000000) |
||||
#define SUNXI_DISP_SYS_BASE (REGS_AHB2_BASE + 0x010000) |
||||
#define SUNXI_DE_FE0_BASE (REGS_AHB2_BASE + 0x100000) |
||||
#define SUNXI_DE_FE1_BASE (REGS_AHB2_BASE + 0x140000) |
||||
#define SUNXI_DE_FE2_BASE (REGS_AHB2_BASE + 0x180000) |
||||
|
||||
#define SUNXI_DE_BE0_BASE (REGS_AHB2_BASE + 0x200000) |
||||
#define SUNXI_DE_BE1_BASE (REGS_AHB2_BASE + 0x240000) |
||||
#define SUNXI_DE_BE2_BASE (REGS_AHB2_BASE + 0x280000) |
||||
|
||||
#define SUNXI_DE_DEU0_BASE (REGS_AHB2_BASE + 0x300000) |
||||
#define SUNXI_DE_DEU1_BASE (REGS_AHB2_BASE + 0x340000) |
||||
#define SUNXI_DE_DRC0_BASE (REGS_AHB2_BASE + 0x400000) |
||||
#define SUNXI_DE_DRC1_BASE (REGS_AHB2_BASE + 0x440000) |
||||
|
||||
#define SUNXI_LCD0_BASE (REGS_AHB2_BASE + 0xC00000) |
||||
#define SUNXI_LCD1_BASE (REGS_AHB2_BASE + 0xC10000) |
||||
#define SUNXI_LCD2_BASE (REGS_AHB2_BASE + 0xC20000) |
||||
#define SUNXI_MIPI_DSI0_BASE (REGS_AHB2_BASE + 0xC40000) |
||||
/* Also seen as SUNXI_MIPI_DSI0_DPHY_BASE 0x01ca1000 */ |
||||
#define SUNXI_MIPI_DSI0_DPHY_BASE (REGS_AHB2_BASE + 0xC40100) |
||||
#define SUNXI_HDMI_BASE (REGS_AHB2_BASE + 0xD00000) |
||||
|
||||
/* APB0 Module */ |
||||
#define SUNXI_CCM_BASE (REGS_APB0_BASE + 0x0000) |
||||
#define SUNXI_CCMMODULE_BASE (REGS_APB0_BASE + 0x0400) |
||||
#define SUNXI_PIO_BASE (REGS_APB0_BASE + 0x0800) |
||||
#define SUNXI_R_PIO_BASE (0x08002C00) |
||||
#define SUNXI_TIMER_BASE (REGS_APB0_BASE + 0x0C00) |
||||
#define SUNXI_PWM_BASE (REGS_APB0_BASE + 0x1400) |
||||
#define SUNXI_LRADC_BASE (REGS_APB0_BASE + 0x1800) |
||||
|
||||
/* APB1 Module */ |
||||
#define SUNXI_UART0_BASE (REGS_APB1_BASE + 0x0000) |
||||
#define SUNXI_UART1_BASE (REGS_APB1_BASE + 0x0400) |
||||
#define SUNXI_UART2_BASE (REGS_APB1_BASE + 0x0800) |
||||
#define SUNXI_UART3_BASE (REGS_APB1_BASE + 0x0C00) |
||||
#define SUNXI_UART4_BASE (REGS_APB1_BASE + 0x1000) |
||||
#define SUNXI_UART5_BASE (REGS_APB1_BASE + 0x1400) |
||||
#define SUNXI_TWI0_BASE (REGS_APB1_BASE + 0x2800) |
||||
#define SUNXI_TWI1_BASE (REGS_APB1_BASE + 0x2C00) |
||||
#define SUNXI_TWI2_BASE (REGS_APB1_BASE + 0x3000) |
||||
#define SUNXI_TWI3_BASE (REGS_APB1_BASE + 0x3400) |
||||
#define SUNXI_TWI4_BASE (REGS_APB1_BASE + 0x3800) |
||||
|
||||
/* RCPUS Module */ |
||||
#define SUNXI_RPRCM_BASE (REGS_RCPUS_BASE + 0x1400) |
||||
#define SUNXI_R_UART_BASE (REGS_RCPUS_BASE + 0x2800) |
||||
|
||||
/* Misc. */ |
||||
#define SUNXI_BROM_BASE 0xFFFF0000 /* 32K */ |
||||
#define SUNXI_CPU_CFG (SUNXI_TIMER_BASE + 0x13c) |
||||
|
||||
#ifndef __ASSEMBLY__ |
||||
void sunxi_board_init(void); |
||||
void sunxi_reset(void); |
||||
int sunxi_get_sid(unsigned int *sid); |
||||
#endif |
||||
|
||||
#endif /* _SUNXI_CPU_SUN9I_H */ |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 480, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 16, |
||||
.cas = 6, |
||||
.zq = 123, |
||||
.odt_en = 0, |
||||
.size = 512, |
||||
.tpr0 = 0x30926692, |
||||
.tpr1 = 0x1090, |
||||
.tpr2 = 0x1a0c8, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include "common.h" |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 480, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 16, |
||||
.cas = 9, |
||||
.zq = 0x7f, |
||||
.odt_en = 0, |
||||
.size = 512, |
||||
.tpr0 = 0x42d899b7, |
||||
.tpr1 = 0xa090, |
||||
.tpr2 = 0x22a00, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0x10, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 480, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 32, |
||||
.cas = 6, |
||||
.zq = 123, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x30926692, |
||||
.tpr1 = 0x1090, |
||||
.tpr2 = 0x1a0c8, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0, |
||||
.emr2 = 0, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 480, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 32, |
||||
.cas = 9, |
||||
.zq = 0x7f, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x42d899b7, |
||||
.tpr1 = 0xa090, |
||||
.tpr2 = 0x22a00, |
||||
.tpr3 = 0x0, |
||||
.tpr4 = 0x1, |
||||
.tpr5 = 0x0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0x10, |
||||
.emr3 = 0x0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 432, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 8, |
||||
.bus_width = 32, |
||||
.cas = 9, |
||||
.zq = 0x7f, |
||||
.odt_en = 0, |
||||
.size = 2048, |
||||
.tpr0 = 0x42d899b7, |
||||
.tpr1 = 0xa090, |
||||
.tpr2 = 0x22a00, |
||||
.tpr3 = 0x0, |
||||
.tpr4 = 0x1, |
||||
.tpr5 = 0x0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0x10, |
||||
.emr3 = 0x0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 480, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 32, |
||||
.cas = 9, |
||||
.zq = 0x7a, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x42d899b7, |
||||
.tpr1 = 0xa090, |
||||
.tpr2 = 0x22a00, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0x10, |
||||
.emr3 = 0x0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 360, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 32, |
||||
.cas = 6, |
||||
.zq = 123, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x30926692, |
||||
.tpr1 = 0x1090, |
||||
.tpr2 = 0x1a0c8, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0, |
||||
.emr2 = 0, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 360, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 2048, |
||||
.io_width = 8, |
||||
.bus_width = 32, |
||||
.cas = 6, |
||||
.zq = 123, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x30926692, |
||||
.tpr1 = 0x1090, |
||||
.tpr2 = 0x1a0c8, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0, |
||||
.emr2 = 0, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 384, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 2048, |
||||
.io_width = 8, |
||||
.bus_width = 32, |
||||
.cas = 6, |
||||
.zq = 123, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x30926692, |
||||
.tpr1 = 0x1090, |
||||
.tpr2 = 0x1a0c8, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 408, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 2048, |
||||
.io_width = 8, |
||||
.bus_width = 32, |
||||
.cas = 6, |
||||
.zq = 123, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x30926692, |
||||
.tpr1 = 0x1090, |
||||
.tpr2 = 0x1a0c8, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0, |
||||
.emr2 = 0, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,26 +1,24 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 360, |
||||
.clock = CONFIG_DRAM_CLK, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 2048, |
||||
.io_width = 16, |
||||
.bus_width = 32, |
||||
.density = 0, |
||||
.io_width = 0, |
||||
.bus_width = 0, |
||||
.cas = 6, |
||||
.zq = 123, |
||||
.zq = CONFIG_DRAM_ZQ, |
||||
.odt_en = 0, |
||||
.size = 512, |
||||
.size = 0, |
||||
.tpr0 = 0x30926692, |
||||
.tpr1 = 0x1090, |
||||
.tpr2 = 0x1a0c8, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0, |
||||
.emr1 = CONFIG_DRAM_EMR1, |
||||
.emr2 = 0, |
||||
.emr3 = 0, |
||||
}; |
@ -1,26 +1,26 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
/* DRAM parameters for auto dram configuration on sun5i and sun7i */ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 480, |
||||
.clock = CONFIG_DRAM_CLK, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 32, |
||||
.density = 0, |
||||
.io_width = 0, |
||||
.bus_width = 0, |
||||
.cas = 9, |
||||
.zq = 0x7f, |
||||
.zq = CONFIG_DRAM_ZQ, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.size = 0, |
||||
.tpr0 = 0x42d899b7, |
||||
.tpr1 = 0xa090, |
||||
.tpr2 = 0x22a00, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0x4, |
||||
.emr1 = CONFIG_DRAM_EMR1, |
||||
.emr2 = 0x10, |
||||
.emr3 = 0, |
||||
}; |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include "common.h" |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 384, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 32, |
||||
.cas = 9, |
||||
.zq = 0x7f, |
||||
.odt_en = 0, |
||||
.size = 1024, |
||||
.tpr0 = 0x42d899b7, |
||||
.tpr1 = 0xa090, |
||||
.tpr2 = 0x22a00, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0x10, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -1,31 +0,0 @@ |
||||
/* this file is generated, don't edit it yourself */ |
||||
|
||||
#include "common.h" |
||||
#include <asm/arch/dram.h> |
||||
|
||||
static struct dram_para dram_para = { |
||||
.clock = 384, |
||||
.type = 3, |
||||
.rank_num = 1, |
||||
.density = 4096, |
||||
.io_width = 16, |
||||
.bus_width = 16, |
||||
.cas = 9, |
||||
.zq = 0x7f, |
||||
.odt_en = 0, |
||||
.size = 512, |
||||
.tpr0 = 0x42d899b7, |
||||
.tpr1 = 0xa090, |
||||
.tpr2 = 0x22a00, |
||||
.tpr3 = 0, |
||||
.tpr4 = 0, |
||||
.tpr5 = 0, |
||||
.emr1 = 0x4, |
||||
.emr2 = 0x10, |
||||
.emr3 = 0, |
||||
}; |
||||
|
||||
unsigned long sunxi_dram_init(void) |
||||
{ |
||||
return dramc_init(&dram_para); |
||||
} |
@ -0,0 +1,19 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" |
||||
CONFIG_FDTFILE="sun4i-a10-chuwi-v7-cw0825.dtb" |
||||
CONFIG_USB_MUSB_SUNXI=y |
||||
CONFIG_USB0_VBUS_PIN="PB9" |
||||
CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:24,pclk_khz:51000,le:19,ri:300,up:6,lo:31,hs:1,vs:1,sync:3,vmode:0" |
||||
CONFIG_VIDEO_LCD_POWER="PH8" |
||||
CONFIG_VIDEO_LCD_BL_EN="PH7" |
||||
CONFIG_VIDEO_LCD_BL_PWM="PB2" |
||||
CONFIG_VIDEO_LCD_SPI_CS="PA0" |
||||
CONFIG_VIDEO_LCD_SPI_SCLK="PA1" |
||||
CONFIG_VIDEO_LCD_SPI_MOSI="PA2" |
||||
CONFIG_VIDEO_LCD_PANEL_HITACHI_TX18D42VM=y |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_DRAM_CLK=408 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=4 |
@ -0,0 +1,22 @@ |
||||
# The Hyundai A7HD is a 7" 16:9 A10 powered tablet featuring 1G RAM, 8G |
||||
# nand, 1024x600 IPS screen, a mini hdmi port, mini usb receptacle and a |
||||
# headphones port for details see: http://linux-sunxi.org/Hyundai_A7HD |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" |
||||
CONFIG_FDTFILE="sun4i-a10-hyundai-a7hd.dtb" |
||||
CONFIG_USB_MUSB_SUNXI=y |
||||
CONFIG_USB0_VBUS_PIN="PB09" |
||||
CONFIG_USB2_VBUS_PIN="" |
||||
CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:45,ri:274,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" |
||||
CONFIG_VIDEO_LCD_DCLK_PHASE=1 |
||||
CONFIG_VIDEO_LCD_POWER="PH2" |
||||
CONFIG_VIDEO_LCD_BL_EN="PH9" |
||||
CONFIG_VIDEO_LCD_BL_PWM="PB2" |
||||
CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW=n |
||||
CONFIG_VIDEO_LCD_PANEL_LVDS=y |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_DRAM_CLK=360 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=4 |
@ -0,0 +1,9 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,AHCI,USB_EHCI" |
||||
CONFIG_FDTFILE="sun4i-a10-marsboard.dtb" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_DRAM_CLK=360 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=0 |
@ -1,8 +0,0 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI" |
||||
CONFIG_FDTFILE="sun4i-a10-a1000.dtb" |
||||
CONFIG_VIDEO_VGA=y |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_TARGET_MELE_A1000G=y |
@ -0,0 +1,13 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,AHCI,USB_EHCI,STATUSLED=234" |
||||
CONFIG_FDTFILE="sun7i-a20-m5.dtb" |
||||
CONFIG_VIDEO_HDMI=y |
||||
+S:CONFIG_MMC0_CD_PIN="PH1" |
||||
+S:CONFIG_USB1_VBUS_PIN="PH6" |
||||
+S:CONFIG_USB2_VBUS_PIN="PH3" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN7I=y |
||||
+S:CONFIG_DRAM_CLK=432 |
||||
+S:CONFIG_DRAM_ZQ=122 |
||||
+S:CONFIG_DRAM_EMR1=4 |
@ -1,8 +1,10 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,USB_EHCI" |
||||
CONFIG_FDTFILE="sun4i-a10-ba10-tvbox.dtb" |
||||
CONFIG_USB1_VBUS_PIN="PH12" |
||||
CONFIG_USB2_VBUS_PIN="PH12" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_TARGET_BA10_TV_BOX=y |
||||
+S:CONFIG_DRAM_CLK=384 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=4 |
||||
|
@ -0,0 +1,11 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,USB_EHCI" |
||||
CONFIG_FDTFILE="sun5i-a10s-mk802.dtb" |
||||
CONFIG_USB1_VBUS_PIN="PB10" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN5I=y |
||||
+S:CONFIG_TARGET_MK802_A10S=y |
||||
+S:CONFIG_DRAM_CLK=432 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=0 |
@ -0,0 +1,10 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI" |
||||
CONFIG_FDTFILE="sun4i-a10-mk802.dtb" |
||||
CONFIG_USB2_VBUS_PIN="PH12" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_DRAM_CLK=360 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=0 |
@ -1,7 +1,9 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI" |
||||
CONFIG_FDTFILE="sun4i-a10-mini-xplus.dtb" |
||||
CONFIG_FDTFILE="sun4i-a10-mk802ii.dtb" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_TARGET_MINI_X_1GB=y |
||||
+S:CONFIG_DRAM_CLK=360 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=0 |
@ -1,7 +0,0 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI" |
||||
CONFIG_FDTFILE="sun7i-a20-i12-tvbox.dtb" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN7I=y |
||||
+S:CONFIG_TARGET_QT840A=y |
@ -0,0 +1,20 @@ |
||||
# Gemei G9 is an A10 based tablet, with 1G RAM, 16G NAND, |
||||
# 1024x768 IPS LCD display, stereo speakers, 1.3MP front camera and 5 MP |
||||
# rear camera, 8000mAh battery, GT901 2+1 touchscreen, Bosch BMA250 |
||||
# accelerometer and RTL8188CUS USB wifi. It also has MicroSD slot, MiniHDMI, |
||||
# 1 x MicroUSB OTG port and 1 x MicroUSB host port and 3.5mm headphone jack. |
||||
# More details are available at: http://linux-sunxi.org/Gemei_G9 |
||||
CONFIG_SPL=y |
||||
CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI" |
||||
CONFIG_FDTFILE="sun4i-gemei-g9.dtb" |
||||
CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:18,pclk_khz:100000,le:799,ri:260,up:15,lo:16,hs:1,vs:1,sync:3,vmode:0" |
||||
CONFIG_VIDEO_LCD_PANEL_LVDS=y |
||||
CONFIG_VIDEO_LCD_POWER="PH8" |
||||
CONFIG_VIDEO_LCD_BL_EN="PH7" |
||||
CONFIG_VIDEO_LCD_BL_PWM="PB2" |
||||
+S:CONFIG_ARM=y |
||||
+S:CONFIG_ARCH_SUNXI=y |
||||
+S:CONFIG_MACH_SUN4I=y |
||||
+S:CONFIG_DRAM_CLK=432 |
||||
+S:CONFIG_DRAM_ZQ=123 |
||||
+S:CONFIG_DRAM_EMR1=4 |
@ -0,0 +1,81 @@ |
||||
/*
|
||||
* Hitachi tx18d42vm LVDS LCD panel driver |
||||
* |
||||
* (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
#include <asm/gpio.h> |
||||
#include <errno.h> |
||||
|
||||
/*
|
||||
* Very simple write only SPI support, this does not use the generic SPI infra |
||||
* because that assumes R/W SPI, requiring a MISO pin. Also the necessary glue |
||||
* code alone would be larger then this minimal version. |
||||
*/ |
||||
static void lcd_panel_spi_write(int cs, int clk, int mosi, |
||||
unsigned int data, int bits) |
||||
{ |
||||
int i, offset; |
||||
|
||||
gpio_direction_output(cs, 0); |
||||
for (i = 0; i < bits; i++) { |
||||
gpio_direction_output(clk, 0); |
||||
offset = (bits - 1) - i; |
||||
gpio_direction_output(mosi, (data >> offset) & 1); |
||||
udelay(2); |
||||
gpio_direction_output(clk, 1); |
||||
udelay(2); |
||||
} |
||||
gpio_direction_output(cs, 1); |
||||
udelay(2); |
||||
} |
||||
|
||||
int hitachi_tx18d42vm_init(void) |
||||
{ |
||||
const u16 init_data[] = { |
||||
0x0029, /* reset */ |
||||
0x0025, /* standby */ |
||||
0x0840, /* enable normally black */ |
||||
0x0430, /* enable FRC/dither */ |
||||
0x385f, /* enter test mode(1) */ |
||||
0x3ca4, /* enter test mode(2) */ |
||||
0x3409, /* enable SDRRS, enlarge OE width */ |
||||
0x4041, /* adopt 2 line / 1 dot */ |
||||
}; |
||||
int i, cs, clk, mosi, ret = 0; |
||||
|
||||
cs = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS); |
||||
clk = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK); |
||||
mosi = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI); |
||||
|
||||
if (cs == -1 || clk == -1 || mosi == 1) { |
||||
printf("Error tx18d42vm spi gpio config is invalid\n"); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
if (gpio_request(cs, "tx18d42vm-spi-cs") != 0 || |
||||
gpio_request(clk, "tx18d42vm-spi-clk") != 0 || |
||||
gpio_request(mosi, "tx18d42vm-spi-mosi") != 0) { |
||||
printf("Error cannot request tx18d42vm spi gpios\n"); |
||||
ret = -EBUSY; |
||||
goto out; |
||||
} |
||||
|
||||
for (i = 0; i < ARRAY_SIZE(init_data); i++) |
||||
lcd_panel_spi_write(cs, clk, mosi, init_data[i], 16); |
||||
|
||||
mdelay(50); /* All the tx18d42vm drivers have a delay here ? */ |
||||
|
||||
lcd_panel_spi_write(cs, clk, mosi, 0x00ad, 16); /* display on */ |
||||
|
||||
out: |
||||
gpio_free(mosi); |
||||
gpio_free(clk); |
||||
gpio_free(cs); |
||||
|
||||
return ret; |
||||
} |
@ -0,0 +1,9 @@ |
||||
/*
|
||||
* Hitachi tx18d42vm LVDS LCD panel driver |
||||
* |
||||
* (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
void hitachi_tx18d42vm_init(void); |
@ -0,0 +1,436 @@ |
||||
/*
|
||||
* (C) 2015 Siarhei Siamashka <siarhei.siamashka@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
/*
|
||||
* Support for the SSD2828 bridge chip, which can take pixel data coming |
||||
* from a parallel LCD interface and translate it on the flight into MIPI DSI |
||||
* interface for driving a MIPI compatible TFT display. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mipi_display.h> |
||||
#include <asm/arch/gpio.h> |
||||
#include <asm/gpio.h> |
||||
|
||||
#include "videomodes.h" |
||||
#include "ssd2828.h" |
||||
|
||||
#define SSD2828_DIR 0xB0 |
||||
#define SSD2828_VICR1 0xB1 |
||||
#define SSD2828_VICR2 0xB2 |
||||
#define SSD2828_VICR3 0xB3 |
||||
#define SSD2828_VICR4 0xB4 |
||||
#define SSD2828_VICR5 0xB5 |
||||
#define SSD2828_VICR6 0xB6 |
||||
#define SSD2828_CFGR 0xB7 |
||||
#define SSD2828_VCR 0xB8 |
||||
#define SSD2828_PCR 0xB9 |
||||
#define SSD2828_PLCR 0xBA |
||||
#define SSD2828_CCR 0xBB |
||||
#define SSD2828_PSCR1 0xBC |
||||
#define SSD2828_PSCR2 0xBD |
||||
#define SSD2828_PSCR3 0xBE |
||||
#define SSD2828_PDR 0xBF |
||||
#define SSD2828_OCR 0xC0 |
||||
#define SSD2828_MRSR 0xC1 |
||||
#define SSD2828_RDCR 0xC2 |
||||
#define SSD2828_ARSR 0xC3 |
||||
#define SSD2828_LCR 0xC4 |
||||
#define SSD2828_ICR 0xC5 |
||||
#define SSD2828_ISR 0xC6 |
||||
#define SSD2828_ESR 0xC7 |
||||
#define SSD2828_DAR1 0xC9 |
||||
#define SSD2828_DAR2 0xCA |
||||
#define SSD2828_DAR3 0xCB |
||||
#define SSD2828_DAR4 0xCC |
||||
#define SSD2828_DAR5 0xCD |
||||
#define SSD2828_DAR6 0xCE |
||||
#define SSD2828_HTTR1 0xCF |
||||
#define SSD2828_HTTR2 0xD0 |
||||
#define SSD2828_LRTR1 0xD1 |
||||
#define SSD2828_LRTR2 0xD2 |
||||
#define SSD2828_TSR 0xD3 |
||||
#define SSD2828_LRR 0xD4 |
||||
#define SSD2828_PLLR 0xD5 |
||||
#define SSD2828_TR 0xD6 |
||||
#define SSD2828_TECR 0xD7 |
||||
#define SSD2828_ACR1 0xD8 |
||||
#define SSD2828_ACR2 0xD9 |
||||
#define SSD2828_ACR3 0xDA |
||||
#define SSD2828_ACR4 0xDB |
||||
#define SSD2828_IOCR 0xDC |
||||
#define SSD2828_VICR7 0xDD |
||||
#define SSD2828_LCFR 0xDE |
||||
#define SSD2828_DAR7 0xDF |
||||
#define SSD2828_PUCR1 0xE0 |
||||
#define SSD2828_PUCR2 0xE1 |
||||
#define SSD2828_PUCR3 0xE2 |
||||
#define SSD2828_CBCR1 0xE9 |
||||
#define SSD2828_CBCR2 0xEA |
||||
#define SSD2828_CBSR 0xEB |
||||
#define SSD2828_ECR 0xEC |
||||
#define SSD2828_VSDR 0xED |
||||
#define SSD2828_TMR 0xEE |
||||
#define SSD2828_GPIO1 0xEF |
||||
#define SSD2828_GPIO2 0xF0 |
||||
#define SSD2828_DLYA01 0xF1 |
||||
#define SSD2828_DLYA23 0xF2 |
||||
#define SSD2828_DLYB01 0xF3 |
||||
#define SSD2828_DLYB23 0xF4 |
||||
#define SSD2828_DLYC01 0xF5 |
||||
#define SSD2828_DLYC23 0xF6 |
||||
#define SSD2828_ACR5 0xF7 |
||||
#define SSD2828_RR 0xFF |
||||
|
||||
#define SSD2828_CFGR_HS (1 << 0) |
||||
#define SSD2828_CFGR_CKE (1 << 1) |
||||
#define SSD2828_CFGR_SLP (1 << 2) |
||||
#define SSD2828_CFGR_VEN (1 << 3) |
||||
#define SSD2828_CFGR_HCLK (1 << 4) |
||||
#define SSD2828_CFGR_CSS (1 << 5) |
||||
#define SSD2828_CFGR_DCS (1 << 6) |
||||
#define SSD2828_CFGR_REN (1 << 7) |
||||
#define SSD2828_CFGR_ECD (1 << 8) |
||||
#define SSD2828_CFGR_EOT (1 << 9) |
||||
#define SSD2828_CFGR_LPE (1 << 10) |
||||
#define SSD2828_CFGR_TXD (1 << 11) |
||||
|
||||
#define SSD2828_VIDEO_MODE_NON_BURST_WITH_SYNC_PULSES (0 << 2) |
||||
#define SSD2828_VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS (1 << 2) |
||||
#define SSD2828_VIDEO_MODE_BURST (2 << 2) |
||||
|
||||
#define SSD2828_VIDEO_PIXEL_FORMAT_16BPP 0 |
||||
#define SSD2828_VIDEO_PIXEL_FORMAT_18BPP_PACKED 1 |
||||
#define SSD2828_VIDEO_PIXEL_FORMAT_18BPP_LOOSELY_PACKED 2 |
||||
#define SSD2828_VIDEO_PIXEL_FORMAT_24BPP 3 |
||||
|
||||
#define SSD2828_LP_CLOCK_DIVIDER(n) (((n) - 1) & 0x3F) |
||||
|
||||
/*
|
||||
* SPI transfer, using the "24-bit 3 wire" mode (that's how it is called in |
||||
* the SSD2828 documentation). The 'dout' input parameter specifies 24-bits |
||||
* of data to be written to SSD2828. Returns the lowest 16-bits of data, |
||||
* that is received back. |
||||
*/ |
||||
static u32 soft_spi_xfer_24bit_3wire(const struct ssd2828_config *drv, u32 dout) |
||||
{ |
||||
int j, bitlen = 24; |
||||
u32 tmpdin = 0; |
||||
/*
|
||||
* According to the "24 Bit 3 Wire SPI Interface Timing Characteristics" |
||||
* and "TX_CLK Timing Characteristics" tables in the SSD2828 datasheet, |
||||
* the lowest possible 'tx_clk' clock frequency is 8MHz, and SPI runs |
||||
* at 1/8 of that after reset. So using 1 microsecond delays is safe in |
||||
* the main loop. But the delays around chip select pin manipulations |
||||
* need to be longer (up to 16 'tx_clk' cycles, or 2 microseconds in |
||||
* the worst case). |
||||
*/ |
||||
const int spi_delay_us = 1; |
||||
const int spi_cs_delay_us = 2; |
||||
|
||||
gpio_set_value(drv->csx_pin, 0); |
||||
udelay(spi_cs_delay_us); |
||||
for (j = bitlen - 1; j >= 0; j--) { |
||||
gpio_set_value(drv->sck_pin, 0); |
||||
gpio_set_value(drv->sdi_pin, (dout & (1 << j)) != 0); |
||||
udelay(spi_delay_us); |
||||
if (drv->sdo_pin != -1) |
||||
tmpdin = (tmpdin << 1) | gpio_get_value(drv->sdo_pin); |
||||
gpio_set_value(drv->sck_pin, 1); |
||||
udelay(spi_delay_us); |
||||
} |
||||
udelay(spi_cs_delay_us); |
||||
gpio_set_value(drv->csx_pin, 1); |
||||
udelay(spi_cs_delay_us); |
||||
return tmpdin & 0xFFFF; |
||||
} |
||||
|
||||
/*
|
||||
* Read from a SSD2828 hardware register (regnum >= 0xB0) |
||||
*/ |
||||
static u32 read_hw_register(const struct ssd2828_config *cfg, u8 regnum) |
||||
{ |
||||
soft_spi_xfer_24bit_3wire(cfg, 0x700000 | regnum); |
||||
return soft_spi_xfer_24bit_3wire(cfg, 0x730000); |
||||
} |
||||
|
||||
/*
|
||||
* Write to a SSD2828 hardware register (regnum >= 0xB0) |
||||
*/ |
||||
static void write_hw_register(const struct ssd2828_config *cfg, u8 regnum, |
||||
u16 val) |
||||
{ |
||||
soft_spi_xfer_24bit_3wire(cfg, 0x700000 | regnum); |
||||
soft_spi_xfer_24bit_3wire(cfg, 0x720000 | val); |
||||
} |
||||
|
||||
/*
|
||||
* Send MIPI command to the LCD panel (cmdnum < 0xB0) |
||||
*/ |
||||
static void send_mipi_dcs_command(const struct ssd2828_config *cfg, u8 cmdnum) |
||||
{ |
||||
/* Set packet size to 1 (a single command with no parameters) */ |
||||
write_hw_register(cfg, SSD2828_PSCR1, 1); |
||||
/* Send the command */ |
||||
write_hw_register(cfg, SSD2828_PDR, cmdnum); |
||||
} |
||||
|
||||
/*
|
||||
* Reset SSD2828 |
||||
*/ |
||||
static void ssd2828_reset(const struct ssd2828_config *cfg) |
||||
{ |
||||
/* RESET needs 10 milliseconds according to the datasheet */ |
||||
gpio_set_value(cfg->reset_pin, 0); |
||||
mdelay(10); |
||||
gpio_set_value(cfg->reset_pin, 1); |
||||
mdelay(10); |
||||
} |
||||
|
||||
static int ssd2828_enable_gpio(const struct ssd2828_config *cfg) |
||||
{ |
||||
if (gpio_request(cfg->csx_pin, "ssd2828_csx")) { |
||||
printf("SSD2828: request for 'ssd2828_csx' pin failed\n"); |
||||
return 1; |
||||
} |
||||
if (gpio_request(cfg->sck_pin, "ssd2828_sck")) { |
||||
gpio_free(cfg->csx_pin); |
||||
printf("SSD2828: request for 'ssd2828_sck' pin failed\n"); |
||||
return 1; |
||||
} |
||||
if (gpio_request(cfg->sdi_pin, "ssd2828_sdi")) { |
||||
gpio_free(cfg->csx_pin); |
||||
gpio_free(cfg->sck_pin); |
||||
printf("SSD2828: request for 'ssd2828_sdi' pin failed\n"); |
||||
return 1; |
||||
} |
||||
if (gpio_request(cfg->reset_pin, "ssd2828_reset")) { |
||||
gpio_free(cfg->csx_pin); |
||||
gpio_free(cfg->sck_pin); |
||||
gpio_free(cfg->sdi_pin); |
||||
printf("SSD2828: request for 'ssd2828_reset' pin failed\n"); |
||||
return 1; |
||||
} |
||||
if (cfg->sdo_pin != -1 && gpio_request(cfg->sdo_pin, "ssd2828_sdo")) { |
||||
gpio_free(cfg->csx_pin); |
||||
gpio_free(cfg->sck_pin); |
||||
gpio_free(cfg->sdi_pin); |
||||
gpio_free(cfg->reset_pin); |
||||
printf("SSD2828: request for 'ssd2828_sdo' pin failed\n"); |
||||
return 1; |
||||
} |
||||
gpio_direction_output(cfg->reset_pin, 0); |
||||
gpio_direction_output(cfg->csx_pin, 1); |
||||
gpio_direction_output(cfg->sck_pin, 1); |
||||
gpio_direction_output(cfg->sdi_pin, 1); |
||||
if (cfg->sdo_pin != -1) |
||||
gpio_direction_input(cfg->sdo_pin); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int ssd2828_free_gpio(const struct ssd2828_config *cfg) |
||||
{ |
||||
gpio_free(cfg->csx_pin); |
||||
gpio_free(cfg->sck_pin); |
||||
gpio_free(cfg->sdi_pin); |
||||
gpio_free(cfg->reset_pin); |
||||
if (cfg->sdo_pin != -1) |
||||
gpio_free(cfg->sdo_pin); |
||||
return 1; |
||||
} |
||||
|
||||
/*
|
||||
* PLL configuration register settings. |
||||
* |
||||
* See the "PLL Configuration Register Description" in the SSD2828 datasheet. |
||||
*/ |
||||
static u32 construct_pll_config(u32 desired_pll_freq_kbps, |
||||
u32 reference_freq_khz) |
||||
{ |
||||
u32 div_factor = 1, mul_factor, fr = 0; |
||||
u32 output_freq_kbps; |
||||
|
||||
/* The intermediate clock after division can't be less than 5MHz */ |
||||
while (reference_freq_khz / (div_factor + 1) >= 5000) |
||||
div_factor++; |
||||
if (div_factor > 31) |
||||
div_factor = 31; |
||||
|
||||
mul_factor = DIV_ROUND_UP(desired_pll_freq_kbps * div_factor, |
||||
reference_freq_khz); |
||||
|
||||
output_freq_kbps = reference_freq_khz * mul_factor / div_factor; |
||||
|
||||
if (output_freq_kbps >= 501000) |
||||
fr = 3; |
||||
else if (output_freq_kbps >= 251000) |
||||
fr = 2; |
||||
else if (output_freq_kbps >= 126000) |
||||
fr = 1; |
||||
|
||||
return (fr << 14) | (div_factor << 8) | mul_factor; |
||||
} |
||||
|
||||
static u32 decode_pll_config(u32 pll_config, u32 reference_freq_khz) |
||||
{ |
||||
u32 mul_factor = pll_config & 0xFF; |
||||
u32 div_factor = (pll_config >> 8) & 0x1F; |
||||
if (mul_factor == 0) |
||||
mul_factor = 1; |
||||
if (div_factor == 0) |
||||
div_factor = 1; |
||||
return reference_freq_khz * mul_factor / div_factor; |
||||
} |
||||
|
||||
static int ssd2828_configure_video_interface(const struct ssd2828_config *cfg, |
||||
const struct ctfb_res_modes *mode) |
||||
{ |
||||
u32 val; |
||||
|
||||
/* RGB Interface Control Register 1 */ |
||||
write_hw_register(cfg, SSD2828_VICR1, (mode->vsync_len << 8) | |
||||
(mode->hsync_len)); |
||||
|
||||
/* RGB Interface Control Register 2 */ |
||||
u32 vbp = mode->vsync_len + mode->upper_margin; |
||||
u32 hbp = mode->hsync_len + mode->left_margin; |
||||
write_hw_register(cfg, SSD2828_VICR2, (vbp << 8) | hbp); |
||||
|
||||
/* RGB Interface Control Register 3 */ |
||||
write_hw_register(cfg, SSD2828_VICR3, (mode->lower_margin << 8) | |
||||
(mode->right_margin)); |
||||
|
||||
/* RGB Interface Control Register 4 */ |
||||
write_hw_register(cfg, SSD2828_VICR4, mode->xres); |
||||
|
||||
/* RGB Interface Control Register 5 */ |
||||
write_hw_register(cfg, SSD2828_VICR5, mode->yres); |
||||
|
||||
/* RGB Interface Control Register 6 */ |
||||
val = SSD2828_VIDEO_MODE_BURST; |
||||
switch (cfg->ssd2828_color_depth) { |
||||
case 16: |
||||
val |= SSD2828_VIDEO_PIXEL_FORMAT_16BPP; |
||||
break; |
||||
case 18: |
||||
val |= cfg->mipi_dsi_loosely_packed_pixel_format ? |
||||
SSD2828_VIDEO_PIXEL_FORMAT_18BPP_LOOSELY_PACKED : |
||||
SSD2828_VIDEO_PIXEL_FORMAT_18BPP_PACKED; |
||||
break; |
||||
case 24: |
||||
val |= SSD2828_VIDEO_PIXEL_FORMAT_24BPP; |
||||
break; |
||||
default: |
||||
printf("SSD2828: unsupported color depth\n"); |
||||
return 1; |
||||
} |
||||
write_hw_register(cfg, SSD2828_VICR6, val); |
||||
|
||||
/* Lane Configuration Register */ |
||||
write_hw_register(cfg, SSD2828_LCFR, |
||||
cfg->mipi_dsi_number_of_data_lanes - 1); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int ssd2828_init(const struct ssd2828_config *cfg, |
||||
const struct ctfb_res_modes *mode) |
||||
{ |
||||
u32 lp_div, pll_freq_kbps, reference_freq_khz, pll_config; |
||||
/* The LP clock speed is limited by 10MHz */ |
||||
const u32 mipi_dsi_low_power_clk_khz = 10000; |
||||
/*
|
||||
* This is just the reset default value of CFGR register (0x301). |
||||
* Because we are not always able to read back from SPI, have |
||||
* it initialized here. |
||||
*/ |
||||
u32 cfgr_reg = SSD2828_CFGR_EOT | /* EOT Packet Enable */ |
||||
SSD2828_CFGR_ECD | /* Disable ECC and CRC */ |
||||
SSD2828_CFGR_HS; /* Data lanes are in HS mode */ |
||||
|
||||
/* Initialize the pins */ |
||||
if (ssd2828_enable_gpio(cfg) != 0) |
||||
return 1; |
||||
|
||||
/* Reset the chip */ |
||||
ssd2828_reset(cfg); |
||||
|
||||
/*
|
||||
* If there is a pin to read data back from SPI, then we are lucky. Try |
||||
* to check if SPI is configured correctly and SSD2828 is actually able |
||||
* to talk back. |
||||
*/ |
||||
if (cfg->sdo_pin != -1) { |
||||
if (read_hw_register(cfg, SSD2828_DIR) != 0x2828 || |
||||
read_hw_register(cfg, SSD2828_CFGR) != cfgr_reg) { |
||||
printf("SSD2828: SPI communication failed.\n"); |
||||
ssd2828_free_gpio(cfg); |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* Pick the reference clock for PLL. If we know the exact 'tx_clk' |
||||
* clock speed, then everything is good. If not, then we can fallback |
||||
* to 'pclk' (pixel clock from the parallel LCD interface). In the |
||||
* case of using this fallback, it is necessary to have parallel LCD |
||||
* already initialized and running at this point. |
||||
*/ |
||||
reference_freq_khz = cfg->ssd2828_tx_clk_khz; |
||||
if (reference_freq_khz == 0) { |
||||
reference_freq_khz = mode->pixclock_khz; |
||||
/* Use 'pclk' as the reference clock for PLL */ |
||||
cfgr_reg |= SSD2828_CFGR_CSS; |
||||
} |
||||
|
||||
/*
|
||||
* Setup the parallel LCD timings in the appropriate registers. |
||||
*/ |
||||
if (ssd2828_configure_video_interface(cfg, mode) != 0) { |
||||
ssd2828_free_gpio(cfg); |
||||
return 1; |
||||
} |
||||
|
||||
/* Configuration Register */ |
||||
cfgr_reg &= ~SSD2828_CFGR_HS; /* Data lanes are in LP mode */ |
||||
cfgr_reg |= SSD2828_CFGR_CKE; /* Clock lane is in HS mode */ |
||||
cfgr_reg |= SSD2828_CFGR_DCS; /* Only use DCS packets */ |
||||
write_hw_register(cfg, SSD2828_CFGR, cfgr_reg); |
||||
|
||||
/* PLL Configuration Register */ |
||||
pll_config = construct_pll_config( |
||||
cfg->mipi_dsi_bitrate_per_data_lane_mbps * 1000, |
||||
reference_freq_khz); |
||||
write_hw_register(cfg, SSD2828_PLCR, pll_config); |
||||
|
||||
pll_freq_kbps = decode_pll_config(pll_config, reference_freq_khz); |
||||
lp_div = DIV_ROUND_UP(pll_freq_kbps, mipi_dsi_low_power_clk_khz * 8); |
||||
|
||||
/* VC Control Register */ |
||||
write_hw_register(cfg, SSD2828_VCR, 0); |
||||
|
||||
/* Clock Control Register */ |
||||
write_hw_register(cfg, SSD2828_CCR, SSD2828_LP_CLOCK_DIVIDER(lp_div)); |
||||
|
||||
/* PLL Control Register */ |
||||
write_hw_register(cfg, SSD2828_PCR, 1); /* Enable PLL */ |
||||
|
||||
/* Wait for PLL lock */ |
||||
udelay(500); |
||||
|
||||
send_mipi_dcs_command(cfg, MIPI_DCS_EXIT_SLEEP_MODE); |
||||
mdelay(cfg->mipi_dsi_delay_after_exit_sleep_mode_ms); |
||||
|
||||
send_mipi_dcs_command(cfg, MIPI_DCS_SET_DISPLAY_ON); |
||||
mdelay(cfg->mipi_dsi_delay_after_set_display_on_ms); |
||||
|
||||
cfgr_reg |= SSD2828_CFGR_HS; /* Enable HS mode for data lanes */ |
||||
cfgr_reg |= SSD2828_CFGR_VEN; /* Enable video pipeline */ |
||||
write_hw_register(cfg, SSD2828_CFGR, cfgr_reg); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,128 @@ |
||||
/*
|
||||
* (C) 2015 Siarhei Siamashka <siarhei.siamashka@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
/*
|
||||
* Support for the SSD2828 bridge chip, which can take pixel data coming |
||||
* from a parallel LCD interface and translate it on the flight into MIPI DSI |
||||
* interface for driving a MIPI compatible TFT display. |
||||
* |
||||
* Implemented as a utility function. To be used from display drivers, which are |
||||
* responsible for driving parallel LCD hardware in front of the video pipeline. |
||||
*/ |
||||
|
||||
#ifndef _SSD2828_H |
||||
#define _SSD2828_H |
||||
|
||||
struct ctfb_res_modes; |
||||
|
||||
struct ssd2828_config { |
||||
/*********************************************************************/ |
||||
/* SSD2828 configuration */ |
||||
/*********************************************************************/ |
||||
|
||||
/*
|
||||
* The pins, which are used for SPI communication. This is only used |
||||
* for configuring SSD2828, so the performance is irrelevant (only |
||||
* around a hundred of bytes is moved). Also these can be any arbitrary |
||||
* GPIO pins (not necessarily the pins having hardware SPI function). |
||||
* Moreover, the 'sdo' pin may be even not wired up in some devices. |
||||
* |
||||
* These configuration variables need to be set as pin numbers for |
||||
* the standard u-boot GPIO interface (gpio_get_value/gpio_set_value |
||||
* functions). Note that -1 value can be used for the pins, which are |
||||
* not really wired up. |
||||
*/ |
||||
int csx_pin; |
||||
int sck_pin; |
||||
int sdi_pin; |
||||
int sdo_pin; |
||||
/* SSD2828 reset pin (shared with LCD panel reset) */ |
||||
int reset_pin; |
||||
|
||||
/*
|
||||
* The SSD2828 has its own dedicated clock source 'tx_clk' (connected |
||||
* to TX_CLK_XIO/TX_CLK_XIN pins), which is necessary at least for |
||||
* clocking SPI after reset. The exact clock speed is not strictly, |
||||
* defined, but the datasheet says that it must be somewhere in the |
||||
* 8MHz - 30MHz range (see "TX_CLK Timing" section). It can be also |
||||
* used as a reference clock for PLL. If the exact clock frequency |
||||
* is known, then it can be specified here. If it is unknown, or the |
||||
* information is not trustworthy, then it can be set to 0. |
||||
* |
||||
* If unsure, set to 0. |
||||
*/ |
||||
int ssd2828_tx_clk_khz; |
||||
|
||||
/*
|
||||
* This is not a property of the used LCD panel, but more like a |
||||
* property of the SSD2828 wiring. See the "SSD2828QN4 RGB data |
||||
* arrangement" table in the datasheet. The SSD2828 pins are arranged |
||||
* in such a way that 18bpp and 24bpp configurations are completely |
||||
* incompatible with each other. |
||||
* |
||||
* Depending on the color depth, this must be set to 16, 18 or 24. |
||||
*/ |
||||
int ssd2828_color_depth; |
||||
|
||||
/*********************************************************************/ |
||||
/* LCD panel configuration */ |
||||
/*********************************************************************/ |
||||
|
||||
/*
|
||||
* The number of lanes in the MIPI DSI interface. May vary from 1 to 4. |
||||
* |
||||
* This information can be found in the LCD panel datasheet. |
||||
*/ |
||||
int mipi_dsi_number_of_data_lanes; |
||||
|
||||
/*
|
||||
* Data transfer bit rate per lane. Please note that it is expected |
||||
* to be higher than the pixel clock rate of the used video mode when |
||||
* multiplied by the number of lanes. This is perfectly normal because |
||||
* MIPI DSI handles data transfers in periodic bursts, and uses the |
||||
* idle time between bursts for sending configuration information and |
||||
* commands. Or just for saving power. |
||||
* |
||||
* The necessary Mbps/lane information can be found in the LCD panel |
||||
* datasheet. Note that the transfer rate can't be always set precisely |
||||
* and it may be rounded *up* (introducing no more than 10Mbps error). |
||||
*/ |
||||
int mipi_dsi_bitrate_per_data_lane_mbps; |
||||
|
||||
/*
|
||||
* Setting this to 1 enforces packing of 18bpp pixel data in 24bpp |
||||
* envelope when sending it over the MIPI DSI link. |
||||
* |
||||
* If unsure, set to 0. |
||||
*/ |
||||
int mipi_dsi_loosely_packed_pixel_format; |
||||
|
||||
/*
|
||||
* According to the "Example for system sleep in and out" section in |
||||
* the SSD2828 datasheet, some LCD panel specific delays are necessary |
||||
* after MIPI DCS commands EXIT_SLEEP_MODE and SET_DISPLAY_ON. |
||||
* |
||||
* For example, Allwinner uses 100 milliseconds delay after |
||||
* EXIT_SLEEP_MODE and 200 milliseconds delay after SET_DISPLAY_ON. |
||||
*/ |
||||
int mipi_dsi_delay_after_exit_sleep_mode_ms; |
||||
int mipi_dsi_delay_after_set_display_on_ms; |
||||
}; |
||||
|
||||
/*
|
||||
* Initialize the SSD2828 chip. It needs the 'ssd2828_config' structure |
||||
* and also the video mode timings. |
||||
* |
||||
* The right place to insert this function call is after the parallel LCD |
||||
* interface is initialized and before turning on the backlight. This is |
||||
* advised in the "Example for system sleep in and out" section of the |
||||
* SSD2828 datasheet. And also SS2828 may use 'pclk' as the clock source |
||||
* for PLL, which means that the input signal must be already there. |
||||
*/ |
||||
int ssd2828_init(const struct ssd2828_config *cfg, |
||||
const struct ctfb_res_modes *mode); |
||||
|
||||
#endif |
@ -0,0 +1,130 @@ |
||||
/*
|
||||
* Defines for Mobile Industry Processor Interface (MIPI(R)) |
||||
* Display Working Group standards: DSI, DCS, DBI, DPI |
||||
* |
||||
* Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
||||
* Copyright (C) 2006 Nokia Corporation |
||||
* Author: Imre Deak <imre.deak@nokia.com> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#ifndef MIPI_DISPLAY_H |
||||
#define MIPI_DISPLAY_H |
||||
|
||||
/* MIPI DSI Processor-to-Peripheral transaction types */ |
||||
enum { |
||||
MIPI_DSI_V_SYNC_START = 0x01, |
||||
MIPI_DSI_V_SYNC_END = 0x11, |
||||
MIPI_DSI_H_SYNC_START = 0x21, |
||||
MIPI_DSI_H_SYNC_END = 0x31, |
||||
|
||||
MIPI_DSI_COLOR_MODE_OFF = 0x02, |
||||
MIPI_DSI_COLOR_MODE_ON = 0x12, |
||||
MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22, |
||||
MIPI_DSI_TURN_ON_PERIPHERAL = 0x32, |
||||
|
||||
MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03, |
||||
MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13, |
||||
MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23, |
||||
|
||||
MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04, |
||||
MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14, |
||||
MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24, |
||||
|
||||
MIPI_DSI_DCS_SHORT_WRITE = 0x05, |
||||
MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15, |
||||
|
||||
MIPI_DSI_DCS_READ = 0x06, |
||||
|
||||
MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37, |
||||
|
||||
MIPI_DSI_END_OF_TRANSMISSION = 0x08, |
||||
|
||||
MIPI_DSI_NULL_PACKET = 0x09, |
||||
MIPI_DSI_BLANKING_PACKET = 0x19, |
||||
MIPI_DSI_GENERIC_LONG_WRITE = 0x29, |
||||
MIPI_DSI_DCS_LONG_WRITE = 0x39, |
||||
|
||||
MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c, |
||||
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c, |
||||
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c, |
||||
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d, |
||||
MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d, |
||||
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d, |
||||
|
||||
MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e, |
||||
MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e, |
||||
MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e, |
||||
MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e, |
||||
}; |
||||
|
||||
/* MIPI DSI Peripheral-to-Processor transaction types */ |
||||
enum { |
||||
MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02, |
||||
MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08, |
||||
MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11, |
||||
MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12, |
||||
MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a, |
||||
MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c, |
||||
MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21, |
||||
MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22, |
||||
}; |
||||
|
||||
/* MIPI DCS commands */ |
||||
enum { |
||||
MIPI_DCS_NOP = 0x00, |
||||
MIPI_DCS_SOFT_RESET = 0x01, |
||||
MIPI_DCS_GET_DISPLAY_ID = 0x04, |
||||
MIPI_DCS_GET_RED_CHANNEL = 0x06, |
||||
MIPI_DCS_GET_GREEN_CHANNEL = 0x07, |
||||
MIPI_DCS_GET_BLUE_CHANNEL = 0x08, |
||||
MIPI_DCS_GET_DISPLAY_STATUS = 0x09, |
||||
MIPI_DCS_GET_POWER_MODE = 0x0A, |
||||
MIPI_DCS_GET_ADDRESS_MODE = 0x0B, |
||||
MIPI_DCS_GET_PIXEL_FORMAT = 0x0C, |
||||
MIPI_DCS_GET_DISPLAY_MODE = 0x0D, |
||||
MIPI_DCS_GET_SIGNAL_MODE = 0x0E, |
||||
MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F, |
||||
MIPI_DCS_ENTER_SLEEP_MODE = 0x10, |
||||
MIPI_DCS_EXIT_SLEEP_MODE = 0x11, |
||||
MIPI_DCS_ENTER_PARTIAL_MODE = 0x12, |
||||
MIPI_DCS_ENTER_NORMAL_MODE = 0x13, |
||||
MIPI_DCS_EXIT_INVERT_MODE = 0x20, |
||||
MIPI_DCS_ENTER_INVERT_MODE = 0x21, |
||||
MIPI_DCS_SET_GAMMA_CURVE = 0x26, |
||||
MIPI_DCS_SET_DISPLAY_OFF = 0x28, |
||||
MIPI_DCS_SET_DISPLAY_ON = 0x29, |
||||
MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A, |
||||
MIPI_DCS_SET_PAGE_ADDRESS = 0x2B, |
||||
MIPI_DCS_WRITE_MEMORY_START = 0x2C, |
||||
MIPI_DCS_WRITE_LUT = 0x2D, |
||||
MIPI_DCS_READ_MEMORY_START = 0x2E, |
||||
MIPI_DCS_SET_PARTIAL_AREA = 0x30, |
||||
MIPI_DCS_SET_SCROLL_AREA = 0x33, |
||||
MIPI_DCS_SET_TEAR_OFF = 0x34, |
||||
MIPI_DCS_SET_TEAR_ON = 0x35, |
||||
MIPI_DCS_SET_ADDRESS_MODE = 0x36, |
||||
MIPI_DCS_SET_SCROLL_START = 0x37, |
||||
MIPI_DCS_EXIT_IDLE_MODE = 0x38, |
||||
MIPI_DCS_ENTER_IDLE_MODE = 0x39, |
||||
MIPI_DCS_SET_PIXEL_FORMAT = 0x3A, |
||||
MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C, |
||||
MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E, |
||||
MIPI_DCS_SET_TEAR_SCANLINE = 0x44, |
||||
MIPI_DCS_GET_SCANLINE = 0x45, |
||||
MIPI_DCS_READ_DDB_START = 0xA1, |
||||
MIPI_DCS_READ_DDB_CONTINUE = 0xA8, |
||||
}; |
||||
|
||||
/* MIPI DCS pixel formats */ |
||||
#define MIPI_DCS_PIXEL_FMT_24BIT 7 |
||||
#define MIPI_DCS_PIXEL_FMT_18BIT 6 |
||||
#define MIPI_DCS_PIXEL_FMT_16BIT 5 |
||||
#define MIPI_DCS_PIXEL_FMT_12BIT 3 |
||||
#define MIPI_DCS_PIXEL_FMT_8BIT 2 |
||||
#define MIPI_DCS_PIXEL_FMT_3BIT 1 |
||||
|
||||
#endif |
Loading…
Reference in new issue