mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
Merge branch 'master' of http://git.denx.de/u-boot-sunxi
This commit is contained in:
commit
15f8876b1d
22 changed files with 788 additions and 96 deletions
|
@ -232,6 +232,13 @@ void sunxi_usb_phy_power_off(int index)
|
|||
gpio_set_value(phy->gpio_vbus, 0);
|
||||
}
|
||||
|
||||
int sunxi_usb_phy_power_is_on(int index)
|
||||
{
|
||||
struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
|
||||
|
||||
return phy->power_on_count > 0;
|
||||
}
|
||||
|
||||
int sunxi_usb_phy_vbus_detect(int index)
|
||||
{
|
||||
struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
|
||||
|
|
|
@ -267,6 +267,8 @@ struct sunxi_ccm_reg {
|
|||
#define CCM_MBUS_CTRL_CLK_SRC_PLL5 0x2
|
||||
#define CCM_MBUS_CTRL_GATE (0x1 << 31)
|
||||
|
||||
#define CCM_NAND_CTRL_ENABLE (0x1 << 31)
|
||||
|
||||
#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)
|
||||
|
@ -289,7 +291,7 @@ struct sunxi_ccm_reg {
|
|||
#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)
|
||||
|
||||
#define CCM_LCD_CH1_CTRL_M(n) ((((n) - 1) & 0xf) << 0)
|
||||
/* We leave bit 11 set to 0, so sclk1 == sclk2 */
|
||||
#define CCM_LCD_CH1_CTRL_HALF_SCLK1 (1 << 11)
|
||||
#define CCM_LCD_CH1_CTRL_PLL3 (0 << 24)
|
||||
#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24)
|
||||
#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24)
|
||||
|
|
|
@ -290,6 +290,7 @@ struct sunxi_ccm_reg {
|
|||
#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)
|
||||
|
||||
#define CCM_LCD_CH1_CTRL_M(n) ((((n) - 1) & 0xf) << 0)
|
||||
#define CCM_LCD_CH1_CTRL_HALF_SCLK1 0 /* no seperate sclk1 & 2 on sun6i */
|
||||
#define CCM_LCD_CH1_CTRL_PLL3 (0 << 24)
|
||||
#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24)
|
||||
#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24)
|
||||
|
|
|
@ -151,6 +151,10 @@ struct sunxi_de_be_reg {
|
|||
u32 layer1_attr1_ctrl; /* 0x8a4 */
|
||||
u32 layer2_attr1_ctrl; /* 0x8a8 */
|
||||
u32 layer3_attr1_ctrl; /* 0x8ac */
|
||||
u8 res5[0x110]; /* 0x8b0 */
|
||||
u32 output_color_ctrl; /* 0x9c0 */
|
||||
u8 res6[0xc]; /* 0x9c4 */
|
||||
u32 output_color_coef[12]; /* 0x9d0 */
|
||||
};
|
||||
|
||||
struct sunxi_lcdc_reg {
|
||||
|
@ -298,7 +302,7 @@ struct sunxi_tve_reg {
|
|||
u32 cbr_level; /* 0x10c */
|
||||
u32 burst_phase; /* 0x110 */
|
||||
u32 burst_width; /* 0x114 */
|
||||
u8 res2[0x04]; /* 0x118 */
|
||||
u32 unknown2; /* 0x118 */
|
||||
u32 sync_vbi_level; /* 0x11c */
|
||||
u32 white_level; /* 0x120 */
|
||||
u32 active_num; /* 0x124 */
|
||||
|
@ -331,11 +335,14 @@ struct sunxi_tve_reg {
|
|||
#define SUNXI_DE_BE_HEIGHT(y) (((y) - 1) << 16)
|
||||
#define SUNXI_DE_BE_MODE_ENABLE (1 << 0)
|
||||
#define SUNXI_DE_BE_MODE_START (1 << 1)
|
||||
#define SUNXI_DE_BE_MODE_DEFLICKER_ENABLE (1 << 4)
|
||||
#define SUNXI_DE_BE_MODE_LAYER0_ENABLE (1 << 8)
|
||||
#define SUNXI_DE_BE_MODE_INTERLACE_ENABLE (1 << 28)
|
||||
#define SUNXI_DE_BE_LAYER_STRIDE(x) ((x) << 5)
|
||||
#define SUNXI_DE_BE_REG_CTRL_LOAD_REGS (1 << 0)
|
||||
#define SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0 0x00000002
|
||||
#define SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888 (0x09 << 8)
|
||||
#define SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE 1
|
||||
|
||||
/*
|
||||
* LCDC register constants.
|
||||
|
@ -372,11 +379,12 @@ struct sunxi_tve_reg {
|
|||
#define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE (1 << 31)
|
||||
#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(x) ((x) << 28)
|
||||
#define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n) (((n) & 0x1f) << 4)
|
||||
#define SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE (1 << 20)
|
||||
#define SUNXI_LCDC_TCON1_CTRL_ENABLE (1 << 31)
|
||||
#define SUNXI_LCDC_TCON1_TIMING_H_BP(n) (((n) - 1) << 0)
|
||||
#define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n) (((n) - 1) << 16)
|
||||
#define SUNXI_LCDC_TCON1_TIMING_V_BP(n) (((n) - 1) << 0)
|
||||
#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n) (((n) * 2) << 16)
|
||||
#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n) ((n) << 16)
|
||||
#ifdef CONFIG_SUNXI_GEN_SUN6I
|
||||
#define SUNXI_LCDC_LVDS_ANA0 0x40040320
|
||||
#define SUNXI_LCDC_LVDS_ANA0_EN_MB (1 << 31)
|
||||
|
@ -494,9 +502,22 @@ struct sunxi_tve_reg {
|
|||
*/
|
||||
#define SUNXI_TVE_GCTRL_DAC_INPUT_MASK(dac) (0xf << (((dac) + 1) * 4))
|
||||
#define SUNXI_TVE_GCTRL_DAC_INPUT(dac, sel) ((sel) << (((dac) + 1) * 4))
|
||||
#define SUNXI_TVE_GCTRL_CFG0_VGA 0x20000000
|
||||
#define SUNXI_TVE_GCTRL_DAC_CFG0_VGA 0x403e1ac7
|
||||
#define SUNXI_TVE_GCTRL_UNKNOWN1_VGA 0x00000000
|
||||
#define SUNXI_TVE_CFG0_VGA 0x20000000
|
||||
#define SUNXI_TVE_CFG0_PAL 0x07030001
|
||||
#define SUNXI_TVE_CFG0_NTSC 0x07030000
|
||||
#define SUNXI_TVE_DAC_CFG0_VGA 0x403e1ac7
|
||||
#define SUNXI_TVE_DAC_CFG0_COMPOSITE 0x403f0008
|
||||
#define SUNXI_TVE_FILTER_COMPOSITE 0x00000120
|
||||
#define SUNXI_TVE_CHROMA_FREQ_PAL_M 0x21e6efe3
|
||||
#define SUNXI_TVE_CHROMA_FREQ_PAL_NC 0x21f69446
|
||||
#define SUNXI_TVE_PORCH_NUM_PAL 0x008a0018
|
||||
#define SUNXI_TVE_PORCH_NUM_NTSC 0x00760020
|
||||
#define SUNXI_TVE_LINE_NUM_PAL 0x00160271
|
||||
#define SUNXI_TVE_LINE_NUM_NTSC 0x0016020d
|
||||
#define SUNXI_TVE_BLANK_BLACK_LEVEL_PAL 0x00fc00fc
|
||||
#define SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC 0x00f0011a
|
||||
#define SUNXI_TVE_UNKNOWN1_VGA 0x00000000
|
||||
#define SUNXI_TVE_UNKNOWN1_COMPOSITE 0x18181818
|
||||
#define SUNXI_TVE_AUTO_DETECT_EN_DET_EN(dac) (1 << ((dac) + 0))
|
||||
#define SUNXI_TVE_AUTO_DETECT_EN_INT_EN(dac) (1 << ((dac) + 16))
|
||||
#define SUNXI_TVE_AUTO_DETECT_INT_STATUS(dac) (1 << ((dac) + 0))
|
||||
|
@ -512,6 +533,20 @@ struct sunxi_tve_reg {
|
|||
#define SUNXI_TVE_CSC_REG1 0x3b6dace1
|
||||
#define SUNXI_TVE_CSC_REG2 0x0e1d13dc
|
||||
#define SUNXI_TVE_CSC_REG3 0x00108080
|
||||
#define SUNXI_TVE_COLOR_BURST_PAL_M 0x00000000
|
||||
#define SUNXI_TVE_CBR_LEVEL_PAL 0x00002828
|
||||
#define SUNXI_TVE_CBR_LEVEL_NTSC 0x0000004f
|
||||
#define SUNXI_TVE_BURST_PHASE_NTSC 0x00000000
|
||||
#define SUNXI_TVE_BURST_WIDTH_COMPOSITE 0x0016447e
|
||||
#define SUNXI_TVE_UNKNOWN2_PAL 0x0000e0e0
|
||||
#define SUNXI_TVE_UNKNOWN2_NTSC 0x0000a0a0
|
||||
#define SUNXI_TVE_SYNC_VBI_LEVEL_NTSC 0x001000f0
|
||||
#define SUNXI_TVE_ACTIVE_NUM_COMPOSITE 0x000005a0
|
||||
#define SUNXI_TVE_CHROMA_BW_GAIN_COMP 0x00000002
|
||||
#define SUNXI_TVE_NOTCH_WIDTH_COMPOSITE 0x00000101
|
||||
#define SUNXI_TVE_RESYNC_NUM_PAL 0x800d000c
|
||||
#define SUNXI_TVE_RESYNC_NUM_NTSC 0x000e000c
|
||||
#define SUNXI_TVE_SLAVE_PARA_COMPOSITE 0x00000000
|
||||
|
||||
int sunxi_simplefb_setup(void *blob);
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ enum sunxi_gpio_number {
|
|||
#define SUN8I_GPB_UART2 2
|
||||
#define SUN8I_A33_GPB_UART0 3
|
||||
|
||||
#define SUNXI_GPC_NAND 2
|
||||
#define SUNXI_GPC_SDC2 3
|
||||
#define SUN6I_GPC_SDC3 4
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ void sunxi_usb_phy_init(int index);
|
|||
void sunxi_usb_phy_exit(int index);
|
||||
void sunxi_usb_phy_power_on(int index);
|
||||
void sunxi_usb_phy_power_off(int index);
|
||||
int sunxi_usb_phy_power_is_on(int index);
|
||||
int sunxi_usb_phy_vbus_detect(int index);
|
||||
int sunxi_usb_phy_id_detect(int index);
|
||||
void sunxi_usb_phy_enable_squelch_detect(int index, int enable);
|
||||
|
|
|
@ -410,6 +410,13 @@ config VIDEO_VGA_EXTERNAL_DAC_EN
|
|||
Set the enable pin for the external VGA DAC. This takes a string in the
|
||||
format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
|
||||
|
||||
config VIDEO_COMPOSITE
|
||||
boolean "Composite video output support"
|
||||
depends on VIDEO && (MACH_SUN4I || MACH_SUN5I || MACH_SUN7I)
|
||||
default n
|
||||
---help---
|
||||
Say Y here to add support for outputting composite video.
|
||||
|
||||
config VIDEO_LCD_MODE
|
||||
string "LCD panel timing details"
|
||||
depends on VIDEO
|
||||
|
|
|
@ -107,6 +107,28 @@ int dram_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SPL_NAND_SUNXI) && defined(CONFIG_SPL_BUILD)
|
||||
static void nand_pinmux_setup(void)
|
||||
{
|
||||
unsigned int pin;
|
||||
for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(6); pin++)
|
||||
sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
|
||||
|
||||
for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(22); pin++)
|
||||
sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
|
||||
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
|
||||
}
|
||||
|
||||
static void nand_clock_setup(void)
|
||||
{
|
||||
struct sunxi_ccm_reg *const ccm =
|
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
|
||||
setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GENERIC_MMC
|
||||
static void mmc_pinmux_setup(int sdc)
|
||||
{
|
||||
|
@ -431,6 +453,11 @@ void sunxi_board_init(void)
|
|||
power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_NAND_SUNXI
|
||||
nand_pinmux_setup();
|
||||
nand_clock_setup();
|
||||
#endif
|
||||
|
||||
printf("DRAM:");
|
||||
ramsize = sunxi_dram_init();
|
||||
printf(" %lu MiB\n", ramsize >> 20);
|
||||
|
|
|
@ -5,6 +5,7 @@ CONFIG_DRAM_CLK=408
|
|||
CONFIG_DRAM_EMR1=4
|
||||
CONFIG_USB0_VBUS_PIN="PB9"
|
||||
CONFIG_USB0_VBUS_DET="PH5"
|
||||
CONFIG_USB0_ID_DET="PH4"
|
||||
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"
|
||||
|
|
|
@ -5,6 +5,7 @@ CONFIG_DRAM_CLK=384
|
|||
CONFIG_MMC0_CD_PIN="PH1"
|
||||
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
CONFIG_VIDEO_VGA=y
|
||||
CONFIG_VIDEO_COMPOSITE=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-m3"
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SPL=y
|
||||
|
|
|
@ -7,6 +7,7 @@ CONFIG_MMC0_CD_PIN="PG0"
|
|||
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
CONFIG_USB0_VBUS_PIN="PB04"
|
||||
CONFIG_USB0_VBUS_DET="PG01"
|
||||
CONFIG_USB0_ID_DET="PG2"
|
||||
CONFIG_AXP_GPIO=y
|
||||
CONFIG_VIDEO_LCD_MODE="x:480,y:800,depth:18,pclk_khz:25000,le:2,ri:93,up:2,lo:93,hs:1,vs:1,sync:3,vmode:0"
|
||||
CONFIG_VIDEO_LCD_DCLK_PHASE=0
|
||||
|
|
|
@ -2,10 +2,15 @@ CONFIG_ARM=y
|
|||
CONFIG_ARCH_SUNXI=y
|
||||
CONFIG_MACH_SUN7I=y
|
||||
CONFIG_DRAM_CLK=384
|
||||
CONFIG_USB0_VBUS_PIN="PB9"
|
||||
CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
|
||||
CONFIG_USB0_ID_DET="PH4"
|
||||
CONFIG_AXP_GPIO=y
|
||||
CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:24,pclk_khz:33000,le:45,ri:210,up:22,lo:22,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_USB_MUSB_HOST=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-wexler-tab7200"
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SPL=y
|
||||
|
|
|
@ -10,3 +10,5 @@ CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(19)"
|
|||
# CONFIG_CMD_FLASH is not set
|
||||
# CONFIG_CMD_FPGA is not set
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_MUSB_HOST=y
|
||||
CONFIG_USB0_VBUS_PIN="PB9"
|
||||
|
|
|
@ -40,12 +40,15 @@ requires the CONFIG_VIDEO_LCD_MODE Kconfig value to be set.
|
|||
|
||||
The sunxi u-boot driver supports the following video-mode options:
|
||||
|
||||
- monitor=[none|dvi|hdmi|lcd] - Select the video output to use
|
||||
- monitor=[none|dvi|hdmi|lcd|vga|composite-*] - Select the video output to use
|
||||
none: Disable video output.
|
||||
dvi/hdmi: Selects output over the hdmi connector with dvi resp. hdmi output
|
||||
format, if edid is used the format is automatically selected.
|
||||
lcd: Selects video output to a LCD screen.
|
||||
vga: Selects bideo output over the VGA connector.
|
||||
vga: Selects video output over the VGA connector.
|
||||
composite-pal/composite-ntsc/composite-pal-m/composite-pal-nc:
|
||||
Selects composite video output, note the specified resolution is
|
||||
ignored with composite video output.
|
||||
Defaults to monitor=dvi.
|
||||
|
||||
- hpd=[0|1] - Enable use of the hdmi HotPlug Detect feature
|
||||
|
|
|
@ -85,6 +85,46 @@ config SPL_NAND_DENALI
|
|||
This is a small implementation of the Denali NAND controller
|
||||
for use on SPL.
|
||||
|
||||
config SPL_NAND_SUNXI
|
||||
bool "Support for NAND on Allwinner A20 in SPL"
|
||||
depends on MACH_SUN7I
|
||||
---help---
|
||||
Enable support for NAND. This option allows SPL to read from
|
||||
sunxi NAND using DMA transfers.
|
||||
Depending on the NAND chip, values like ECC strength and page sizes
|
||||
have to be configured.
|
||||
|
||||
config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END
|
||||
hex "Size of syndrome partitions in sunxi NAND"
|
||||
default 0x400000
|
||||
depends on SPL_NAND_SUNXI
|
||||
---help---
|
||||
End address for boot partitions on NAND. Those partitions have a
|
||||
different random seed that has to match the sunxi BROM setting.
|
||||
|
||||
config NAND_SUNXI_SPL_ECC_STRENGTH
|
||||
int "ECC Strength for sunxi NAND"
|
||||
default 40
|
||||
depends on SPL_NAND_SUNXI
|
||||
---help---
|
||||
ECC strength used by the sunxi NAND SPL driver. This is specific to the
|
||||
chosen NAND chip and has to match the value used by the sunxi BROM.
|
||||
|
||||
config NAND_SUNXI_SPL_ECC_PAGE_SIZE
|
||||
hex "ECC page size for sunxi NAND"
|
||||
default 0x400
|
||||
depends on SPL_NAND_SUNXI
|
||||
---help---
|
||||
ECC page size used by the sunxi NAND SPL driver for syndrome partitions.
|
||||
This setting has to match the value used by the sunxi BROM.
|
||||
|
||||
config NAND_SUNXI_SPL_PAGE_SIZE
|
||||
hex "Page size for sunxi NAND"
|
||||
default 0x2000
|
||||
depends on SPL_NAND_SUNXI
|
||||
---help---
|
||||
Page size of the NAND flash used by the sunxi NAND SPL driver. This is
|
||||
specific to the chosen NAND chip.
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -12,6 +12,7 @@ NORMAL_DRIVERS=y
|
|||
endif
|
||||
|
||||
obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
|
||||
obj-$(CONFIG_SPL_NAND_SUNXI) += sunxi_nand_spl.o
|
||||
obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
|
||||
obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
|
||||
obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
|
||||
|
|
353
drivers/mtd/nand/sunxi_nand_spl.c
Normal file
353
drivers/mtd/nand/sunxi_nand_spl.c
Normal file
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015, Antmicro Ltd <www.antmicro.com>
|
||||
* Copyright (c) 2015, AW-SOM Technologies <www.aw-som.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <asm/io.h>
|
||||
#include <nand.h>
|
||||
|
||||
/* registers */
|
||||
#define NFC_CTL 0x00000000
|
||||
#define NFC_ST 0x00000004
|
||||
#define NFC_INT 0x00000008
|
||||
#define NFC_TIMING_CTL 0x0000000C
|
||||
#define NFC_TIMING_CFG 0x00000010
|
||||
#define NFC_ADDR_LOW 0x00000014
|
||||
#define NFC_ADDR_HIGH 0x00000018
|
||||
#define NFC_SECTOR_NUM 0x0000001C
|
||||
#define NFC_CNT 0x00000020
|
||||
#define NFC_CMD 0x00000024
|
||||
#define NFC_RCMD_SET 0x00000028
|
||||
#define NFC_WCMD_SET 0x0000002C
|
||||
#define NFC_IO_DATA 0x00000030
|
||||
#define NFC_ECC_CTL 0x00000034
|
||||
#define NFC_ECC_ST 0x00000038
|
||||
#define NFC_DEBUG 0x0000003C
|
||||
#define NFC_ECC_CNT0 0x00000040
|
||||
#define NFC_ECC_CNT1 0x00000044
|
||||
#define NFC_ECC_CNT2 0x00000048
|
||||
#define NFC_ECC_CNT3 0x0000004C
|
||||
#define NFC_USER_DATA_BASE 0x00000050
|
||||
#define NFC_EFNAND_STATUS 0x00000090
|
||||
#define NFC_SPARE_AREA 0x000000A0
|
||||
#define NFC_PATTERN_ID 0x000000A4
|
||||
#define NFC_RAM0_BASE 0x00000400
|
||||
#define NFC_RAM1_BASE 0x00000800
|
||||
|
||||
#define NFC_CTL_EN (1 << 0)
|
||||
#define NFC_CTL_RESET (1 << 1)
|
||||
#define NFC_CTL_RAM_METHOD (1 << 14)
|
||||
|
||||
|
||||
#define NFC_ECC_EN (1 << 0)
|
||||
#define NFC_ECC_PIPELINE (1 << 3)
|
||||
#define NFC_ECC_EXCEPTION (1 << 4)
|
||||
#define NFC_ECC_BLOCK_SIZE (1 << 5)
|
||||
#define NFC_ECC_RANDOM_EN (1 << 9)
|
||||
#define NFC_ECC_RANDOM_DIRECTION (1 << 10)
|
||||
|
||||
|
||||
#define NFC_ADDR_NUM_OFFSET 16
|
||||
#define NFC_SEND_ADR (1 << 19)
|
||||
#define NFC_ACCESS_DIR (1 << 20)
|
||||
#define NFC_DATA_TRANS (1 << 21)
|
||||
#define NFC_SEND_CMD1 (1 << 22)
|
||||
#define NFC_WAIT_FLAG (1 << 23)
|
||||
#define NFC_SEND_CMD2 (1 << 24)
|
||||
#define NFC_SEQ (1 << 25)
|
||||
#define NFC_DATA_SWAP_METHOD (1 << 26)
|
||||
#define NFC_ROW_AUTO_INC (1 << 27)
|
||||
#define NFC_SEND_CMD3 (1 << 28)
|
||||
#define NFC_SEND_CMD4 (1 << 29)
|
||||
|
||||
#define NFC_CMD_INT_FLAG (1 << 1)
|
||||
|
||||
#define NFC_READ_CMD_OFFSET 0
|
||||
#define NFC_RANDOM_READ_CMD0_OFFSET 8
|
||||
#define NFC_RANDOM_READ_CMD1_OFFSET 16
|
||||
|
||||
#define NFC_CMD_RNDOUTSTART 0xE0
|
||||
#define NFC_CMD_RNDOUT 0x05
|
||||
#define NFC_CMD_READSTART 0x30
|
||||
|
||||
|
||||
#define NFC_PAGE_CMD (2 << 30)
|
||||
|
||||
#define SUNXI_DMA_CFG_REG0 0x300
|
||||
#define SUNXI_DMA_SRC_START_ADDR_REG0 0x304
|
||||
#define SUNXI_DMA_DEST_START_ADDRR_REG0 0x308
|
||||
#define SUNXI_DMA_DDMA_BC_REG0 0x30C
|
||||
#define SUNXI_DMA_DDMA_PARA_REG0 0x318
|
||||
|
||||
#define SUNXI_DMA_DDMA_CFG_REG_LOADING (1 << 31)
|
||||
#define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
|
||||
#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
|
||||
#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
|
||||
#define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
|
||||
|
||||
#define SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC (0x0F << 0)
|
||||
#define SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE (0x7F << 8)
|
||||
|
||||
/* minimal "boot0" style NAND support for Allwinner A20 */
|
||||
|
||||
/* temporary buffer in internal ram */
|
||||
unsigned char temp_buf[CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE]
|
||||
__aligned(0x10) __section(".text#");
|
||||
|
||||
/* random seed used by linux */
|
||||
const uint16_t random_seed[128] = {
|
||||
0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
|
||||
0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
|
||||
0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
|
||||
0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
|
||||
0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
|
||||
0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
|
||||
0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
|
||||
0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
|
||||
0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
|
||||
0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
|
||||
0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
|
||||
0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
|
||||
0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
|
||||
0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
|
||||
0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
|
||||
0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
|
||||
};
|
||||
|
||||
/* random seed used for syndrome calls */
|
||||
const uint16_t random_seed_syndrome = 0x4a80;
|
||||
|
||||
#define MAX_RETRIES 10
|
||||
|
||||
static int check_value_inner(int offset, int expected_bits,
|
||||
int max_number_of_retries, int negation)
|
||||
{
|
||||
int retries = 0;
|
||||
do {
|
||||
int val = readl(offset) & expected_bits;
|
||||
if (negation ? !val : val)
|
||||
return 1;
|
||||
mdelay(1);
|
||||
retries++;
|
||||
} while (retries < max_number_of_retries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_value(int offset, int expected_bits,
|
||||
int max_number_of_retries)
|
||||
{
|
||||
return check_value_inner(offset, expected_bits,
|
||||
max_number_of_retries, 0);
|
||||
}
|
||||
|
||||
static inline int check_value_negated(int offset, int unexpected_bits,
|
||||
int max_number_of_retries)
|
||||
{
|
||||
return check_value_inner(offset, unexpected_bits,
|
||||
max_number_of_retries, 1);
|
||||
}
|
||||
|
||||
void nand_init(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = readl(SUNXI_NFC_BASE + NFC_CTL);
|
||||
/* enable and reset CTL */
|
||||
writel(val | NFC_CTL_EN | NFC_CTL_RESET,
|
||||
SUNXI_NFC_BASE + NFC_CTL);
|
||||
|
||||
if (!check_value_negated(SUNXI_NFC_BASE + NFC_CTL,
|
||||
NFC_CTL_RESET, MAX_RETRIES)) {
|
||||
printf("Couldn't initialize nand\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void nand_read_page(unsigned int real_addr, int syndrome,
|
||||
uint32_t *ecc_errors)
|
||||
{
|
||||
uint32_t val;
|
||||
int ecc_off = 0;
|
||||
uint16_t ecc_mode = 0;
|
||||
uint16_t rand_seed;
|
||||
uint32_t page;
|
||||
uint16_t column;
|
||||
uint32_t oob_offset;
|
||||
|
||||
switch (CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH) {
|
||||
case 16:
|
||||
ecc_mode = 0;
|
||||
ecc_off = 0x20;
|
||||
break;
|
||||
case 24:
|
||||
ecc_mode = 1;
|
||||
ecc_off = 0x2e;
|
||||
break;
|
||||
case 28:
|
||||
ecc_mode = 2;
|
||||
ecc_off = 0x32;
|
||||
break;
|
||||
case 32:
|
||||
ecc_mode = 3;
|
||||
ecc_off = 0x3c;
|
||||
break;
|
||||
case 40:
|
||||
ecc_mode = 4;
|
||||
ecc_off = 0x4a;
|
||||
break;
|
||||
case 48:
|
||||
ecc_mode = 4;
|
||||
ecc_off = 0x52;
|
||||
break;
|
||||
case 56:
|
||||
ecc_mode = 4;
|
||||
ecc_off = 0x60;
|
||||
break;
|
||||
case 60:
|
||||
ecc_mode = 4;
|
||||
ecc_off = 0x0;
|
||||
break;
|
||||
case 64:
|
||||
ecc_mode = 4;
|
||||
ecc_off = 0x0;
|
||||
break;
|
||||
default:
|
||||
ecc_mode = 0;
|
||||
ecc_off = 0;
|
||||
}
|
||||
|
||||
if (ecc_off == 0) {
|
||||
printf("Unsupported ECC strength (%d)!\n",
|
||||
CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH);
|
||||
return;
|
||||
}
|
||||
|
||||
/* clear temp_buf */
|
||||
memset(temp_buf, 0, CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE);
|
||||
|
||||
/* set CMD */
|
||||
writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
|
||||
SUNXI_NFC_BASE + NFC_CMD);
|
||||
|
||||
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_CMD_INT_FLAG,
|
||||
MAX_RETRIES)) {
|
||||
printf("Error while initilizing command interrupt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
page = real_addr / CONFIG_NAND_SUNXI_SPL_PAGE_SIZE;
|
||||
column = real_addr % CONFIG_NAND_SUNXI_SPL_PAGE_SIZE;
|
||||
|
||||
if (syndrome)
|
||||
column += (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
|
||||
* ecc_off;
|
||||
|
||||
/* clear ecc status */
|
||||
writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
|
||||
|
||||
/* Choose correct seed */
|
||||
if (syndrome)
|
||||
rand_seed = random_seed_syndrome;
|
||||
else
|
||||
rand_seed = random_seed[page % 128];
|
||||
|
||||
writel((rand_seed << 16) | NFC_ECC_RANDOM_EN | NFC_ECC_EN
|
||||
| NFC_ECC_PIPELINE | (ecc_mode << 12),
|
||||
SUNXI_NFC_BASE + NFC_ECC_CTL);
|
||||
|
||||
val = readl(SUNXI_NFC_BASE + NFC_CTL);
|
||||
writel(val | NFC_CTL_RAM_METHOD, SUNXI_NFC_BASE + NFC_CTL);
|
||||
|
||||
if (syndrome) {
|
||||
writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
|
||||
SUNXI_NFC_BASE + NFC_SPARE_AREA);
|
||||
} else {
|
||||
oob_offset = CONFIG_NAND_SUNXI_SPL_PAGE_SIZE
|
||||
+ (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
|
||||
* ecc_off;
|
||||
writel(oob_offset, SUNXI_NFC_BASE + NFC_SPARE_AREA);
|
||||
}
|
||||
|
||||
/* SUNXI_DMA */
|
||||
writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
|
||||
/* read from REG_IO_DATA */
|
||||
writel(SUNXI_NFC_BASE + NFC_IO_DATA,
|
||||
SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
|
||||
/* read to RAM */
|
||||
writel((uint32_t)temp_buf,
|
||||
SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
|
||||
writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC
|
||||
| SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
|
||||
SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
|
||||
writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
|
||||
SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */
|
||||
writel(SUNXI_DMA_DDMA_CFG_REG_LOADING
|
||||
| SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32
|
||||
| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32
|
||||
| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO
|
||||
| SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
|
||||
SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0);
|
||||
|
||||
writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET)
|
||||
| (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET)
|
||||
| (NFC_CMD_READSTART | NFC_READ_CMD_OFFSET), SUNXI_NFC_BASE
|
||||
+ NFC_RCMD_SET);
|
||||
writel(1, SUNXI_NFC_BASE + NFC_SECTOR_NUM);
|
||||
writel(((page & 0xFFFF) << 16) | column,
|
||||
SUNXI_NFC_BASE + NFC_ADDR_LOW);
|
||||
writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
|
||||
writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_TRANS |
|
||||
NFC_PAGE_CMD | NFC_WAIT_FLAG | (4 << NFC_ADDR_NUM_OFFSET) |
|
||||
NFC_SEND_ADR | NFC_DATA_SWAP_METHOD | (syndrome ? NFC_SEQ : 0),
|
||||
SUNXI_NFC_BASE + NFC_CMD);
|
||||
|
||||
if (!check_value(SUNXI_NFC_BASE + NFC_ST, (1 << 2),
|
||||
MAX_RETRIES)) {
|
||||
printf("Error while initializing dma interrupt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0,
|
||||
SUNXI_DMA_DDMA_CFG_REG_LOADING, MAX_RETRIES)) {
|
||||
printf("Error while waiting for dma transfer to finish\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (readl(SUNXI_NFC_BASE + NFC_ECC_ST))
|
||||
(*ecc_errors)++;
|
||||
}
|
||||
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
|
||||
{
|
||||
void *current_dest;
|
||||
uint32_t count;
|
||||
uint32_t current_count;
|
||||
uint32_t ecc_errors = 0;
|
||||
|
||||
memset(dest, 0x0, size); /* clean destination memory */
|
||||
for (current_dest = dest;
|
||||
current_dest < (dest + size);
|
||||
current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) {
|
||||
nand_read_page(offs, offs
|
||||
< CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END,
|
||||
&ecc_errors);
|
||||
count = current_dest - dest;
|
||||
|
||||
if (size - count > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
|
||||
current_count = CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
|
||||
else
|
||||
current_count = size - count;
|
||||
|
||||
memcpy(current_dest,
|
||||
temp_buf,
|
||||
current_count);
|
||||
offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
|
||||
}
|
||||
return ecc_errors ? -1 : 0;
|
||||
}
|
||||
|
||||
void nand_deselect(void) {}
|
|
@ -67,7 +67,6 @@ static int ehci_usb_remove(struct udevice *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
sunxi_usb_phy_power_off(priv->phy_index);
|
||||
sunxi_usb_phy_exit(priv->phy_index);
|
||||
|
||||
#ifdef CONFIG_SUNXI_GEN_SUN6I
|
||||
|
|
|
@ -69,7 +69,6 @@ static int ohci_usb_remove(struct udevice *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
sunxi_usb_phy_power_off(priv->phy_index);
|
||||
sunxi_usb_phy_exit(priv->phy_index);
|
||||
|
||||
#ifdef CONFIG_SUNXI_GEN_SUN6I
|
||||
|
|
|
@ -196,8 +196,6 @@ static bool enabled = false;
|
|||
|
||||
static int sunxi_musb_enable(struct musb *musb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pr_debug("%s():\n", __func__);
|
||||
|
||||
musb_ep_select(musb->mregs, 0);
|
||||
|
@ -210,17 +208,26 @@ static int sunxi_musb_enable(struct musb *musb)
|
|||
musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
|
||||
|
||||
if (is_host_enabled(musb)) {
|
||||
ret = sunxi_usb_phy_vbus_detect(0);
|
||||
if (ret == 1) {
|
||||
printf("A charger is plugged into the OTG: ");
|
||||
return -ENODEV;
|
||||
int id = sunxi_usb_phy_id_detect(0);
|
||||
|
||||
if (id == 1 && sunxi_usb_phy_power_is_on(0))
|
||||
sunxi_usb_phy_power_off(0);
|
||||
|
||||
if (!sunxi_usb_phy_power_is_on(0)) {
|
||||
int vbus = sunxi_usb_phy_vbus_detect(0);
|
||||
if (vbus == 1) {
|
||||
printf("A charger is plugged into the OTG: ");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
ret = sunxi_usb_phy_id_detect(0);
|
||||
if (ret == 1) {
|
||||
|
||||
if (id == 1) {
|
||||
printf("No host cable detected: ");
|
||||
return -ENODEV;
|
||||
}
|
||||
sunxi_usb_phy_power_on(0); /* port power on */
|
||||
|
||||
if (!sunxi_usb_phy_power_is_on(0))
|
||||
sunxi_usb_phy_power_on(0);
|
||||
}
|
||||
|
||||
USBC_ForceVbusValidToHigh(musb->mregs);
|
||||
|
@ -236,9 +243,6 @@ static void sunxi_musb_disable(struct musb *musb)
|
|||
if (!enabled)
|
||||
return;
|
||||
|
||||
if (is_host_enabled(musb))
|
||||
sunxi_usb_phy_power_off(0); /* port power off */
|
||||
|
||||
USBC_ForceVbusValidToLow(musb->mregs);
|
||||
mdelay(200); /* Wait for the current session to timeout */
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Display driver for Allwinner SoCs.
|
||||
*
|
||||
* (C) Copyright 2013-2014 Luc Verhaegen <libv@skynet.be>
|
||||
* (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
|
||||
* (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
@ -40,8 +40,12 @@ enum sunxi_monitor {
|
|||
sunxi_monitor_hdmi,
|
||||
sunxi_monitor_lcd,
|
||||
sunxi_monitor_vga,
|
||||
sunxi_monitor_composite_pal,
|
||||
sunxi_monitor_composite_ntsc,
|
||||
sunxi_monitor_composite_pal_m,
|
||||
sunxi_monitor_composite_pal_nc,
|
||||
};
|
||||
#define SUNXI_MONITOR_LAST sunxi_monitor_vga
|
||||
#define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
|
||||
|
||||
struct sunxi_display {
|
||||
GraphicDevice graphic_device;
|
||||
|
@ -50,6 +54,12 @@ struct sunxi_display {
|
|||
unsigned int fb_size;
|
||||
} sunxi_display;
|
||||
|
||||
const struct ctfb_res_modes composite_video_modes[2] = {
|
||||
/* x y hz pixclk ps/kHz le ri up lo hs vs s vmode */
|
||||
{ 720, 576, 50, 37037, 27000, 137, 5, 20, 27, 2, 2, 0, FB_VMODE_INTERLACED },
|
||||
{ 720, 480, 60, 37037, 27000, 116, 20, 16, 27, 2, 2, 0, FB_VMODE_INTERLACED },
|
||||
};
|
||||
|
||||
#ifdef CONFIG_VIDEO_HDMI
|
||||
|
||||
/*
|
||||
|
@ -390,6 +400,25 @@ static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
|
|||
static void sunxi_frontend_enable(void) {}
|
||||
#endif
|
||||
|
||||
static bool sunxi_is_composite(void)
|
||||
{
|
||||
switch (sunxi_display.monitor) {
|
||||
case sunxi_monitor_none:
|
||||
case sunxi_monitor_dvi:
|
||||
case sunxi_monitor_hdmi:
|
||||
case sunxi_monitor_lcd:
|
||||
case sunxi_monitor_vga:
|
||||
return false;
|
||||
case sunxi_monitor_composite_pal:
|
||||
case sunxi_monitor_composite_ntsc:
|
||||
case sunxi_monitor_composite_pal_m:
|
||||
case sunxi_monitor_composite_pal_nc:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; /* Never reached */
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the entity that mixes and matches the different layers and inputs.
|
||||
* Allwinner calls it the back-end, but i like composer better.
|
||||
|
@ -423,11 +452,18 @@ static void sunxi_composer_init(void)
|
|||
setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE);
|
||||
}
|
||||
|
||||
static u32 sunxi_rgb2yuv_coef[12] = {
|
||||
0x00000107, 0x00000204, 0x00000064, 0x00000108,
|
||||
0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
|
||||
0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
|
||||
};
|
||||
|
||||
static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
|
||||
unsigned int address)
|
||||
{
|
||||
struct sunxi_de_be_reg * const de_be =
|
||||
(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
|
||||
int i;
|
||||
|
||||
sunxi_frontend_mode_set(mode, address);
|
||||
|
||||
|
@ -445,6 +481,18 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
|
|||
writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl);
|
||||
|
||||
setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE);
|
||||
if (mode->vmode == FB_VMODE_INTERLACED)
|
||||
setbits_le32(&de_be->mode,
|
||||
SUNXI_DE_BE_MODE_DEFLICKER_ENABLE |
|
||||
SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
|
||||
|
||||
if (sunxi_is_composite()) {
|
||||
writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
|
||||
&de_be->output_color_ctrl);
|
||||
for (i = 0; i < 12; i++)
|
||||
writel(sunxi_rgb2yuv_coef[i],
|
||||
&de_be->output_color_coef[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void sunxi_composer_enable(void)
|
||||
|
@ -535,6 +583,9 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock,
|
|||
(best_double ? CCM_LCD_CH1_CTRL_PLL3_2X :
|
||||
CCM_LCD_CH1_CTRL_PLL3) |
|
||||
CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg);
|
||||
if (sunxi_is_composite())
|
||||
setbits_le32(&ccm->lcd0_ch1_clk_cfg,
|
||||
CCM_LCD_CH1_CTRL_HALF_SCLK1);
|
||||
}
|
||||
|
||||
*clk_div = best_m;
|
||||
|
@ -663,11 +714,16 @@ static void sunxi_lcdc_backlight_enable(void)
|
|||
gpio_direction_output(pin, PWM_ON);
|
||||
}
|
||||
|
||||
static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode)
|
||||
static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon)
|
||||
{
|
||||
int delay;
|
||||
|
||||
delay = mode->lower_margin + mode->vsync_len + mode->upper_margin - 2;
|
||||
delay = mode->lower_margin + mode->vsync_len + mode->upper_margin;
|
||||
if (mode->vmode == FB_VMODE_INTERLACED)
|
||||
delay /= 2;
|
||||
if (tcon == 1)
|
||||
delay -= 2;
|
||||
|
||||
return (delay > 30) ? 30 : delay;
|
||||
}
|
||||
|
||||
|
@ -692,7 +748,7 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
|
|||
clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
|
||||
SUNXI_LCDC_CTRL_IO_MAP_TCON0);
|
||||
|
||||
clk_delay = sunxi_lcdc_get_clk_delay(mode);
|
||||
clk_delay = sunxi_lcdc_get_clk_delay(mode, 0);
|
||||
writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
|
||||
SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
|
||||
|
||||
|
@ -757,28 +813,33 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
|
|||
writel(0, &lcdc->tcon0_io_tristate);
|
||||
}
|
||||
|
||||
#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA
|
||||
#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
|
||||
static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
|
||||
int *clk_div, int *clk_double,
|
||||
bool use_portd_hvsync)
|
||||
{
|
||||
struct sunxi_lcdc_reg * const lcdc =
|
||||
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
|
||||
int bp, clk_delay, total, val;
|
||||
int bp, clk_delay, total, val, yres;
|
||||
|
||||
/* Use tcon1 */
|
||||
clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
|
||||
SUNXI_LCDC_CTRL_IO_MAP_TCON1);
|
||||
|
||||
clk_delay = sunxi_lcdc_get_clk_delay(mode);
|
||||
clk_delay = sunxi_lcdc_get_clk_delay(mode, 1);
|
||||
writel(SUNXI_LCDC_TCON1_CTRL_ENABLE |
|
||||
((mode->vmode == FB_VMODE_INTERLACED) ?
|
||||
SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) |
|
||||
SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl);
|
||||
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
|
||||
yres = mode->yres;
|
||||
if (mode->vmode == FB_VMODE_INTERLACED)
|
||||
yres /= 2;
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
|
||||
&lcdc->tcon1_timing_source);
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
|
||||
&lcdc->tcon1_timing_scale);
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
|
||||
&lcdc->tcon1_timing_out);
|
||||
|
||||
bp = mode->hsync_len + mode->left_margin;
|
||||
|
@ -788,6 +849,8 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
|
|||
|
||||
bp = mode->vsync_len + mode->upper_margin;
|
||||
total = mode->yres + mode->lower_margin + bp;
|
||||
if (mode->vmode == FB_VMODE_NONINTERLACED)
|
||||
total *= 2;
|
||||
writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) |
|
||||
SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v);
|
||||
|
||||
|
@ -811,7 +874,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
|
|||
}
|
||||
sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double);
|
||||
}
|
||||
#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA */
|
||||
#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
|
||||
|
||||
#ifdef CONFIG_VIDEO_HDMI
|
||||
|
||||
|
@ -925,9 +988,9 @@ static void sunxi_hdmi_enable(void)
|
|||
|
||||
#endif /* CONFIG_VIDEO_HDMI */
|
||||
|
||||
#ifdef CONFIG_VIDEO_VGA
|
||||
#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
|
||||
|
||||
static void sunxi_vga_mode_set(void)
|
||||
static void sunxi_tvencoder_mode_set(void)
|
||||
{
|
||||
struct sunxi_ccm_reg * const ccm =
|
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
|
@ -937,16 +1000,75 @@ static void sunxi_vga_mode_set(void)
|
|||
/* Clock on */
|
||||
setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
|
||||
|
||||
/* Set TVE in VGA mode */
|
||||
writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
|
||||
writel(SUNXI_TVE_GCTRL_CFG0_VGA, &tve->cfg0);
|
||||
writel(SUNXI_TVE_GCTRL_DAC_CFG0_VGA, &tve->dac_cfg0);
|
||||
writel(SUNXI_TVE_GCTRL_UNKNOWN1_VGA, &tve->unknown1);
|
||||
switch (sunxi_display.monitor) {
|
||||
case sunxi_monitor_vga:
|
||||
writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
|
||||
writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0);
|
||||
writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
|
||||
writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
|
||||
break;
|
||||
case sunxi_monitor_composite_pal_nc:
|
||||
writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
|
||||
/* Fall through */
|
||||
case sunxi_monitor_composite_pal:
|
||||
writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
|
||||
writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
|
||||
writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
|
||||
writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
|
||||
writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
|
||||
writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
|
||||
writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level);
|
||||
writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
|
||||
writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
|
||||
writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
|
||||
writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
|
||||
writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
|
||||
writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
|
||||
writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
|
||||
writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
|
||||
writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
|
||||
break;
|
||||
case sunxi_monitor_composite_pal_m:
|
||||
writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
|
||||
writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
|
||||
/* Fall through */
|
||||
case sunxi_monitor_composite_ntsc:
|
||||
writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
|
||||
SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
|
||||
writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
|
||||
writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
|
||||
writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
|
||||
writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
|
||||
writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
|
||||
writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level);
|
||||
writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
|
||||
writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
|
||||
writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
|
||||
writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
|
||||
writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
|
||||
writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
|
||||
writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
|
||||
writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
|
||||
writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
|
||||
writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
|
||||
writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
|
||||
break;
|
||||
case sunxi_monitor_none:
|
||||
case sunxi_monitor_dvi:
|
||||
case sunxi_monitor_hdmi:
|
||||
case sunxi_monitor_lcd:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sunxi_vga_enable(void)
|
||||
static void sunxi_tvencoder_enable(void)
|
||||
{
|
||||
struct sunxi_tve_reg * const tve =
|
||||
(struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
|
||||
|
@ -954,7 +1076,7 @@ static void sunxi_vga_enable(void)
|
|||
setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_VIDEO_VGA */
|
||||
#endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */
|
||||
|
||||
static void sunxi_drc_init(void)
|
||||
{
|
||||
|
@ -1069,16 +1191,29 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
|
|||
#ifdef CONFIG_VIDEO_VGA
|
||||
sunxi_composer_mode_set(mode, address);
|
||||
sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
|
||||
sunxi_vga_mode_set();
|
||||
sunxi_tvencoder_mode_set();
|
||||
sunxi_composer_enable();
|
||||
sunxi_lcdc_enable();
|
||||
sunxi_vga_enable();
|
||||
sunxi_tvencoder_enable();
|
||||
#elif defined CONFIG_VIDEO_VGA_VIA_LCD
|
||||
sunxi_composer_mode_set(mode, address);
|
||||
sunxi_lcdc_tcon0_mode_set(mode, true);
|
||||
sunxi_composer_enable();
|
||||
sunxi_lcdc_enable();
|
||||
sunxi_vga_external_dac_enable();
|
||||
#endif
|
||||
break;
|
||||
case sunxi_monitor_composite_pal:
|
||||
case sunxi_monitor_composite_ntsc:
|
||||
case sunxi_monitor_composite_pal_m:
|
||||
case sunxi_monitor_composite_pal_nc:
|
||||
#ifdef CONFIG_VIDEO_COMPOSITE
|
||||
sunxi_composer_mode_set(mode, address);
|
||||
sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
|
||||
sunxi_tvencoder_mode_set();
|
||||
sunxi_composer_enable();
|
||||
sunxi_lcdc_enable();
|
||||
sunxi_tvencoder_enable();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
@ -1087,11 +1222,15 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
|
|||
static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
|
||||
{
|
||||
switch (monitor) {
|
||||
case sunxi_monitor_none: return "none";
|
||||
case sunxi_monitor_dvi: return "dvi";
|
||||
case sunxi_monitor_hdmi: return "hdmi";
|
||||
case sunxi_monitor_lcd: return "lcd";
|
||||
case sunxi_monitor_vga: return "vga";
|
||||
case sunxi_monitor_none: return "none";
|
||||
case sunxi_monitor_dvi: return "dvi";
|
||||
case sunxi_monitor_hdmi: return "hdmi";
|
||||
case sunxi_monitor_lcd: return "lcd";
|
||||
case sunxi_monitor_vga: return "vga";
|
||||
case sunxi_monitor_composite_pal: return "composite-pal";
|
||||
case sunxi_monitor_composite_ntsc: return "composite-ntsc";
|
||||
case sunxi_monitor_composite_pal_m: return "composite-pal-m";
|
||||
case sunxi_monitor_composite_pal_nc: return "composite-pal-nc";
|
||||
}
|
||||
return NULL; /* never reached */
|
||||
}
|
||||
|
@ -1101,6 +1240,54 @@ ulong board_get_usable_ram_top(ulong total_size)
|
|||
return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
|
||||
}
|
||||
|
||||
static bool sunxi_has_hdmi(void)
|
||||
{
|
||||
#ifdef CONFIG_VIDEO_HDMI
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool sunxi_has_lcd(void)
|
||||
{
|
||||
char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
|
||||
|
||||
return lcd_mode[0] != 0;
|
||||
}
|
||||
|
||||
static bool sunxi_has_vga(void)
|
||||
{
|
||||
#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool sunxi_has_composite(void)
|
||||
{
|
||||
#ifdef CONFIG_VIDEO_COMPOSITE
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
|
||||
{
|
||||
if (allow_hdmi && sunxi_has_hdmi())
|
||||
return sunxi_monitor_dvi;
|
||||
else if (sunxi_has_lcd())
|
||||
return sunxi_monitor_lcd;
|
||||
else if (sunxi_has_vga())
|
||||
return sunxi_monitor_vga;
|
||||
else if (sunxi_has_composite())
|
||||
return sunxi_monitor_composite_pal;
|
||||
else
|
||||
return sunxi_monitor_none;
|
||||
}
|
||||
|
||||
void *video_hw_init(void)
|
||||
{
|
||||
static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
|
||||
|
@ -1122,12 +1309,8 @@ void *video_hw_init(void)
|
|||
hpd = video_get_option_int(options, "hpd", 1);
|
||||
hpd_delay = video_get_option_int(options, "hpd_delay", 500);
|
||||
edid = video_get_option_int(options, "edid", 1);
|
||||
sunxi_display.monitor = sunxi_monitor_dvi;
|
||||
#elif defined CONFIG_VIDEO_VGA_VIA_LCD
|
||||
sunxi_display.monitor = sunxi_monitor_vga;
|
||||
#else
|
||||
sunxi_display.monitor = sunxi_monitor_lcd;
|
||||
#endif
|
||||
sunxi_display.monitor = sunxi_get_default_mon(true);
|
||||
video_get_option_string(options, "monitor", mon, sizeof(mon),
|
||||
sunxi_get_mon_desc(sunxi_display.monitor));
|
||||
for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
|
||||
|
@ -1152,16 +1335,7 @@ void *video_hw_init(void)
|
|||
mode = &custom;
|
||||
} else if (hpd) {
|
||||
sunxi_hdmi_shutdown();
|
||||
/* Fallback to lcd / vga / none */
|
||||
if (lcd_mode[0]) {
|
||||
sunxi_display.monitor = sunxi_monitor_lcd;
|
||||
} else {
|
||||
#if defined CONFIG_VIDEO_VGA_VIA_LCD || defined CONFIG_VIDEO_VGA
|
||||
sunxi_display.monitor = sunxi_monitor_vga;
|
||||
#else
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
#endif
|
||||
}
|
||||
sunxi_display.monitor = sunxi_get_default_mon(false);
|
||||
} /* else continue with hdmi/dvi without a cable connected */
|
||||
}
|
||||
#endif
|
||||
|
@ -1171,39 +1345,45 @@ void *video_hw_init(void)
|
|||
return NULL;
|
||||
case sunxi_monitor_dvi:
|
||||
case sunxi_monitor_hdmi:
|
||||
#ifdef CONFIG_VIDEO_HDMI
|
||||
break;
|
||||
#else
|
||||
printf("HDMI/DVI not supported on this board\n");
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
return NULL;
|
||||
#endif
|
||||
case sunxi_monitor_lcd:
|
||||
if (lcd_mode[0]) {
|
||||
sunxi_display.depth = video_get_params(&custom, lcd_mode);
|
||||
mode = &custom;
|
||||
break;
|
||||
if (!sunxi_has_hdmi()) {
|
||||
printf("HDMI/DVI not supported on this board\n");
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
return NULL;
|
||||
}
|
||||
printf("LCD not supported on this board\n");
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
return NULL;
|
||||
break;
|
||||
case sunxi_monitor_lcd:
|
||||
if (!sunxi_has_lcd()) {
|
||||
printf("LCD not supported on this board\n");
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
return NULL;
|
||||
}
|
||||
sunxi_display.depth = video_get_params(&custom, lcd_mode);
|
||||
mode = &custom;
|
||||
break;
|
||||
case sunxi_monitor_vga:
|
||||
#if defined CONFIG_VIDEO_VGA_VIA_LCD || defined CONFIG_VIDEO_VGA
|
||||
if (!sunxi_has_vga()) {
|
||||
printf("VGA not supported on this board\n");
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
return NULL;
|
||||
}
|
||||
sunxi_display.depth = 18;
|
||||
break;
|
||||
#else
|
||||
printf("VGA not supported on this board\n");
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mode->vmode != FB_VMODE_NONINTERLACED) {
|
||||
printf("Only non-interlaced modes supported, falling back to 1024x768\n");
|
||||
mode = &res_mode_init[RES_MODE_1024x768];
|
||||
} else {
|
||||
printf("Setting up a %dx%d %s console\n", mode->xres,
|
||||
mode->yres, sunxi_get_mon_desc(sunxi_display.monitor));
|
||||
case sunxi_monitor_composite_pal:
|
||||
case sunxi_monitor_composite_ntsc:
|
||||
case sunxi_monitor_composite_pal_m:
|
||||
case sunxi_monitor_composite_pal_nc:
|
||||
if (!sunxi_has_composite()) {
|
||||
printf("Composite video not supported on this board\n");
|
||||
sunxi_display.monitor = sunxi_monitor_none;
|
||||
return NULL;
|
||||
}
|
||||
if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
|
||||
sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
|
||||
mode = &composite_video_modes[0];
|
||||
else
|
||||
mode = &composite_video_modes[1];
|
||||
sunxi_display.depth = 24;
|
||||
break;
|
||||
}
|
||||
|
||||
sunxi_display.fb_size =
|
||||
|
@ -1215,6 +1395,10 @@ void *video_hw_init(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
printf("Setting up a %dx%d%s %s console\n", mode->xres, mode->yres,
|
||||
(mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
|
||||
sunxi_get_mon_desc(sunxi_display.monitor));
|
||||
|
||||
gd->fb_base = gd->bd->bi_dram[0].start +
|
||||
gd->bd->bi_dram[0].size - sunxi_display.fb_size;
|
||||
sunxi_engines_init();
|
||||
|
@ -1268,6 +1452,12 @@ int sunxi_simplefb_setup(void *blob)
|
|||
pipeline = PIPELINE_PREFIX "de_be0-lcd0";
|
||||
#endif
|
||||
break;
|
||||
case sunxi_monitor_composite_pal:
|
||||
case sunxi_monitor_composite_ntsc:
|
||||
case sunxi_monitor_composite_pal_m:
|
||||
case sunxi_monitor_composite_pal_nc:
|
||||
pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
|
||||
break;
|
||||
}
|
||||
|
||||
/* Find a prefilled simpefb node, matching out pipeline config */
|
||||
|
|
|
@ -139,6 +139,16 @@
|
|||
#define CONFIG_INITRD_TAG
|
||||
#define CONFIG_SERIAL_TAG
|
||||
|
||||
#if defined(CONFIG_SPL_NAND_SUNXI)
|
||||
#define CONFIG_SPL_NAND_DRIVERS
|
||||
#define CONFIG_SPL_NAND_SUPPORT
|
||||
|
||||
#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x008000
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* mmc config */
|
||||
#if !defined(CONFIG_UART0_PORT_F)
|
||||
#define CONFIG_MMC
|
||||
|
@ -252,6 +262,7 @@ extern int soft_i2c_gpio_scl;
|
|||
#define CONFIG_CONS_INDEX 1 /* UART0 */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_REQUIRE_SERIAL_CONSOLE
|
||||
#if CONFIG_CONS_INDEX == 1
|
||||
#ifdef CONFIG_MACH_SUN9I
|
||||
#define OF_STDOUT_PATH "/soc/serial@07000000:115200"
|
||||
|
@ -267,6 +278,7 @@ extern int soft_i2c_gpio_scl;
|
|||
#else
|
||||
#error Unsupported console port nr. Please fix stdout-path in sunxi-common.h.
|
||||
#endif
|
||||
#endif /* ifdef CONFIG_REQUIRE_SERIAL_CONSOLE */
|
||||
|
||||
/* GPIO */
|
||||
#define CONFIG_SUNXI_GPIO
|
||||
|
|
Loading…
Reference in a new issue