Merge branch 'for-next/omap'
This commit is contained in:
commit
da05cbd69a
|
@ -48,8 +48,7 @@ static noinline void archosg9_init_lowlevel(void)
|
|||
|
||||
set_muxconf_regs();
|
||||
|
||||
/* Set VCORE1 = 1.3 V, VCORE2 = VCORE3 = 1.21V */
|
||||
omap4_scale_vcores(TPS62361_VSEL0_GPIO);
|
||||
omap4460_scale_vcores(TPS62361_VSEL0_GPIO, 1380);
|
||||
|
||||
/* Enable all clocks */
|
||||
omap4_enable_all_clocks();
|
||||
|
|
|
@ -52,6 +52,7 @@ static void noinline panda_init_lowlevel(void)
|
|||
struct dpll_param per = OMAP4_PER_DPLL_PARAM_38M4;
|
||||
struct dpll_param abe = OMAP4_ABE_DPLL_PARAM_38M4;
|
||||
struct dpll_param usb = OMAP4_USB_DPLL_PARAM_38M4;
|
||||
unsigned int rev = omap4_revision();
|
||||
|
||||
writel(CM_SYS_CLKSEL_38M4, CM_SYS_CLKSEL);
|
||||
|
||||
|
@ -69,8 +70,10 @@ static void noinline panda_init_lowlevel(void)
|
|||
|
||||
omap4_ddr_init(&ddr_regs_400_mhz_2cs, &core);
|
||||
|
||||
/* Set VCORE1 = 1.3 V, VCORE2 = VCORE3 = 1.21V */
|
||||
omap4_scale_vcores(TPS62361_VSEL0_GPIO);
|
||||
if (rev < OMAP4460_ES1_0)
|
||||
omap4430_scale_vcores();
|
||||
else
|
||||
omap4460_scale_vcores(TPS62361_VSEL0_GPIO, 1210);
|
||||
}
|
||||
|
||||
void barebox_arm_reset_vector(void)
|
||||
|
|
|
@ -67,6 +67,7 @@ static void noinline pcm049_init_lowlevel(void)
|
|||
struct dpll_param per = OMAP4_PER_DPLL_PARAM_19M2;
|
||||
struct dpll_param abe = OMAP4_ABE_DPLL_PARAM_19M2;
|
||||
struct dpll_param usb = OMAP4_USB_DPLL_PARAM_19M2;
|
||||
unsigned int rev = omap4_revision();
|
||||
|
||||
set_muxconf_regs();
|
||||
|
||||
|
@ -77,12 +78,15 @@ static void noinline pcm049_init_lowlevel(void)
|
|||
#endif
|
||||
|
||||
/* Set VCORE1 = 1.3 V, VCORE2 = VCORE3 = 1.21V */
|
||||
omap4_scale_vcores(TPS62361_VSEL0_GPIO);
|
||||
if (rev < OMAP4460_ES1_0)
|
||||
omap4430_scale_vcores();
|
||||
else
|
||||
omap4460_scale_vcores(TPS62361_VSEL0_GPIO, 1320);
|
||||
|
||||
writel(CM_SYS_CLKSEL_19M2, CM_SYS_CLKSEL);
|
||||
|
||||
/* Configure all DPLL's at 100% OPP */
|
||||
if (omap4_revision() < OMAP4460_ES1_0)
|
||||
if (rev < OMAP4460_ES1_0)
|
||||
omap4_configure_mpu_dpll(&mpu44xx);
|
||||
else
|
||||
omap4_configure_mpu_dpll(&mpu4460);
|
||||
|
|
|
@ -19,13 +19,21 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <io.h>
|
||||
#include <sizes.h>
|
||||
#include <ns16550.h>
|
||||
#include <asm/armlinux.h>
|
||||
#include <generated/mach-types.h>
|
||||
#include <linux/phy.h>
|
||||
#include <mach/am33xx-devices.h>
|
||||
#include <mach/am33xx-generic.h>
|
||||
#include <mach/am33xx-mux.h>
|
||||
#include <mach/am33xx-silicon.h>
|
||||
#include <mach/cpsw.h>
|
||||
#include <spi/spi.h>
|
||||
#include <spi/flash.h>
|
||||
#include <i2c/i2c.h>
|
||||
#include <i2c/at24.h>
|
||||
|
||||
#include "mux.h"
|
||||
|
||||
|
@ -52,12 +60,91 @@ static int pcm051_mem_init(void)
|
|||
}
|
||||
mem_initcall(pcm051_mem_init);
|
||||
|
||||
static struct flash_platform_data pcm051_spi_flash = {
|
||||
.name = "nor",
|
||||
.type = "w25q64",
|
||||
};
|
||||
|
||||
/*
|
||||
* SPI Flash works at 80Mhz however the SPI controller runs with 48MHz.
|
||||
* So setup Max speed to be less than the controller speed.
|
||||
*/
|
||||
static struct spi_board_info pcm051_spi_board_info[] = {
|
||||
{
|
||||
.name = "m25p80",
|
||||
.platform_data = &pcm051_spi_flash,
|
||||
.max_speed_hz = 24000000,
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cpsw_slave_data cpsw_slaves[] = {
|
||||
{
|
||||
.phy_id = 0,
|
||||
.phy_if = PHY_INTERFACE_MODE_RMII,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cpsw_platform_data cpsw_data = {
|
||||
.slave_data = cpsw_slaves,
|
||||
.num_slaves = ARRAY_SIZE(cpsw_slaves),
|
||||
};
|
||||
|
||||
static struct i2c_board_info i2c0_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("24c32", 0x52),
|
||||
},
|
||||
};
|
||||
|
||||
static void pcm051_spi_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
am33xx_enable_spi0_pin_mux();
|
||||
|
||||
ret = spi_register_board_info(pcm051_spi_board_info,
|
||||
ARRAY_SIZE(pcm051_spi_board_info));
|
||||
am33xx_add_spi0();
|
||||
}
|
||||
|
||||
static void pcm051_eth_init(void)
|
||||
{
|
||||
am33xx_register_ethaddr(0, 0);
|
||||
|
||||
writel(0x49, AM33XX_MAC_MII_SEL);
|
||||
|
||||
am33xx_enable_rmii1_pin_mux();
|
||||
|
||||
am33xx_add_cpsw(&cpsw_data);
|
||||
}
|
||||
|
||||
static void pcm051_i2c_init(void)
|
||||
{
|
||||
am33xx_enable_i2c0_pin_mux();
|
||||
|
||||
i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
|
||||
|
||||
am33xx_add_i2c0(NULL);
|
||||
}
|
||||
|
||||
static int pcm051_devices_init(void)
|
||||
{
|
||||
pcm051_enable_mmc0_pin_mux();
|
||||
|
||||
am33xx_add_mmc0(NULL);
|
||||
|
||||
pcm051_spi_init();
|
||||
pcm051_eth_init();
|
||||
pcm051_i2c_init();
|
||||
|
||||
devfs_add_partition("nor0", 0x00000, SZ_128K,
|
||||
DEVFS_PARTITION_FIXED, "xload");
|
||||
devfs_add_partition("nor0", SZ_128K, SZ_512K,
|
||||
DEVFS_PARTITION_FIXED, "self0");
|
||||
devfs_add_partition("nor0", SZ_128K + SZ_512K, SZ_128K,
|
||||
DEVFS_PARTITION_FIXED, "env0");
|
||||
|
||||
armlinux_set_bootparams((void *)(AM33XX_DRAM_ADDR_SPACE_START + 0x100));
|
||||
armlinux_set_architecture(MACH_TYPE_PCM051);
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ "$1" = menu ]; then
|
||||
boot-menu-add-entry "$0" "SPI NOR Flash"
|
||||
exit
|
||||
fi
|
||||
|
||||
global.bootm.image="/dev/nor0.kernel"
|
||||
|
||||
# Use rootfs form SD-Card for now as rootfs partition < 4MB
|
||||
global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2 rootfstype=ext3 rootwait"
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ "$1" = menu ]; then
|
||||
init-menu-add-entry "$0" "NOR partitions"
|
||||
exit
|
||||
fi
|
||||
|
||||
mtdparts="128k(nor0.xload),512k(nor0.barebox),128k(nor0.bareboxenv),4M(nor0.kernel),-(nor0.root)"
|
||||
kernelname="spi_flash"
|
||||
|
||||
mtdparts-add -d nor0 -k ${kernelname} -p ${mtdparts}
|
||||
|
|
@ -52,18 +52,21 @@ static noinline void pcaaxl2_init_lowlevel(void)
|
|||
struct dpll_param per = OMAP4_PER_DPLL_PARAM_19M2;
|
||||
struct dpll_param abe = OMAP4_ABE_DPLL_PARAM_19M2;
|
||||
struct dpll_param usb = OMAP4_USB_DPLL_PARAM_19M2;
|
||||
unsigned int rev = omap4_revision();
|
||||
|
||||
set_muxconf_regs();
|
||||
|
||||
omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
|
||||
|
||||
/* Set VCORE1 = 1.3 V, VCORE2 = VCORE3 = 1.21V */
|
||||
omap4_scale_vcores(TPS62361_VSEL0_GPIO);
|
||||
if (rev < OMAP4460_ES1_0)
|
||||
omap4430_scale_vcores();
|
||||
else
|
||||
omap4460_scale_vcores(TPS62361_VSEL0_GPIO, 1320);
|
||||
|
||||
writel(CM_SYS_CLKSEL_19M2, CM_SYS_CLKSEL);
|
||||
|
||||
/* Configure all DPLL's at 100% OPP */
|
||||
if (omap4_revision() < OMAP4460_ES1_0)
|
||||
if (rev < OMAP4460_ES1_0)
|
||||
omap4_configure_mpu_dpll(&mpu44xx);
|
||||
else
|
||||
omap4_configure_mpu_dpll(&mpu4460);
|
||||
|
|
|
@ -42,15 +42,25 @@ CONFIG_CMD_TIMEOUT=y
|
|||
CONFIG_CMD_PARTITION=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_UNCOMPRESS=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_DHCP=y
|
||||
CONFIG_NET_NFS=y
|
||||
CONFIG_NET_PING=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y
|
||||
# CONFIG_SPI is not set
|
||||
CONFIG_DRIVER_NET_CPSW=y
|
||||
CONFIG_DRIVER_SPI_OMAP3=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_OMAP=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_NAND=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_MCI=y
|
||||
CONFIG_MCI_STARTUP=y
|
||||
CONFIG_MCI_OMAP_HSMMC=y
|
||||
CONFIG_EEPROM_AT24=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_FS_FAT_WRITE=y
|
||||
CONFIG_FS_FAT_LFN=y
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
obj-$(CONFIG_ARCH_OMAP) += syslib.o omap_devices.o omap_generic.o
|
||||
obj-$(CONFIG_ARCH_OMAP) += syslib.o omap_devices.o omap_generic.o omap_fb.o
|
||||
pbl-$(CONFIG_ARCH_OMAP) += syslib.o
|
||||
obj-$(CONFIG_OMAP_CLOCK_SOURCE_S32K) += s32k_clksource.o
|
||||
obj-$(CONFIG_OMAP_CLOCK_SOURCE_DMTIMER0) += dmtimer0.o
|
||||
|
|
|
@ -314,3 +314,8 @@ void am33xx_enable_mmc0_pin_mux(void)
|
|||
{
|
||||
configure_module_pin_mux(mmc0_pin_mux);
|
||||
}
|
||||
|
||||
void am33xx_enable_spi0_pin_mux(void)
|
||||
{
|
||||
configure_module_pin_mux(spi0_pin_mux);
|
||||
}
|
||||
|
|
|
@ -37,4 +37,38 @@ static inline struct device_d *am33xx_add_cpsw(struct cpsw_platform_data *cpsw_d
|
|||
AM335X_CPSW_BASE, SZ_32K, IORESOURCE_MEM, cpsw_data);
|
||||
}
|
||||
|
||||
static inline struct device_d *am33xx_add_spi(int id, resource_size_t start)
|
||||
{
|
||||
return add_generic_device("omap3_spi", id, NULL, start + 0x100, SZ_4K - 0x100,
|
||||
IORESOURCE_MEM, NULL);
|
||||
}
|
||||
|
||||
static inline struct device_d *am33xx_add_spi0(void)
|
||||
{
|
||||
return am33xx_add_spi(0, AM33XX_MCSPI0_BASE);
|
||||
}
|
||||
|
||||
static inline struct device_d *am33xx_add_spi1(void)
|
||||
{
|
||||
return am33xx_add_spi(1, AM33XX_MCSPI1_BASE);
|
||||
}
|
||||
|
||||
static inline struct device_d *am33xx_add_i2c0(void *pdata)
|
||||
{
|
||||
return add_generic_device("i2c-am33xx", 0, NULL, AM33XX_I2C0_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *am33xx_add_i2c1(void *pdata)
|
||||
{
|
||||
return add_generic_device("i2c-am33xx", 1, NULL, AM33XX_I2C1_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *am33xx_add_i2c2(void *pdata)
|
||||
{
|
||||
return add_generic_device("i2c-am33xx", 2, NULL, AM33XX_I2C2_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
#endif /* __MACH_OMAP3_DEVICES_H */
|
||||
|
|
|
@ -256,5 +256,6 @@ extern void am33xx_enable_i2c2_pin_mux(void);
|
|||
extern void am33xx_enable_uart0_pin_mux(void);
|
||||
extern void am33xx_enable_uart2_pin_mux(void);
|
||||
extern void am33xx_enable_mmc0_pin_mux(void);
|
||||
extern void am33xx_enable_spi0_pin_mux(void);
|
||||
|
||||
#endif /*__AM33XX_MUX_H__ */
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
#define AM33XX_DRAM_ADDR_SPACE_START 0x80000000
|
||||
#define AM33XX_DRAM_ADDR_SPACE_END 0xC0000000
|
||||
|
||||
/* I2C */
|
||||
#define AM33XX_I2C0_BASE (AM33XX_L4_WKUP_BASE + 0x20B000)
|
||||
#define AM33XX_I2C1_BASE (AM33XX_L4_PER_BASE + 0x02A000)
|
||||
#define AM33XX_I2C2_BASE (AM33XX_L4_PER_BASE + 0x19C000)
|
||||
|
||||
/* GPMC */
|
||||
#define AM33XX_GPMC_BASE 0x50000000
|
||||
|
||||
|
@ -49,6 +54,10 @@
|
|||
#define AM33XX_MMC1_BASE (AM33XX_L4_PER_BASE + 0x1D8000)
|
||||
#define AM33XX_MMCHS2_BASE 0x47810000
|
||||
|
||||
/* SPI */
|
||||
#define AM33XX_MCSPI0_BASE (AM33XX_L4_PER_BASE + 0x30000)
|
||||
#define AM33XX_MCSPI1_BASE (AM33XX_L4_PER_BASE + 0x1A0000)
|
||||
|
||||
/* DTMTimer0 */
|
||||
#define AM33XX_DMTIMER0_BASE (AM33XX_L4_WKUP_BASE + 0x205000)
|
||||
|
||||
|
|
|
@ -9,6 +9,4 @@ void omap_add_sram0(resource_size_t base, resource_size_t size);
|
|||
|
||||
struct device_d *omap_add_uart(int id, unsigned long base);
|
||||
|
||||
struct device_d *omap_add_i2c(int id, unsigned long base, void *pdata);
|
||||
|
||||
#endif /* __MACH_OMAP_DEVICES_H */
|
||||
|
|
|
@ -27,4 +27,10 @@
|
|||
#define cpu_is_omap4xxx() (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_AM33XX
|
||||
#define cpu_is_am33xx() (1)
|
||||
#else
|
||||
#define cpu_is_am33xx() (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef H_BAREBOX_ARCH_ARM_MACH_OMAP_MACH_FB4_H
|
||||
#define H_BAREBOX_ARCH_ARM_MACH_OMAP_MACH_FB4_H
|
||||
|
||||
#include <fb.h>
|
||||
|
||||
#define OMAP_DSS_LCD_TFT (1u << 0)
|
||||
#define OMAP_DSS_LCD_IVS (1u << 1)
|
||||
#define OMAP_DSS_LCD_IHS (1u << 2)
|
||||
#define OMAP_DSS_LCD_IPC (1u << 3)
|
||||
#define OMAP_DSS_LCD_IEO (1u << 4)
|
||||
#define OMAP_DSS_LCD_RF (1u << 5)
|
||||
#define OMAP_DSS_LCD_ONOFF (1u << 6)
|
||||
|
||||
#define OMAP_DSS_LCD_DATALINES(_l) ((_l) << 10)
|
||||
#define OMAP_DSS_LCD_DATALINES_msk OMAP_DSS_LCD_DATALINES(3u)
|
||||
#define OMAP_DSS_LCD_DATALINES_12 OMAP_DSS_LCD_DATALINES(0u)
|
||||
#define OMAP_DSS_LCD_DATALINES_16 OMAP_DSS_LCD_DATALINES(1u)
|
||||
#define OMAP_DSS_LCD_DATALINES_18 OMAP_DSS_LCD_DATALINES(2u)
|
||||
#define OMAP_DSS_LCD_DATALINES_24 OMAP_DSS_LCD_DATALINES(3u)
|
||||
|
||||
struct omapfb_display {
|
||||
struct fb_videomode mode;
|
||||
|
||||
unsigned long config;
|
||||
|
||||
unsigned int power_on_delay;
|
||||
unsigned int power_off_delay;
|
||||
};
|
||||
|
||||
struct omapfb_platform_data {
|
||||
struct omapfb_display const *displays;
|
||||
size_t num_displays;
|
||||
|
||||
unsigned int dss_clk_hz;
|
||||
|
||||
unsigned int bpp;
|
||||
|
||||
struct resource const *screen;
|
||||
|
||||
void (*enable)(int p);
|
||||
};
|
||||
|
||||
struct device_d;
|
||||
struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata);
|
||||
|
||||
|
||||
#endif /* H_BAREBOX_ARCH_ARM_MACH_OMAP_MACH_FB4_H */
|
|
@ -77,17 +77,20 @@ static inline struct device_d *omap3_add_mmc3(struct omap_hsmmc_platform_data *p
|
|||
|
||||
static inline struct device_d *omap3_add_i2c1(void *pdata)
|
||||
{
|
||||
return omap_add_i2c(0, OMAP3_I2C1_BASE, pdata);
|
||||
return add_generic_device("i2c-omap3", 0, NULL, OMAP3_I2C1_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *omap3_add_i2c2(void *pdata)
|
||||
{
|
||||
return omap_add_i2c(1, OMAP3_I2C2_BASE, pdata);
|
||||
return add_generic_device("i2c-omap3", 1, NULL, OMAP3_I2C2_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *omap3_add_i2c3(void *pdata)
|
||||
{
|
||||
return omap_add_i2c(2, OMAP3_I2C3_BASE, pdata);
|
||||
return add_generic_device("i2c-omap3", 2, NULL, OMAP3_I2C3_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *omap3_add_ehci(void *pdata)
|
||||
|
|
|
@ -60,22 +60,26 @@ static inline struct device_d *omap44xx_add_mmc5(struct omap_hsmmc_platform_data
|
|||
|
||||
static inline struct device_d *omap44xx_add_i2c1(void *pdata)
|
||||
{
|
||||
return omap_add_i2c(0, OMAP44XX_I2C1_BASE, pdata);
|
||||
return add_generic_device("i2c-omap4", 0, NULL, OMAP44XX_I2C1_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *omap44xx_add_i2c2(void *pdata)
|
||||
{
|
||||
return omap_add_i2c(1, OMAP44XX_I2C2_BASE, pdata);
|
||||
return add_generic_device("i2c-omap4", 1, NULL, OMAP44XX_I2C2_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *omap44xx_add_i2c3(void *pdata)
|
||||
{
|
||||
return omap_add_i2c(2, OMAP44XX_I2C3_BASE, pdata);
|
||||
return add_generic_device("i2c-omap4", 2, NULL, OMAP44XX_I2C3_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *omap44xx_add_i2c4(void *pdata)
|
||||
{
|
||||
return omap_add_i2c(3, OMAP44XX_I2C4_BASE, pdata);
|
||||
return add_generic_device("i2c-omap4", 3, NULL, OMAP44XX_I2C4_BASE,
|
||||
SZ_4K, IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *omap44xx_add_ehci(void *pdata)
|
||||
|
|
|
@ -230,7 +230,8 @@ struct dpll_param;
|
|||
void omap4_ddr_init(const struct ddr_regs *, const struct dpll_param *);
|
||||
void omap4_power_i2c_send(u32);
|
||||
unsigned int omap4_revision(void);
|
||||
noinline int omap4_scale_vcores(unsigned vsel0_pin);
|
||||
int omap4430_scale_vcores(void);
|
||||
int omap4460_scale_vcores(unsigned vsel0_pin, unsigned volt_mv);
|
||||
void omap4_set_warmboot_order(u32 *device_list);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -537,11 +537,9 @@ static void __iomem *omap4_get_gpio_base(unsigned gpio)
|
|||
|
||||
#define I2C_SLAVE 0x12
|
||||
|
||||
noinline int omap4_scale_vcores(unsigned vsel0_pin)
|
||||
noinline int omap4430_scale_vcores(void)
|
||||
{
|
||||
void __iomem *base;
|
||||
unsigned int rev = omap4_revision();
|
||||
u32 val = 0;
|
||||
|
||||
/* For VC bypass only VCOREx_CGF_FORCE is necessary and
|
||||
* VCOREx_CFG_VOLTAGE changes can be discarded
|
||||
|
@ -549,50 +547,16 @@ noinline int omap4_scale_vcores(unsigned vsel0_pin)
|
|||
writel(0, OMAP44XX_PRM_VC_CFG_I2C_MODE);
|
||||
writel(0x6026, OMAP44XX_PRM_VC_CFG_I2C_CLK);
|
||||
|
||||
/* TPS - supplies vdd_mpu on 4460 */
|
||||
if (rev >= OMAP4460_ES1_0) {
|
||||
/*
|
||||
* Setup SET1 and SET0 with right values so that kernel
|
||||
* can use either of them based on its needs.
|
||||
*/
|
||||
omap4_do_scale_tps62361(TPS62361_REG_ADDR_SET0, 1430);
|
||||
omap4_do_scale_tps62361(TPS62361_REG_ADDR_SET1, 1430);
|
||||
|
||||
/*
|
||||
* Select SET1 in TPS62361:
|
||||
* VSEL1 is grounded on board. So the following selects
|
||||
* VSEL1 = 0 and VSEL0 = 1
|
||||
*/
|
||||
base = omap4_get_gpio_base(vsel0_pin);
|
||||
|
||||
val = 1 << (vsel0_pin & GPIO_MASK);
|
||||
writel(val, base + 0x190);
|
||||
|
||||
val = readl(base + 0x134);
|
||||
val &= ~(1 << (vsel0_pin & GPIO_MASK));
|
||||
writel(val, base + 0x134);
|
||||
|
||||
val = 1 << (vsel0_pin & GPIO_MASK);
|
||||
writel(val, base + 0x194);
|
||||
}
|
||||
|
||||
/* set VCORE1 force VSEL */
|
||||
/*
|
||||
/* set VCORE1 force VSEL
|
||||
* 4430 : supplies vdd_mpu
|
||||
* Setting a high voltage for Nitro mode as smart reflex is not enabled.
|
||||
* We use the maximum possible value in the AVS range because the next
|
||||
* higher voltage in the discrete range (code >= 0b111010) is way too
|
||||
* high
|
||||
*
|
||||
* 4460 : supplies vdd_core
|
||||
*
|
||||
*/
|
||||
if (rev < OMAP4460_ES1_0)
|
||||
/* 0x55: i2c addr, 3A: ~ 1430 mvolts*/
|
||||
omap4_power_i2c_send((0x3A55 << 8) | I2C_SLAVE);
|
||||
else
|
||||
/* 0x55: i2c addr, 28: ~ 1200 mvolts*/
|
||||
omap4_power_i2c_send((0x2855 << 8) | I2C_SLAVE);
|
||||
|
||||
/* 0x55: i2c addr, 3A: ~ 1430 mvolts*/
|
||||
omap4_power_i2c_send((0x3A55 << 8) | I2C_SLAVE);
|
||||
|
||||
/* FIXME: set VCORE2 force VSEL, Check the reset value */
|
||||
omap4_power_i2c_send((0x295B << 8) | I2C_SLAVE);
|
||||
|
@ -605,12 +569,59 @@ noinline int omap4_scale_vcores(unsigned vsel0_pin)
|
|||
case OMAP4430_ES2_1:
|
||||
omap4_power_i2c_send((0x2A61 << 8) | I2C_SLAVE);
|
||||
break;
|
||||
/* > OMAP4460_ES1_0 : VCORE3 not connected */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
noinline int omap4460_scale_vcores(unsigned vsel0_pin, unsigned volt_mv)
|
||||
{
|
||||
void __iomem *base;
|
||||
u32 val = 0;
|
||||
|
||||
/* For VC bypass only VCOREx_CGF_FORCE is necessary and
|
||||
* VCOREx_CFG_VOLTAGE changes can be discarded
|
||||
*/
|
||||
writel(0, OMAP44XX_PRM_VC_CFG_I2C_MODE);
|
||||
writel(0x6026, OMAP44XX_PRM_VC_CFG_I2C_CLK);
|
||||
|
||||
/* TPS - supplies vdd_mpu on 4460
|
||||
* Setup SET1 and don't touch SET0 it acts as boot voltage
|
||||
* source after reset.
|
||||
*/
|
||||
|
||||
omap4_do_scale_tps62361(TPS62361_REG_ADDR_SET1, volt_mv);
|
||||
|
||||
/*
|
||||
* Select SET1 in TPS62361:
|
||||
* VSEL1 is grounded on board. So the following selects
|
||||
* VSEL1 = 0 and VSEL0 = 1
|
||||
*/
|
||||
base = omap4_get_gpio_base(vsel0_pin);
|
||||
|
||||
val = 1 << (vsel0_pin & GPIO_MASK);
|
||||
writel(val, base + 0x190);
|
||||
|
||||
val = readl(base + 0x134);
|
||||
val &= ~(1 << (vsel0_pin & GPIO_MASK));
|
||||
writel(val, base + 0x134);
|
||||
|
||||
val = 1 << (vsel0_pin & GPIO_MASK);
|
||||
writel(val, base + 0x194);
|
||||
|
||||
/* set VCORE1 force VSEL
|
||||
* 4460 : supplies vdd_core
|
||||
*/
|
||||
|
||||
/* 0x55: i2c addr, 28: ~ 1200 mvolts*/
|
||||
omap4_power_i2c_send((0x2855 << 8) | I2C_SLAVE);
|
||||
|
||||
/* FIXME: set VCORE2 force VSEL, Check the reset value */
|
||||
omap4_power_i2c_send((0x295B << 8) | I2C_SLAVE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omap4_do_set_mux(u32 base, struct pad_conf_entry const *array, int size)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -24,9 +24,3 @@ struct device_d *omap_add_uart(int id, unsigned long base)
|
|||
return add_ns16550_device(id, base, 1024,
|
||||
IORESOURCE_MEM_8BIT, &serial_plat);
|
||||
}
|
||||
|
||||
struct device_d *omap_add_i2c(int id, unsigned long base, void *pdata)
|
||||
{
|
||||
return add_generic_device("i2c-omap", id, NULL, base, SZ_4K,
|
||||
IORESOURCE_MEM, pdata);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#include <driver.h>
|
||||
#include <common.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <mach/omap-fb.h>
|
||||
|
||||
#if defined(CONFIG_DRIVER_VIDEO_OMAP)
|
||||
static struct resource omapfb_resources[] = {
|
||||
{
|
||||
.name = "omap4_dss",
|
||||
.start = 0x48040000,
|
||||
.end = 0x48040000 + 512 - 1,
|
||||
.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
|
||||
}, {
|
||||
.name = "omap4_dispc",
|
||||
.start = 0x48041000,
|
||||
.end = 0x48041000 + 3072 - 1,
|
||||
.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
|
||||
},
|
||||
};
|
||||
|
||||
struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata)
|
||||
{
|
||||
return add_generic_device_res("omap_fb", -1,
|
||||
omapfb_resources,
|
||||
ARRAY_SIZE(omapfb_resources),
|
||||
o_pdata);
|
||||
}
|
||||
#else
|
||||
struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
EXPORT_SYMBOL(omap_add_display);
|
|
@ -24,10 +24,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
/* #include <linux/delay.h> */
|
||||
|
||||
|
||||
#include <clock.h>
|
||||
#include <common.h>
|
||||
#include <driver.h>
|
||||
|
@ -44,12 +40,6 @@
|
|||
#include <mach/generic.h>
|
||||
#include <mach/omap3-clock.h>
|
||||
|
||||
#define OMAP_I2C_SIZE 0x3f
|
||||
#define OMAP1_I2C_BASE 0xfffb3800
|
||||
#define OMAP2_I2C_BASE1 0x48070000
|
||||
#define OMAP2_I2C_BASE2 0x48072000
|
||||
#define OMAP2_I2C_BASE3 0x48060000
|
||||
|
||||
/* This will be the driver name */
|
||||
#define DRIVER_NAME "i2c-omap"
|
||||
|
||||
|
@ -141,11 +131,17 @@
|
|||
#define SYSC_IDLEMODE_SMART 0x2
|
||||
#define SYSC_CLOCKACTIVITY_FCLK 0x2
|
||||
|
||||
/* i2c driver flags from kernel */
|
||||
#define OMAP_I2C_FLAG_RESET_REGS_POSTIDLE BIT(3)
|
||||
#define OMAP_I2C_FLAG_BUS_SHIFT_NONE 0
|
||||
#define OMAP_I2C_FLAG_BUS_SHIFT_1 BIT(7)
|
||||
#define OMAP_I2C_FLAG_BUS_SHIFT_2 BIT(8)
|
||||
#define OMAP_I2C_FLAG_BUS_SHIFT__SHIFT 7
|
||||
|
||||
struct omap_i2c_struct {
|
||||
void *base;
|
||||
u8 *regs;
|
||||
u8 reg_shift;
|
||||
struct omap_i2c_driver_data *data;
|
||||
struct resource *ioarea;
|
||||
u32 speed; /* Speed of bus in Khz */
|
||||
u16 cmd_err;
|
||||
|
@ -241,22 +237,50 @@ static const u8 omap4_reg_map[] = {
|
|||
[OMAP_I2C_IRQENABLE_CLR] = 0x30,
|
||||
};
|
||||
|
||||
struct omap_i2c_driver_data {
|
||||
u32 flags;
|
||||
u32 fclk_rate;
|
||||
u8 *regs;
|
||||
};
|
||||
|
||||
static struct omap_i2c_driver_data omap3_data = {
|
||||
.flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
|
||||
OMAP_I2C_FLAG_BUS_SHIFT_2,
|
||||
.fclk_rate = 48000,
|
||||
.regs = (u8 *) reg_map,
|
||||
};
|
||||
|
||||
static struct omap_i2c_driver_data omap4_data = {
|
||||
.flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
|
||||
.fclk_rate = 96000,
|
||||
.regs = (u8 *) omap4_reg_map,
|
||||
};
|
||||
|
||||
static struct omap_i2c_driver_data am33xx_data = {
|
||||
.flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
|
||||
OMAP_I2C_FLAG_BUS_SHIFT_NONE,
|
||||
.fclk_rate = 96000,
|
||||
.regs = (u8 *) omap4_reg_map,
|
||||
};
|
||||
|
||||
static inline void omap_i2c_write_reg(struct omap_i2c_struct *i2c_omap,
|
||||
int reg, u16 val)
|
||||
{
|
||||
__raw_writew(val, i2c_omap->base +
|
||||
(i2c_omap->regs[reg] << i2c_omap->reg_shift));
|
||||
(i2c_omap->data->regs[reg] << i2c_omap->reg_shift));
|
||||
}
|
||||
|
||||
static inline u16 omap_i2c_read_reg(struct omap_i2c_struct *i2c_omap, int reg)
|
||||
{
|
||||
return __raw_readw(i2c_omap->base +
|
||||
(i2c_omap->regs[reg] << i2c_omap->reg_shift));
|
||||
(i2c_omap->data->regs[reg] << i2c_omap->reg_shift));
|
||||
}
|
||||
|
||||
static void omap_i2c_unidle(struct omap_i2c_struct *i2c_omap)
|
||||
{
|
||||
if (cpu_is_omap34xx()) {
|
||||
struct omap_i2c_driver_data *i2c_data = i2c_omap->data;
|
||||
|
||||
if (i2c_data->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
|
||||
omap_i2c_write_reg(i2c_omap, OMAP_I2C_CON_REG, 0);
|
||||
omap_i2c_write_reg(i2c_omap, OMAP_I2C_PSC_REG, i2c_omap->pscstate);
|
||||
omap_i2c_write_reg(i2c_omap, OMAP_I2C_SCLL_REG, i2c_omap->scllstate);
|
||||
|
@ -299,9 +323,8 @@ static int omap_i2c_init(struct omap_i2c_struct *i2c_omap)
|
|||
u16 psc = 0, scll = 0, sclh = 0, buf = 0;
|
||||
u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
|
||||
uint64_t start;
|
||||
|
||||
unsigned long fclk_rate = 12000000;
|
||||
unsigned long internal_clk = 0;
|
||||
struct omap_i2c_driver_data *i2c_data = i2c_omap->data;
|
||||
|
||||
if (i2c_omap->rev >= OMAP_I2C_REV_2) {
|
||||
/* Disable I2C controller before soft reset */
|
||||
|
@ -352,63 +375,50 @@ static int omap_i2c_init(struct omap_i2c_struct *i2c_omap)
|
|||
}
|
||||
omap_i2c_write_reg(i2c_omap, OMAP_I2C_CON_REG, 0);
|
||||
|
||||
/* omap1 handling is missing here */
|
||||
/*
|
||||
* HSI2C controller internal clk rate should be 19.2 Mhz for
|
||||
* HS and for all modes on 2430. On 34xx we can use lower rate
|
||||
* to get longer filter period for better noise suppression.
|
||||
* The filter is iclk (fclk for HS) period.
|
||||
*/
|
||||
if (i2c_omap->speed > 400)
|
||||
internal_clk = 19200;
|
||||
else if (i2c_omap->speed > 100)
|
||||
internal_clk = 9600;
|
||||
else
|
||||
internal_clk = 4000;
|
||||
|
||||
if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap4xxx()) {
|
||||
/* Compute prescaler divisor */
|
||||
psc = i2c_data->fclk_rate / internal_clk;
|
||||
psc = psc - 1;
|
||||
|
||||
/*
|
||||
* HSI2C controller internal clk rate should be 19.2 Mhz for
|
||||
* HS and for all modes on 2430. On 34xx we can use lower rate
|
||||
* to get longer filter period for better noise suppression.
|
||||
* The filter is iclk (fclk for HS) period.
|
||||
*/
|
||||
if (i2c_omap->speed > 400 || cpu_is_omap2430())
|
||||
internal_clk = 19200;
|
||||
else if (i2c_omap->speed > 100)
|
||||
internal_clk = 9600;
|
||||
else
|
||||
internal_clk = 4000;
|
||||
fclk_rate = 96000000 / 1000;
|
||||
/* If configured for High Speed */
|
||||
if (i2c_omap->speed > 400) {
|
||||
unsigned long scl;
|
||||
|
||||
/* Compute prescaler divisor */
|
||||
psc = fclk_rate / internal_clk;
|
||||
psc = psc - 1;
|
||||
/* For first phase of HS mode */
|
||||
scl = internal_clk / 400;
|
||||
fsscll = scl - (scl / 3) - 7;
|
||||
fssclh = (scl / 3) - 5;
|
||||
|
||||
/* If configured for High Speed */
|
||||
if (i2c_omap->speed > 400) {
|
||||
unsigned long scl;
|
||||
/* For second phase of HS mode */
|
||||
scl = i2c_data->fclk_rate / i2c_omap->speed;
|
||||
hsscll = scl - (scl / 3) - 7;
|
||||
hssclh = (scl / 3) - 5;
|
||||
} else if (i2c_omap->speed > 100) {
|
||||
unsigned long scl;
|
||||
|
||||
/* For first phase of HS mode */
|
||||
scl = internal_clk / 400;
|
||||
fsscll = scl - (scl / 3) - 7;
|
||||
fssclh = (scl / 3) - 5;
|
||||
|
||||
/* For second phase of HS mode */
|
||||
scl = fclk_rate / i2c_omap->speed;
|
||||
hsscll = scl - (scl / 3) - 7;
|
||||
hssclh = (scl / 3) - 5;
|
||||
} else if (i2c_omap->speed > 100) {
|
||||
unsigned long scl;
|
||||
|
||||
/* Fast mode */
|
||||
scl = internal_clk / i2c_omap->speed;
|
||||
fsscll = scl - (scl / 3) - 7;
|
||||
fssclh = (scl / 3) - 5;
|
||||
} else {
|
||||
/* Standard mode */
|
||||
fsscll = internal_clk / (i2c_omap->speed * 2) - 7;
|
||||
fssclh = internal_clk / (i2c_omap->speed * 2) - 5;
|
||||
}
|
||||
scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll;
|
||||
sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh;
|
||||
/* Fast mode */
|
||||
scl = internal_clk / i2c_omap->speed;
|
||||
fsscll = scl - (scl / 3) - 7;
|
||||
fssclh = (scl / 3) - 5;
|
||||
} else {
|
||||
/* Program desired operating rate */
|
||||
fclk_rate /= (psc + 1) * 1000;
|
||||
if (psc > 2)
|
||||
psc = 2;
|
||||
scll = fclk_rate / (i2c_omap->speed * 2) - 7 + psc;
|
||||
sclh = fclk_rate / (i2c_omap->speed * 2) - 7 + psc;
|
||||
/* Standard mode */
|
||||
fsscll = internal_clk / (i2c_omap->speed * 2) - 7;
|
||||
fssclh = internal_clk / (i2c_omap->speed * 2) - 5;
|
||||
}
|
||||
scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll;
|
||||
sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh;
|
||||
|
||||
/* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
|
||||
omap_i2c_write_reg(i2c_omap, OMAP_I2C_PSC_REG, psc);
|
||||
|
@ -433,7 +443,7 @@ static int omap_i2c_init(struct omap_i2c_struct *i2c_omap)
|
|||
OMAP_I2C_IE_AL) | ((i2c_omap->fifo_size) ?
|
||||
(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
|
||||
omap_i2c_write_reg(i2c_omap, OMAP_I2C_IE_REG, i2c_omap->iestate);
|
||||
if (cpu_is_omap34xx()) {
|
||||
if (i2c_data->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
|
||||
i2c_omap->pscstate = psc;
|
||||
i2c_omap->scllstate = scll;
|
||||
i2c_omap->sclhstate = sclh;
|
||||
|
@ -525,15 +535,6 @@ complete:
|
|||
if (dev->buf_len) {
|
||||
*dev->buf++ = w;
|
||||
dev->buf_len--;
|
||||
/* Data reg from 2430 is 8 bit wide */
|
||||
if (!cpu_is_omap2430() &&
|
||||
!cpu_is_omap34xx() &&
|
||||
!cpu_is_omap4xxx()) {
|
||||
if (dev->buf_len) {
|
||||
*dev->buf++ = w >> 8;
|
||||
dev->buf_len--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stat & OMAP_I2C_STAT_RRDY)
|
||||
dev_err(&dev->adapter.dev,
|
||||
|
@ -566,15 +567,6 @@ complete:
|
|||
if (dev->buf_len) {
|
||||
w = *dev->buf++;
|
||||
dev->buf_len--;
|
||||
/* Data reg from 2430 is 8 bit wide */
|
||||
if (!cpu_is_omap2430() &&
|
||||
!cpu_is_omap34xx() &&
|
||||
!cpu_is_omap4xxx()) {
|
||||
if (dev->buf_len) {
|
||||
w |= *dev->buf++ << 8;
|
||||
dev->buf_len--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stat & OMAP_I2C_STAT_XRDY)
|
||||
dev_err(&dev->adapter.dev,
|
||||
|
@ -706,7 +698,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adapter,
|
|||
ret = omap_i2c_isr(i2c_omap);
|
||||
while (ret){
|
||||
ret = omap_i2c_isr(i2c_omap);
|
||||
if (is_timeout(start, MSECOND)) {
|
||||
if (is_timeout(start, 50 * MSECOND)) {
|
||||
dev_err(&adapter->dev,
|
||||
"timed out on polling for "
|
||||
"open i2c message handling\n");
|
||||
|
@ -773,9 +765,10 @@ static int __init
|
|||
i2c_omap_probe(struct device_d *pdev)
|
||||
{
|
||||
struct omap_i2c_struct *i2c_omap;
|
||||
/* struct i2c_platform_data *pdata; */
|
||||
struct omap_i2c_driver_data *i2c_data;
|
||||
int r;
|
||||
u32 speed = 0;
|
||||
u16 s;
|
||||
|
||||
i2c_omap = kzalloc(sizeof(struct omap_i2c_struct), GFP_KERNEL);
|
||||
if (!i2c_omap) {
|
||||
|
@ -783,13 +776,13 @@ i2c_omap_probe(struct device_d *pdev)
|
|||
goto err_free_mem;
|
||||
}
|
||||
|
||||
if (cpu_is_omap4xxx()) {
|
||||
i2c_omap->regs = (u8 *)omap4_reg_map;
|
||||
i2c_omap->reg_shift = 0;
|
||||
} else {
|
||||
i2c_omap->regs = (u8 *)reg_map;
|
||||
i2c_omap->reg_shift = 2;
|
||||
}
|
||||
r = dev_get_drvdata(pdev, (unsigned long *)&i2c_data);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
i2c_omap->data = i2c_data;
|
||||
i2c_omap->reg_shift = (i2c_data->flags >>
|
||||
OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
|
||||
|
||||
if (pdev->platform_data != NULL)
|
||||
speed = *(u32 *)pdev->platform_data;
|
||||
|
@ -802,28 +795,23 @@ i2c_omap_probe(struct device_d *pdev)
|
|||
omap_i2c_unidle(i2c_omap);
|
||||
|
||||
i2c_omap->rev = omap_i2c_read_reg(i2c_omap, OMAP_I2C_REV_REG) & 0xff;
|
||||
/* i2c_omap->base = OMAP2_I2C_BASE3; */
|
||||
|
||||
if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap4xxx()) {
|
||||
u16 s;
|
||||
/* Set up the fifo size - Get total size */
|
||||
s = (omap_i2c_read_reg(i2c_omap, OMAP_I2C_BUFSTAT_REG) >> 14) & 0x3;
|
||||
i2c_omap->fifo_size = 0x8 << s;
|
||||
|
||||
/* Set up the fifo size - Get total size */
|
||||
s = (omap_i2c_read_reg(i2c_omap, OMAP_I2C_BUFSTAT_REG) >> 14) & 0x3;
|
||||
i2c_omap->fifo_size = 0x8 << s;
|
||||
/*
|
||||
* Set up notification threshold as half the total available
|
||||
* size. This is to ensure that we can handle the status on int
|
||||
* call back latencies.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set up notification threshold as half the total available
|
||||
* size. This is to ensure that we can handle the status on int
|
||||
* call back latencies.
|
||||
*/
|
||||
i2c_omap->fifo_size = (i2c_omap->fifo_size / 2);
|
||||
|
||||
i2c_omap->fifo_size = (i2c_omap->fifo_size / 2);
|
||||
|
||||
if (i2c_omap->rev >= OMAP_I2C_REV_ON_4430)
|
||||
i2c_omap->b_hw = 0; /* Disable hardware fixes */
|
||||
else
|
||||
i2c_omap->b_hw = 1; /* Enable hardware fixes */
|
||||
}
|
||||
if (i2c_omap->rev >= OMAP_I2C_REV_ON_4430)
|
||||
i2c_omap->b_hw = 0; /* Disable hardware fixes */
|
||||
else
|
||||
i2c_omap->b_hw = 1; /* Enable hardware fixes */
|
||||
|
||||
/* reset ASAP, clearing any IRQs */
|
||||
omap_i2c_init(i2c_omap);
|
||||
|
@ -856,9 +844,25 @@ err_free_mem:
|
|||
return r;
|
||||
}
|
||||
|
||||
static struct platform_device_id omap_i2c_ids[] = {
|
||||
{
|
||||
.name = "i2c-omap3",
|
||||
.driver_data = (unsigned long)&omap3_data,
|
||||
}, {
|
||||
.name = "i2c-omap4",
|
||||
.driver_data = (unsigned long)&omap4_data,
|
||||
}, {
|
||||
.name = "i2c-am33xx",
|
||||
.driver_data = (unsigned long)&am33xx_data,
|
||||
}, {
|
||||
/* sentinel */
|
||||
},
|
||||
};
|
||||
|
||||
static struct driver_d omap_i2c_driver = {
|
||||
.probe = i2c_omap_probe,
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = omap_i2c_ids,
|
||||
};
|
||||
device_platform_driver(omap_i2c_driver);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ config DRIVER_SPI_MXS
|
|||
|
||||
config DRIVER_SPI_OMAP3
|
||||
bool "OMAP3 McSPI Master driver"
|
||||
depends on ARCH_OMAP3
|
||||
depends on ARCH_OMAP3 || ARCH_AM33XX
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -325,17 +325,6 @@ static int omap3_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
|
|||
|
||||
static int omap3_spi_setup(struct spi_device *spi)
|
||||
{
|
||||
struct spi_master *master = spi->master;
|
||||
|
||||
if (((master->bus_num == 1) && (spi->chip_select > 3)) ||
|
||||
((master->bus_num == 2) && (spi->chip_select > 1)) ||
|
||||
((master->bus_num == 3) && (spi->chip_select > 1)) ||
|
||||
((master->bus_num == 4) && (spi->chip_select > 0))) {
|
||||
printf("SPI error: unsupported chip select %i \
|
||||
on bus %i\n", spi->chip_select, master->bus_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (spi->max_speed_hz > OMAP3_MCSPI_MAX_FREQ) {
|
||||
printf("SPI error: unsupported frequency %i Hz. \
|
||||
Max frequency is 48 Mhz\n", spi->max_speed_hz);
|
||||
|
@ -368,16 +357,24 @@ static int omap3_spi_probe(struct device_d *dev)
|
|||
* McSPI3 has 2 CS (bus 3, cs 0 - 1)
|
||||
* McSPI4 has 1 CS (bus 4, cs 0)
|
||||
*
|
||||
* AM335x McSPI has 2 busses with 2 chip selects:
|
||||
* McSPI0 has 2 CS (bus 0, cs 0 - 1)
|
||||
* McSPI1 has 2 CS (bus 1, cs 0 - 1)
|
||||
*
|
||||
* The board code has to make sure that it does not use
|
||||
* invalid buses or chip selects.
|
||||
*/
|
||||
|
||||
master->bus_num = dev->id;
|
||||
master->num_chipselect = 4;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_OMAP3))
|
||||
master->num_chipselect = 4;
|
||||
else
|
||||
master->num_chipselect = 2;
|
||||
master->setup = omap3_spi_setup;
|
||||
master->transfer = omap3_spi_transfer;
|
||||
|
||||
omap3_master->regs = dev_request_mem_region(dev, 0);;
|
||||
omap3_master->regs = dev_request_mem_region(dev, 0);
|
||||
|
||||
spi_reset(master);
|
||||
|
||||
|
|
|
@ -45,6 +45,14 @@ config DRIVER_VIDEO_S3C24XX
|
|||
help
|
||||
Add support for the S3C244x LCD controller.
|
||||
|
||||
config DRIVER_VIDEO_OMAP
|
||||
bool "OMAP framebuffer driver"
|
||||
depends on ARCH_OMAP4
|
||||
help
|
||||
Add support for OMAP Display Controller. Currently this
|
||||
driver only supports OMAP4 SoCs in DISPC parallel mode on
|
||||
LCD2 (MIPI DPI).
|
||||
|
||||
if DRIVER_VIDEO_S3C24XX
|
||||
|
||||
config DRIVER_VIDEO_S3C_VERBOSE
|
||||
|
|
|
@ -8,3 +8,4 @@ obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
|
|||
obj-$(CONFIG_DRIVER_VIDEO_S3C24XX) += s3c24xx.o
|
||||
obj-$(CONFIG_DRIVER_VIDEO_PXA) += pxa.o
|
||||
obj-$(CONFIG_DRIVER_VIDEO_SDL) += sdl.o
|
||||
obj-$(CONFIG_DRIVER_VIDEO_OMAP) += omap.o
|
||||
|
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
* TI Omap Frame Buffer device driver
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Fritz <chf.fritz@googlemail.com>
|
||||
* Based on work by Enrico Scholz, sponsored by Phytec
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <driver.h>
|
||||
#include <fb.h>
|
||||
#include <errno.h>
|
||||
#include <xfuncs.h>
|
||||
#include <init.h>
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <common.h>
|
||||
#include <clock.h>
|
||||
|
||||
#include <mach/omap4-silicon.h>
|
||||
#include <mach/omap-fb.h>
|
||||
|
||||
#include <asm/mmu.h>
|
||||
|
||||
#include "omap.h"
|
||||
|
||||
struct omapfb_device {
|
||||
struct fb_info info;
|
||||
struct device_d *dev;
|
||||
|
||||
struct omapfb_display const *cur_display;
|
||||
|
||||
struct omapfb_display const *displays;
|
||||
size_t num_displays;
|
||||
|
||||
void __iomem *dss;
|
||||
void __iomem *dispc;
|
||||
|
||||
struct {
|
||||
void __iomem *addr;
|
||||
size_t size;
|
||||
} prealloc_screen;
|
||||
|
||||
struct {
|
||||
uint32_t dispc_control;
|
||||
uint32_t dispc_pol_freq;
|
||||
} shadow;
|
||||
|
||||
struct {
|
||||
unsigned int dss_clk_hz;
|
||||
unsigned int lckd;
|
||||
unsigned int pckd;
|
||||
} divisor;
|
||||
size_t dma_size;
|
||||
void (*enable_fn)(int);
|
||||
|
||||
struct fb_videomode video_modes[];
|
||||
};
|
||||
|
||||
static inline struct omapfb_device *to_omapfb(const struct fb_info *info)
|
||||
{
|
||||
return container_of(info, struct omapfb_device, info);
|
||||
}
|
||||
|
||||
static void omapfb_enable(struct fb_info *info)
|
||||
{
|
||||
struct omapfb_device *fbi = to_omapfb(info);
|
||||
|
||||
dev_dbg(fbi->dev, "%s\n", __func__);
|
||||
|
||||
if (!fbi->cur_display) {
|
||||
dev_err(fbi->dev, "no valid mode set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fbi->enable_fn)
|
||||
fbi->enable_fn(1);
|
||||
|
||||
udelay(fbi->cur_display->power_on_delay * 1000u);
|
||||
|
||||
o4_dispc_write(o4_dispc_read(O4_DISPC_CONTROL2) |
|
||||
DSS_DISPC_CONTROL_LCDENABLE |
|
||||
DSS_DISPC_CONTROL_LCDENABLESIGNAL, O4_DISPC_CONTROL2);
|
||||
|
||||
o4_dispc_write(o4_dispc_read(O4_DISPC_VID1_ATTRIBUTES) |
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDENABLE, O4_DISPC_VID1_ATTRIBUTES);
|
||||
|
||||
o4_dispc_write(o4_dispc_read(O4_DISPC_CONTROL2) |
|
||||
DSS_DISPC_CONTROL_GOLCD, O4_DISPC_CONTROL2);
|
||||
}
|
||||
|
||||
static void omapfb_disable(struct fb_info *info)
|
||||
{
|
||||
struct omapfb_device *fbi = to_omapfb(info);
|
||||
|
||||
dev_dbg(fbi->dev, "%s\n", __func__);
|
||||
|
||||
if (!fbi->cur_display) {
|
||||
dev_err(fbi->dev, "no valid mode set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
o4_dispc_write(o4_dispc_read(O4_DISPC_CONTROL2) &
|
||||
~(DSS_DISPC_CONTROL_LCDENABLE |
|
||||
DSS_DISPC_CONTROL_LCDENABLESIGNAL), O4_DISPC_CONTROL2);
|
||||
|
||||
o4_dispc_write(o4_dispc_read(O4_DISPC_VID1_ATTRIBUTES) &
|
||||
~(DSS_DISPC_VIDn_ATTRIBUTES_VIDENABLE),
|
||||
O4_DISPC_VID1_ATTRIBUTES);
|
||||
|
||||
if (fbi->prealloc_screen.addr == NULL) {
|
||||
/* free frame buffer; but only when screen is not
|
||||
* preallocated */
|
||||
if (info->screen_base)
|
||||
dma_free_coherent(info->screen_base, fbi->dma_size);
|
||||
}
|
||||
|
||||
info->screen_base = NULL;
|
||||
|
||||
udelay(fbi->cur_display->power_off_delay * 1000u);
|
||||
|
||||
if (fbi->enable_fn)
|
||||
fbi->enable_fn(0);
|
||||
}
|
||||
|
||||
static void omapfb_calc_divisor(struct omapfb_device *fbi,
|
||||
struct fb_videomode const *mode)
|
||||
{
|
||||
unsigned int l, k, t, b;
|
||||
|
||||
b = UINT_MAX;
|
||||
for (l = 1; l < 256; l++) {
|
||||
for (k = 1; k < 256; k++) {
|
||||
t = abs(mode->pixclock * 100 -
|
||||
(fbi->divisor.dss_clk_hz / l / k));
|
||||
if (t <= b) {
|
||||
b = t;
|
||||
fbi->divisor.lckd = l;
|
||||
fbi->divisor.pckd = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int omapfb_calc_format(struct fb_info const *info)
|
||||
{
|
||||
struct omapfb_device *fbi = to_omapfb(info);
|
||||
|
||||
switch (info->bits_per_pixel) {
|
||||
case 24:
|
||||
return 9;
|
||||
case 32:
|
||||
return 0x8; /* xRGB24-8888 (32-bit container) */
|
||||
default:
|
||||
dev_err(fbi->dev, "%s: unsupported bpp %d\n", __func__,
|
||||
info->bits_per_pixel);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct omapfb_colors {
|
||||
struct fb_bitfield red;
|
||||
struct fb_bitfield green;
|
||||
struct fb_bitfield blue;
|
||||
struct fb_bitfield transp;
|
||||
};
|
||||
|
||||
static struct omapfb_colors const omapfb_col[] = {
|
||||
[0] = {
|
||||
.red = { .length = 0, .offset = 0 },
|
||||
},
|
||||
[1] = {
|
||||
.blue = { .length = 8, .offset = 0 },
|
||||
.green = { .length = 8, .offset = 8 },
|
||||
.red = { .length = 8, .offset = 16 },
|
||||
},
|
||||
[2] = {
|
||||
.blue = { .length = 8, .offset = 0 },
|
||||
.green = { .length = 8, .offset = 8 },
|
||||
.red = { .length = 8, .offset = 16 },
|
||||
.transp = { .length = 8, .offset = 24 },
|
||||
},
|
||||
};
|
||||
|
||||
static void omapfb_fill_shadow(struct omapfb_device *fbi,
|
||||
struct omapfb_display const *display)
|
||||
{
|
||||
fbi->shadow.dispc_control = 0;
|
||||
fbi->shadow.dispc_pol_freq = 0;
|
||||
|
||||
fbi->shadow.dispc_control |= DSS_DISPC_CONTROL_STNTFT;
|
||||
|
||||
switch (display->config & OMAP_DSS_LCD_DATALINES_msk) {
|
||||
case OMAP_DSS_LCD_DATALINES_12:
|
||||
fbi->shadow.dispc_control |= DSS_DISPC_CONTROL_TFTDATALINES_12;
|
||||
break;
|
||||
case OMAP_DSS_LCD_DATALINES_16:
|
||||
fbi->shadow.dispc_control |= DSS_DISPC_CONTROL_TFTDATALINES_16;
|
||||
break;
|
||||
case OMAP_DSS_LCD_DATALINES_18:
|
||||
fbi->shadow.dispc_control |= DSS_DISPC_CONTROL_TFTDATALINES_18;
|
||||
break;
|
||||
case OMAP_DSS_LCD_DATALINES_24:
|
||||
fbi->shadow.dispc_control |= DSS_DISPC_CONTROL_TFTDATALINES_24;
|
||||
break;
|
||||
}
|
||||
|
||||
if (display->config & OMAP_DSS_LCD_IPC)
|
||||
fbi->shadow.dispc_pol_freq |= DSS_DISPC_POL_FREQ_IPC;
|
||||
|
||||
if (display->config & OMAP_DSS_LCD_IVS)
|
||||
fbi->shadow.dispc_pol_freq |= DSS_DISPC_POL_FREQ_IVS;
|
||||
|
||||
if (display->config & OMAP_DSS_LCD_IHS)
|
||||
fbi->shadow.dispc_pol_freq |= DSS_DISPC_POL_FREQ_IHS;
|
||||
|
||||
if (display->config & OMAP_DSS_LCD_IEO)
|
||||
fbi->shadow.dispc_pol_freq |= DSS_DISPC_POL_FREQ_IEO;
|
||||
|
||||
if (display->config & OMAP_DSS_LCD_RF)
|
||||
fbi->shadow.dispc_pol_freq |= DSS_DISPC_POL_FREQ_RF;
|
||||
|
||||
if (display->config & OMAP_DSS_LCD_ONOFF)
|
||||
fbi->shadow.dispc_pol_freq |= DSS_DISPC_POL_FREQ_ONOFF;
|
||||
}
|
||||
|
||||
static int omapfb_find_display_by_name(struct omapfb_device *fbi,
|
||||
const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fbi->num_displays; ++i) {
|
||||
if (strcmp(name, fbi->displays[i].mode.name) == 0)
|
||||
return i;
|
||||
}
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static int omapfb_activate_var(struct fb_info *info)
|
||||
{
|
||||
struct omapfb_device *fbi = to_omapfb(info);
|
||||
struct fb_videomode const *mode = info->mode;
|
||||
size_t size = mode->xres * mode->yres * (info->bits_per_pixel / 8);
|
||||
int rc;
|
||||
unsigned int fmt = omapfb_calc_format(info);
|
||||
struct omapfb_colors const *cols;
|
||||
struct omapfb_display const *new_display = NULL;
|
||||
|
||||
rc = omapfb_find_display_by_name(fbi, mode->name);
|
||||
if (rc < 0) {
|
||||
dev_err(fbi->dev, "no display found for this mode '%s'\n",
|
||||
mode->name);
|
||||
goto out;
|
||||
}
|
||||
new_display = &fbi->displays[rc];
|
||||
|
||||
/*Free old screen buf*/
|
||||
if (!fbi->prealloc_screen.addr && info->screen_base)
|
||||
dma_free_coherent(info->screen_base, fbi->dma_size);
|
||||
|
||||
fbi->dma_size = PAGE_ALIGN(size);
|
||||
|
||||
if (!fbi->prealloc_screen.addr) {
|
||||
/* case 1: no preallocated screen */
|
||||
info->screen_base = dma_alloc_coherent(size);
|
||||
} else if (fbi->prealloc_screen.size < fbi->dma_size) {
|
||||
/* case 2: preallocated screen, but too small */
|
||||
dev_err(fbi->dev,
|
||||
"allocated framebuffer too small (%zu < %zu)\n",
|
||||
fbi->prealloc_screen.size, fbi->dma_size);
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
} else {
|
||||
/* case 3: preallocated screen */
|
||||
info->screen_base = fbi->prealloc_screen.addr;
|
||||
}
|
||||
|
||||
omapfb_fill_shadow(fbi, new_display);
|
||||
|
||||
omapfb_calc_divisor(fbi, mode);
|
||||
|
||||
switch (info->bits_per_pixel) {
|
||||
case 24:
|
||||
cols = &omapfb_col[1];
|
||||
break;
|
||||
case 32:
|
||||
cols = &omapfb_col[2];
|
||||
break;
|
||||
default:
|
||||
cols = &omapfb_col[0];
|
||||
}
|
||||
|
||||
info->red = cols->red;
|
||||
info->green = cols->green;
|
||||
info->blue = cols->blue;
|
||||
info->transp = cols->transp;
|
||||
|
||||
o4_dispc_write(fbi->shadow.dispc_control, O4_DISPC_CONTROL2);
|
||||
|
||||
o4_dispc_write(fbi->shadow.dispc_pol_freq, O4_DISPC_POL_FREQ2);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_TIMING_H_HSW(mode->hsync_len - 1) |
|
||||
DSS_DISPC_TIMING_H_HFP(mode->right_margin - 1) |
|
||||
DSS_DISPC_TIMING_H_HBP(mode->left_margin - 1),
|
||||
O4_DISPC_TIMING_H2);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_TIMING_V_VSW(mode->vsync_len - 1) |
|
||||
DSS_DISPC_TIMING_V_VFP(mode->lower_margin) |
|
||||
DSS_DISPC_TIMING_V_VBP(mode->upper_margin), O4_DISPC_TIMING_V2);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_DIVISOR_ENABLE | DSS_DISPC_DIVISOR_LCD(1),
|
||||
O4_DISPC_DIVISOR);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_DIVISOR2_LCD(fbi->divisor.lckd) |
|
||||
DSS_DISPC_DIVISOR2_PCD(fbi->divisor.pckd), O4_DISPC_DIVISOR2);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_SIZE_LCD_PPL(mode->xres - 1) |
|
||||
DSS_DISPC_SIZE_LCD_LPP(mode->yres - 1), O4_DISPC_SIZE_LCD2);
|
||||
|
||||
o4_dispc_write(0x0000ff00, O4_DISPC_DEFAULT_COLOR2);
|
||||
|
||||
/* we use VID1 */
|
||||
o4_dispc_write((uintptr_t)info->screen_base, O4_DISPC_VID1_BA0);
|
||||
o4_dispc_write((uintptr_t)info->screen_base, O4_DISPC_VID1_BA1);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_VIDn_POSITION_VIDPOSX(0) |
|
||||
DSS_DISPC_VIDn_POSITION_VIDPOSY(0), O4_DISPC_VID1_POSITION);
|
||||
o4_dispc_write(DSS_DISPC_VIDn_SIZE_VIDSIZEX(mode->xres - 1) |
|
||||
DSS_DISPC_VIDn_SIZE_VIDSIZEY(mode->yres - 1),
|
||||
O4_DISPC_VID1_SIZE);
|
||||
o4_dispc_write(DSS_DISPC_VIDn_PICTURE_SIZE_VIDORGSIZEX(mode->xres - 1) |
|
||||
DSS_DISPC_VIDn_PICTURE_SIZE_VIDORGSIZEY(mode->yres - 1),
|
||||
O4_DISPC_VID1_PICTURE_SIZE);
|
||||
o4_dispc_write(1, O4_DISPC_VID1_ROW_INC);
|
||||
o4_dispc_write(1, O4_DISPC_VID1_PIXEL_INC);
|
||||
|
||||
o4_dispc_write(0xfff, O4_DISPC_VID1_PRELOAD);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(fmt) |
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE_8x128 |
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_ZORDERENABLE |
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2_SECONDARY_LCD,
|
||||
O4_DISPC_VID1_ATTRIBUTES);
|
||||
|
||||
rc = wait_on_timeout(OFB_TIMEOUT,
|
||||
!(o4_dispc_read(O4_DISPC_CONTROL2) &
|
||||
DSS_DISPC_CONTROL_GOLCD));
|
||||
|
||||
if (rc) {
|
||||
dev_err(fbi->dev, "timeout: dispc golcd\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
o4_dispc_write(o4_dispc_read(O4_DISPC_CONTROL2) |
|
||||
DSS_DISPC_CONTROL_GOLCD, O4_DISPC_CONTROL2);
|
||||
|
||||
fbi->cur_display = new_display;
|
||||
info->xres = mode->xres;
|
||||
info->yres = mode->yres;
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int omapfb_reset(struct omapfb_device const *fbi)
|
||||
{
|
||||
uint32_t v = o4_dispc_read(O4_DISPC_CONTROL2);
|
||||
int rc;
|
||||
|
||||
/* step 1: stop the LCD controller */
|
||||
if (v & DSS_DISPC_CONTROL_LCDENABLE) {
|
||||
o4_dispc_write(v & ~DSS_DISPC_CONTROL_LCDENABLE,
|
||||
O4_DISPC_CONTROL2);
|
||||
|
||||
o4_dispc_write(DSS_DISPC_IRQSTATUS_FRAMEDONE2,
|
||||
O4_DISPC_IRQSTATUS);
|
||||
|
||||
rc = wait_on_timeout(OFB_TIMEOUT,
|
||||
((o4_dispc_read(O4_DISPC_IRQSTATUS) &
|
||||
DSS_DISPC_IRQSTATUS_FRAMEDONE) != 0));
|
||||
|
||||
if (rc) {
|
||||
dev_err(fbi->dev, "timeout: irqstatus framedone\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* step 2: wait for reset done status */
|
||||
rc = wait_on_timeout(OFB_TIMEOUT,
|
||||
(o4_dss_read(O4_DSS_SYSSTATUS) &
|
||||
DSS_DSS_SYSSTATUS_RESETDONE));
|
||||
|
||||
if (rc) {
|
||||
dev_err(fbi->dev, "timeout: sysstatus resetdone\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* DSS_CTL: set to reset value */
|
||||
o4_dss_write(0, O4_DSS_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops omapfb_ops = {
|
||||
.fb_enable = omapfb_enable,
|
||||
.fb_disable = omapfb_disable,
|
||||
.fb_activate_var = omapfb_activate_var,
|
||||
};
|
||||
|
||||
static int omapfb_probe(struct device_d *dev)
|
||||
{
|
||||
struct omapfb_platform_data const *pdata = dev->platform_data;
|
||||
struct omapfb_device *fbi;
|
||||
struct fb_info *info;
|
||||
int rc;
|
||||
size_t i;
|
||||
|
||||
fbi = xzalloc(sizeof *fbi +
|
||||
pdata->num_displays * sizeof fbi->video_modes[0]);
|
||||
info = &fbi->info;
|
||||
|
||||
fbi->dev = dev;
|
||||
|
||||
/* CM_DSS_CLKSTCTRL (TRM: 935) trigger SW_WKUP */
|
||||
__raw_writel(0x2, 0x4a009100); /* TODO: move this to clockmanagement */
|
||||
|
||||
fbi->dss = dev_request_mem_region_by_name(dev, "omap4_dss");
|
||||
fbi->dispc = dev_request_mem_region_by_name(dev, "omap4_dispc");
|
||||
|
||||
if (!fbi->dss || !fbi->dispc) {
|
||||
dev_err(dev, "Insufficient register description\n");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_info(dev, "HW-Revision 0x%04x 0x%04x\n",
|
||||
o4_dss_read(O4_DISPC_REVISION),
|
||||
o4_dss_read(O4_DSS_REVISION));
|
||||
|
||||
if (!pdata->dss_clk_hz | !pdata->displays | !pdata->num_displays |
|
||||
!pdata->bpp) {
|
||||
dev_err(dev, "Insufficient omapfb_platform_data\n");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fbi->enable_fn = pdata->enable;
|
||||
fbi->displays = pdata->displays;
|
||||
fbi->num_displays = pdata->num_displays;
|
||||
fbi->divisor.dss_clk_hz = pdata->dss_clk_hz;
|
||||
|
||||
for (i = 0; i < pdata->num_displays; ++i)
|
||||
fbi->video_modes[i] = pdata->displays[i].mode;
|
||||
|
||||
info->mode_list = fbi->video_modes;
|
||||
info->num_modes = pdata->num_displays;
|
||||
|
||||
info->priv = fbi;
|
||||
info->fbops = &omapfb_ops;
|
||||
info->bits_per_pixel = pdata->bpp;
|
||||
|
||||
if (pdata->screen) {
|
||||
if (!IS_ALIGNED(pdata->screen->start, PAGE_SIZE) ||
|
||||
!IS_ALIGNED(resource_size(pdata->screen), PAGE_SIZE)) {
|
||||
dev_err(dev, "screen resource not aligned\n");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
fbi->prealloc_screen.addr =
|
||||
(void __iomem *)pdata->screen->start;
|
||||
fbi->prealloc_screen.size = resource_size(pdata->screen);
|
||||
remap_range(fbi->prealloc_screen.addr,
|
||||
fbi->prealloc_screen.size,
|
||||
mmu_get_pte_uncached_flags());
|
||||
}
|
||||
|
||||
rc = omapfb_reset(fbi);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "failed to reset: %d\n", rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = register_framebuffer(info);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "failed to register framebuffer: %d\n", rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
dev_info(dev, "registered\n");
|
||||
|
||||
out:
|
||||
if (rc < 0)
|
||||
free(fbi);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct driver_d omapfb_driver = {
|
||||
.name = "omap_fb",
|
||||
.probe = omapfb_probe,
|
||||
};
|
||||
|
||||
static int omapfb_init(void)
|
||||
{
|
||||
return platform_driver_register(&omapfb_driver);
|
||||
}
|
||||
|
||||
device_initcall(omapfb_init);
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* TI Omap4 Frame Buffer device driver
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Fritz <chf.fritz@googlemail.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef H_BAREBOX_DRIVER_VIDEO_OMAP4_REGS_H
|
||||
#define H_BAREBOX_DRIVER_VIDEO_OMAP4_REGS_H
|
||||
|
||||
#include <types.h>
|
||||
#include <common.h>
|
||||
|
||||
#define OFB_TIMEOUT (128 * USECOND)
|
||||
|
||||
#define _ofb_read(io, reg) __raw_readl((io)+(reg))
|
||||
#define _ofb_write(val, io, reg) __raw_writel((val), (io)+(reg))
|
||||
|
||||
/* TRM: 10.1.3.2 DSS Registers */
|
||||
#define O4_DSS_REVISION 0x0
|
||||
#define O4_DSS_SYSSTATUS 0x14
|
||||
#define O4_DSS_CTRL 0x40
|
||||
#define O4_DSS_STATUS 0x5c
|
||||
|
||||
#define o4_dss_read(reg) _ofb_read(fbi->dss, reg)
|
||||
#define o4_dss_write(val, reg) _ofb_write(val, fbi->dss, reg)
|
||||
|
||||
/* TRM: 10.2.7.3 Display Controller Registers */
|
||||
#define O4_DISPC_REVISION 0x0
|
||||
#define O4_DISPC_IRQSTATUS 0x18
|
||||
#define O4_DISPC_VID1_BA0 0xbc
|
||||
#define O4_DISPC_VID1_BA1 0xc0
|
||||
#define O4_DISPC_VID1_POSITION 0xc4
|
||||
#define O4_DISPC_VID1_SIZE 0xc8
|
||||
#define O4_DISPC_VID1_ATTRIBUTES 0xcc
|
||||
#define O4_DISPC_VID1_ROW_INC 0xd8
|
||||
#define O4_DISPC_VID1_PIXEL_INC 0xdc
|
||||
#define O4_DISPC_VID1_PICTURE_SIZE 0xe4
|
||||
#define O4_DISPC_VID1_PRELOAD 0x230
|
||||
#define O4_DISPC_CONTROL2 0x238
|
||||
#define O4_DISPC_DEFAULT_COLOR2 0x3ac
|
||||
#define O4_DISPC_SIZE_LCD2 0x3cc
|
||||
#define O4_DISPC_TIMING_H2 0x400
|
||||
#define O4_DISPC_TIMING_V2 0x404
|
||||
#define O4_DISPC_POL_FREQ2 0x408
|
||||
#define O4_DISPC_DIVISOR2 0x40c
|
||||
#define O4_DISPC_DIVISOR 0x804
|
||||
|
||||
#define o4_dispc_read(reg) _ofb_read(fbi->dispc, reg)
|
||||
#define o4_dispc_write(val, reg) _ofb_write(val, fbi->dispc, reg)
|
||||
|
||||
#define DSS_DISPC_VIDn_POSITION_VIDPOSX(_x) ((_x) << 0)
|
||||
#define DSS_DISPC_VIDn_POSITION_VIDPOSY(_y) ((_y) << 16)
|
||||
|
||||
#define DSS_DISPC_VIDn_PICTURE_SIZE_VIDORGSIZEX(_x) ((_x) << 0)
|
||||
#define DSS_DISPC_VIDn_PICTURE_SIZE_VIDORGSIZEY(_y) ((_y) << 16)
|
||||
|
||||
#define DSS_DISPC_VIDn_SIZE_VIDSIZEX(_x) ((_x) << 0)
|
||||
#define DSS_DISPC_VIDn_SIZE_VIDSIZEY(_y) ((_y) << 16)
|
||||
|
||||
#define DSS_DISPC_SIZE_LCD_PPL(_x) ((_x) << 0)
|
||||
#define DSS_DISPC_SIZE_LCD_LPP(_y) ((_y) << 16)
|
||||
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDENABLE (1u << 0)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(_fmt) ((_fmt) << 1)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_RGB12 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(4u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_ARGB16 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(5u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_RGB16 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(6u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_ARGB16o \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(7u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_xRGB24u \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(8u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_RGB24p \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(9u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_YUV2 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(10u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_UYVY \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(11u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_ARGB32 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(12u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_RGBA32 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(13u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT_xRGB32 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDFORMAT(14u)
|
||||
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE(_b) ((_b) << 14)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE_2x128 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE(0u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE_4x128 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE(1u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE_8x128 \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_VIDBURSTSIZE(2u)
|
||||
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDCHANNELOUT (1u << 16)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_SELFREFRESHAUTO (1u << 17)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDFIFOPRELOAD (1u << 19)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDVERTICALTAPS (1u << 21)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_DOUBLESTRIDE (1u << 22)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDARBITRATION (1u << 23)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_VIDSELFREFRESH (1u << 24)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_ZORDERENABLE (1u << 25)
|
||||
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2(_b) ((_b) << 30)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2_PRIMARY_LCD \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2(0u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2_SECONDARY_LCD \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2(1u)
|
||||
#define DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2_WRITEBACK_MEM \
|
||||
DSS_DISPC_VIDn_ATTRIBUTES_CHANNELOUT2(3u)
|
||||
|
||||
#define DSS_DISPC_CONTROL_LCDENABLE (1u << 0)
|
||||
#define DSS_DISPC_CONTROL_TVENABLE (1u << 1)
|
||||
#define DSS_DISPC_CONTROL_MONOCOLOR (1u << 2)
|
||||
#define DSS_DISPC_CONTROL_STNTFT (1u << 3)
|
||||
#define DSS_DISPC_CONTROL_M8B (1u << 4)
|
||||
#define DSS_DISPC_CONTROL_GOLCD (1u << 5)
|
||||
#define DSS_DISPC_CONTROL_GOTV (1u << 6)
|
||||
#define DSS_DISPC_CONTROL_STDITHERENABLE (1u << 7)
|
||||
|
||||
#define DSS_DISPC_CONTROL_TFTDATALINES(_l) ((_l) << 8)
|
||||
#define DSS_DISPC_CONTROL_TFTDATALINES_12 \
|
||||
DSS_DISPC_CONTROL_TFTDATALINES(0u)
|
||||
#define DSS_DISPC_CONTROL_TFTDATALINES_16 \
|
||||
DSS_DISPC_CONTROL_TFTDATALINES(1u)
|
||||
#define DSS_DISPC_CONTROL_TFTDATALINES_18 \
|
||||
DSS_DISPC_CONTROL_TFTDATALINES(2u)
|
||||
#define DSS_DISPC_CONTROL_TFTDATALINES_24 \
|
||||
DSS_DISPC_CONTROL_TFTDATALINES(3u)
|
||||
|
||||
#define DSS_DISPC_CONTROL_STALLMODE (1u << 11)
|
||||
#define DSS_DISPC_CONTROL_OVERLAYOPTIMIZATION (1u << 12)
|
||||
#define DSS_DISPC_CONTROL_GPIN0 (1u << 13) /* ro */
|
||||
#define DSS_DISPC_CONTROL_GPIN1 (1u << 14) /* ro */
|
||||
#define DSS_DISPC_CONTROL_GPOUT0 (1u << 15)
|
||||
#define DSS_DISPC_CONTROL_GPOUT1 (1u << 16)
|
||||
#define DSS_DISPC_CONTROL_HT(_ht) ((_ht) << 17)
|
||||
#define DSS_DISPC_CONTROL_TDMENABLE (1u << 20)
|
||||
#define DSS_DISPC_CONTROL_TDMPARALLELMODE(_pm) ((_pm) << 21)
|
||||
#define DSS_DISPC_CONTROL_TDMCYCLEFORMAT(_cf) ((_cf) << 23)
|
||||
#define DSS_DISPC_CONTROL_TDMUNUSEDBITS(_ub) ((_ub) << 25)
|
||||
#define DSS_DISPC_CONTROL_PCKFREEENABLE (1u << 27)
|
||||
#define DSS_DISPC_CONTROL_LCDENABLESIGNAL (1u << 28)
|
||||
#define DSS_DISPC_CONTROL_LCDENABLEPOL (1u << 29)
|
||||
#define DSS_DISPC_CONTROL_SPATIALTEMPD(_df) ((_df) << 30)
|
||||
|
||||
#define DSS_DISPC_POL_FREQ_IVS (1u << 12)
|
||||
#define DSS_DISPC_POL_FREQ_IHS (1u << 13)
|
||||
#define DSS_DISPC_POL_FREQ_IPC (1u << 14)
|
||||
#define DSS_DISPC_POL_FREQ_IEO (1u << 15)
|
||||
#define DSS_DISPC_POL_FREQ_RF (1u << 16)
|
||||
#define DSS_DISPC_POL_FREQ_ONOFF (1u << 17)
|
||||
|
||||
#define DSS_DISPC_TIMING_H_HSW(_hsw) ((_hsw) << 0)
|
||||
#define DSS_DISPC_TIMING_H_HFP(_hfp) ((_hfp) << 8)
|
||||
#define DSS_DISPC_TIMING_H_HBP(_hbp) ((_hbp) << 20)
|
||||
|
||||
#define DSS_DISPC_TIMING_V_VSW(_vsw) ((_vsw) << 0)
|
||||
#define DSS_DISPC_TIMING_V_VFP(_vfp) ((_vfp) << 8)
|
||||
#define DSS_DISPC_TIMING_V_VBP(_vbp) ((_vbp) << 20)
|
||||
|
||||
#define DSS_DISPC_DIVISOR_ENABLE (1u << 0)
|
||||
#define DSS_DISPC_DIVISOR_LCD(_lcd) ((_lcd) << 16)
|
||||
|
||||
#define DSS_DISPC_DIVISOR2_PCD(_pcd) ((_pcd) << 0)
|
||||
#define DSS_DISPC_DIVISOR2_LCD(_lcd) ((_lcd) << 16)
|
||||
|
||||
#define DSS_DISPC_IRQSTATUS_FRAMEDONE (1u << 0)
|
||||
#define DSS_DISPC_IRQSTATUS_FRAMEDONE2 (1u << 22)
|
||||
|
||||
#define DSS_DSS_SYSSTATUS_RESETDONE (1u << 0)
|
||||
|
||||
#endif /* H_BAREBOX_DRIVER_VIDEO_O4_REGS_H */
|
Loading…
Reference in New Issue