Commit aed886ce authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'davinci-for-linus' of...

Merge branch 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci

* 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci: (69 commits)
  davinci: Initial support for Neuros OSD2 platform.
  davinci: remove unused variable in arch/arm/mach-davinci/board-sffsdr.c
  davinci: fix section mismatch warning in arch/arm/mach-davinci/board-dm646x-evm.c
  DaVinci: DM365: Enable DaVinci RTC support for DM365 EVM
  DA8xx/OMAP-L1xx: Add high speed SD/MMC capabilities
  davinci: DA8XX/OMAP-L1XX: enable cpuidle and regulator in defconfig
  davinci: DA850/OMAP-L138: avoid using separate initcall for initializing regulator
  davinci: DA850/OMAP-L138 EVM: register for cpuidle support
  davinci: DA8XX/OMAP-L1XX: add support for cpuidle driver register
  davinci: add CPU idle driver
  davinci: DA8XX/OMAP-L1XX: fix compiler warning
  davinci: DA850/OMAP-L138: eliminate static function declaration
  davinci: DA850/OMAP-L138 EVM: simplify configuration of emac in MII/RMII mode
  davinci: DA850/OMAP-L138 EVM: get rid of DA850_UI_EXP config option
  davinci: DA850/OMAP-L138 EVM: implement autodetect of RMII PHY
  davinci: DA830/OMAP-L137 EVM: do not configure NAND on UI card when MMC/SD is selected
  davinci: DA830/OMAP-L137 EVM: use runtime detection for UI card
  davinci: DA830/OMAP-L137 EVM: remove ifdefs inside da830_evm_init()
  davinci: DA830/OMAP-L137 EVM: fix warning with default config
  davinci: Add NAND support for DA830/OMAP-L137 EVM platform
  ...
parents 67dd2f5a c16fe267
This diff is collapsed.
This diff is collapsed.
...@@ -32,11 +32,13 @@ config ARCH_DAVINCI_DA830 ...@@ -32,11 +32,13 @@ config ARCH_DAVINCI_DA830
bool "DA830/OMAP-L137 based system" bool "DA830/OMAP-L137 based system"
select CP_INTC select CP_INTC
select ARCH_DAVINCI_DA8XX select ARCH_DAVINCI_DA8XX
select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
config ARCH_DAVINCI_DA850 config ARCH_DAVINCI_DA850
bool "DA850/OMAP-L138 based system" bool "DA850/OMAP-L138 based system"
select CP_INTC select CP_INTC
select ARCH_DAVINCI_DA8XX select ARCH_DAVINCI_DA8XX
select ARCH_HAS_CPUFREQ
config ARCH_DAVINCI_DA8XX config ARCH_DAVINCI_DA8XX
bool bool
...@@ -63,6 +65,13 @@ config MACH_SFFSDR ...@@ -63,6 +65,13 @@ config MACH_SFFSDR
Say Y here to select the Lyrtech Small Form Factor Say Y here to select the Lyrtech Small Form Factor
Software Defined Radio (SFFSDR) board. Software Defined Radio (SFFSDR) board.
config MACH_NEUROS_OSD2
bool "Neuros OSD2 Open Television Set Top Box"
depends on ARCH_DAVINCI_DM644x
help
Configure this option to specify the whether the board used
for development is a Neuros OSD2 Open Set Top Box.
config MACH_DAVINCI_DM355_EVM config MACH_DAVINCI_DM355_EVM
bool "TI DM355 EVM" bool "TI DM355 EVM"
default ARCH_DAVINCI_DM355 default ARCH_DAVINCI_DM355
...@@ -98,16 +107,66 @@ config MACH_DAVINCI_DA830_EVM ...@@ -98,16 +107,66 @@ config MACH_DAVINCI_DA830_EVM
bool "TI DA830/OMAP-L137 Reference Platform" bool "TI DA830/OMAP-L137 Reference Platform"
default ARCH_DAVINCI_DA830 default ARCH_DAVINCI_DA830
depends on ARCH_DAVINCI_DA830 depends on ARCH_DAVINCI_DA830
select GPIO_PCF857X
help help
Say Y here to select the TI DA830/OMAP-L137 Evaluation Module. Say Y here to select the TI DA830/OMAP-L137 Evaluation Module.
choice
prompt "Select DA830/OMAP-L137 UI board peripheral"
depends on MACH_DAVINCI_DA830_EVM
help
The presence of UI card on the DA830/OMAP-L137 EVM is detected
automatically based on successful probe of the I2C based GPIO
expander on that board. This option selected in this menu has
an effect only in case of a successful UI card detection.
config DA830_UI_LCD
bool "LCD"
help
Say Y here to use the LCD as a framebuffer or simple character
display.
config DA830_UI_NAND
bool "NAND flash"
help
Say Y here to use the NAND flash. Do not forget to setup
the switch correctly.
endchoice
config MACH_DAVINCI_DA850_EVM config MACH_DAVINCI_DA850_EVM
bool "TI DA850/OMAP-L138 Reference Platform" bool "TI DA850/OMAP-L138 Reference Platform"
default ARCH_DAVINCI_DA850 default ARCH_DAVINCI_DA850
depends on ARCH_DAVINCI_DA850 depends on ARCH_DAVINCI_DA850
select GPIO_PCA953X
help help
Say Y here to select the TI DA850/OMAP-L138 Evaluation Module. Say Y here to select the TI DA850/OMAP-L138 Evaluation Module.
choice
prompt "Select peripherals connected to expander on UI board"
depends on MACH_DAVINCI_DA850_EVM
help
The presence of User Interface (UI) card on the DA850/OMAP-L138
EVM is detected automatically based on successful probe of the I2C
based GPIO expander on that card. This option selected in this
menu has an effect only in case of a successful UI card detection.
config DA850_UI_NONE
bool "No peripheral is enabled"
help
Say Y if you do not want to enable any of the peripherals connected
to TCA6416 expander on DA850/OMAP-L138 EVM UI card
config DA850_UI_RMII
bool "RMII Ethernet PHY"
help
Say Y if you want to use the RMII PHY on the DA850/OMAP-L138 EVM.
This PHY is found on the UI daughter card that is supplied with
the EVM.
NOTE: Please take care while choosing this option, MII PHY will
not be functional if RMII mode is selected.
endchoice
config DAVINCI_MUX config DAVINCI_MUX
bool "DAVINCI multiplexing support" bool "DAVINCI multiplexing support"
depends on ARCH_DAVINCI depends on ARCH_DAVINCI
......
...@@ -23,9 +23,14 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o ...@@ -23,9 +23,14 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o
# Board specific # Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o
obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o
obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o
obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
# Power Management
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
This diff is collapsed.
This diff is collapsed.
...@@ -9,15 +9,13 @@ ...@@ -9,15 +9,13 @@
* or implied. * or implied.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h> #include <linux/err.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
...@@ -25,20 +23,15 @@ ...@@ -25,20 +23,15 @@
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/eeprom.h> #include <linux/spi/eeprom.h>
#include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/hardware.h>
#include <mach/dm355.h> #include <mach/dm355.h>
#include <mach/psc.h>
#include <mach/common.h>
#include <mach/i2c.h> #include <mach/i2c.h>
#include <mach/serial.h> #include <mach/serial.h>
#include <mach/nand.h> #include <mach/nand.h>
#include <mach/mmc.h> #include <mach/mmc.h>
#include <mach/usb.h>
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
...@@ -86,8 +79,9 @@ static struct davinci_nand_pdata davinci_nand_data = { ...@@ -86,8 +79,9 @@ static struct davinci_nand_pdata davinci_nand_data = {
.mask_chipsel = BIT(14), .mask_chipsel = BIT(14),
.parts = davinci_nand_partitions, .parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions), .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
.ecc_mode = NAND_ECC_HW_SYNDROME, .ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT, .options = NAND_USE_FLASH_BBT,
.ecc_bits = 4,
}; };
static struct resource davinci_nand_resources[] = { static struct resource davinci_nand_resources[] = {
...@@ -344,7 +338,7 @@ static __init void dm355_evm_init(void) ...@@ -344,7 +338,7 @@ static __init void dm355_evm_init(void)
gpio_request(2, "usb_id_toggle"); gpio_request(2, "usb_id_toggle");
gpio_direction_output(2, USB_ID_VALUE); gpio_direction_output(2, USB_ID_VALUE);
/* irlml6401 switches over 1A in under 8 msec */ /* irlml6401 switches over 1A in under 8 msec */
setup_usb(500, 8); davinci_setup_usb(1000, 8);
davinci_setup_mmc(0, &dm355evm_mmc_config); davinci_setup_mmc(0, &dm355evm_mmc_config);
davinci_setup_mmc(1, &dm355evm_mmc_config); davinci_setup_mmc(1, &dm355evm_mmc_config);
......
...@@ -8,34 +8,27 @@ ...@@ -8,34 +8,27 @@
* warranty of any kind, whether express or implied. * warranty of any kind, whether express or implied.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h> #include <linux/err.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/eeprom.h> #include <linux/spi/eeprom.h>
#include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/hardware.h>
#include <mach/dm355.h> #include <mach/dm355.h>
#include <mach/psc.h>
#include <mach/common.h>
#include <mach/i2c.h> #include <mach/i2c.h>
#include <mach/serial.h> #include <mach/serial.h>
#include <mach/nand.h> #include <mach/nand.h>
#include <mach/mmc.h> #include <mach/mmc.h>
#include <mach/usb.h>
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
...@@ -270,7 +263,7 @@ static __init void dm355_leopard_init(void) ...@@ -270,7 +263,7 @@ static __init void dm355_leopard_init(void)
gpio_request(2, "usb_id_toggle"); gpio_request(2, "usb_id_toggle");
gpio_direction_output(2, USB_ID_VALUE); gpio_direction_output(2, USB_ID_VALUE);
/* irlml6401 switches over 1A in under 8 msec */ /* irlml6401 switches over 1A in under 8 msec */
setup_usb(500, 8); davinci_setup_usb(1000, 8);
davinci_setup_mmc(0, &dm355leopard_mmc_config); davinci_setup_mmc(0, &dm355leopard_mmc_config);
davinci_setup_mmc(1, &dm355leopard_mmc_config); davinci_setup_mmc(1, &dm355leopard_mmc_config);
......
...@@ -13,9 +13,8 @@ ...@@ -13,9 +13,8 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h> #include <linux/err.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clk.h> #include <linux/clk.h>
...@@ -24,20 +23,19 @@ ...@@ -24,20 +23,19 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <asm/setup.h> #include <linux/input.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/mux.h> #include <mach/mux.h>
#include <mach/hardware.h>
#include <mach/dm365.h> #include <mach/dm365.h>
#include <mach/psc.h>
#include <mach/common.h> #include <mach/common.h>
#include <mach/i2c.h> #include <mach/i2c.h>
#include <mach/serial.h> #include <mach/serial.h>
#include <mach/mmc.h> #include <mach/mmc.h>
#include <mach/nand.h> #include <mach/nand.h>
#include <mach/keyscan.h>
static inline int have_imager(void) static inline int have_imager(void)
{ {
...@@ -144,6 +142,7 @@ static struct davinci_nand_pdata davinci_nand_data = { ...@@ -144,6 +142,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
.nr_parts = ARRAY_SIZE(davinci_nand_partitions), .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
.ecc_mode = NAND_ECC_HW, .ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT, .options = NAND_USE_FLASH_BBT,
.ecc_bits = 4,
}; };
static struct resource davinci_nand_resources[] = { static struct resource davinci_nand_resources[] = {
...@@ -176,11 +175,16 @@ static struct at24_platform_data eeprom_info = { ...@@ -176,11 +175,16 @@ static struct at24_platform_data eeprom_info = {
.context = (void *)0x7f00, .context = (void *)0x7f00,
}; };
static struct snd_platform_data dm365_evm_snd_data;
static struct i2c_board_info i2c_info[] = { static struct i2c_board_info i2c_info[] = {
{ {
I2C_BOARD_INFO("24c256", 0x50), I2C_BOARD_INFO("24c256", 0x50),
.platform_data = &eeprom_info, .platform_data = &eeprom_info,
}, },
{
I2C_BOARD_INFO("tlv320aic3x", 0x18),
},
}; };
static struct davinci_i2c_platform_data i2c_pdata = { static struct davinci_i2c_platform_data i2c_pdata = {
...@@ -188,6 +192,38 @@ static struct davinci_i2c_platform_data i2c_pdata = { ...@@ -188,6 +192,38 @@ static struct davinci_i2c_platform_data i2c_pdata = {
.bus_delay = 0 /* usec */, .bus_delay = 0 /* usec */,
}; };
#ifdef CONFIG_KEYBOARD_DAVINCI
static unsigned short dm365evm_keymap[] = {
KEY_KP2,
KEY_LEFT,
KEY_EXIT,
KEY_DOWN,
KEY_ENTER,
KEY_UP,
KEY_KP1,
KEY_RIGHT,
KEY_MENU,
KEY_RECORD,
KEY_REWIND,
KEY_KPMINUS,
KEY_STOP,
KEY_FASTFORWARD,
KEY_KPPLUS,
KEY_PLAYPAUSE,
0
};
static struct davinci_ks_platform_data dm365evm_ks_data = {
.keymap = dm365evm_keymap,
.keymapsize = ARRAY_SIZE(dm365evm_keymap),
.rep = 1,
/* Scan period = strobe + interval */
.strobe = 0x5,
.interval = 0x2,
.matrix_type = DAVINCI_KEYSCAN_MATRIX_4X4,
};
#endif
static int cpld_mmc_get_cd(int module) static int cpld_mmc_get_cd(int module)
{ {
if (!cpld) if (!cpld)
...@@ -472,6 +508,13 @@ static __init void dm365_evm_init(void) ...@@ -472,6 +508,13 @@ static __init void dm365_evm_init(void)
/* maybe setup mmc1/etc ... _after_ mmc0 */ /* maybe setup mmc1/etc ... _after_ mmc0 */
evm_init_cpld(); evm_init_cpld();
dm365_init_asp(&dm365_evm_snd_data);
dm365_init_rtc();
#ifdef CONFIG_KEYBOARD_DAVINCI
dm365_init_ks(&dm365evm_ks_data);
#endif
} }
static __init void dm365_evm_irq_init(void) static __init void dm365_evm_irq_init(void)
......
...@@ -9,45 +9,34 @@ ...@@ -9,45 +9,34 @@
* or implied. * or implied.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/memory.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c/pcf857x.h> #include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h> #include <linux/i2c/at24.h>
#include <linux/etherdevice.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/io.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <media/tvp514x.h> #include <media/tvp514x.h>
#include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/dm644x.h> #include <mach/dm644x.h>
#include <mach/common.h> #include <mach/common.h>
#include <mach/i2c.h> #include <mach/i2c.h>
#include <mach/serial.h> #include <mach/serial.h>
#include <mach/mux.h> #include <mach/mux.h>
#include <mach/psc.h>
#include <mach/nand.h> #include <mach/nand.h>
#include <mach/mmc.h> #include <mach/mmc.h>
#include <mach/emac.h> #include <mach/usb.h>
#define DM644X_EVM_PHY_MASK (0x2) #define DM644X_EVM_PHY_MASK (0x2)
#define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
...@@ -477,7 +466,7 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) ...@@ -477,7 +466,7 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
/* irlml6401 switches over 1A, in under 8 msec; /* irlml6401 switches over 1A, in under 8 msec;
* now it can be managed by nDRV_VBUS ... * now it can be managed by nDRV_VBUS ...
*/ */
setup_usb(500, 8); davinci_setup_usb(1000, 8);
return 0; return 0;
} }
......
...@@ -17,38 +17,28 @@ ...@@ -17,38 +17,28 @@
**************************************************************************/ **************************************************************************/
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/root_dev.h>
#include <linux/dma-mapping.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/io.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c/at24.h> #include <linux/i2c/at24.h>
#include <linux/i2c/pcf857x.h> #include <linux/i2c/pcf857x.h>
#include <linux/etherdevice.h>
#include <media/tvp514x.h> #include <media/tvp514x.h>
#include <asm/setup.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/dm646x.h> #include <mach/dm646x.h>
#include <mach/common.h> #include <mach/common.h>
#include <mach/psc.h>
#include <mach/serial.h> #include <mach/serial.h>
#include <mach/i2c.h> #include <mach/i2c.h>
#include <mach/mmc.h> #include <mach/nand.h>
#include <mach/emac.h>
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
...@@ -57,6 +47,11 @@ ...@@ -57,6 +47,11 @@
#define HAS_ATA 0 #define HAS_ATA 0
#endif #endif
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x20008000
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x42000000
#define NAND_BLOCK_SIZE SZ_128K
/* CPLD Register 0 bits to control ATA */ /* CPLD Register 0 bits to control ATA */
#define DM646X_EVM_ATA_RST BIT(0) #define DM646X_EVM_ATA_RST BIT(0)
#define DM646X_EVM_ATA_PWD BIT(1) #define DM646X_EVM_ATA_PWD BIT(1)
...@@ -92,6 +87,63 @@ static struct davinci_uart_config uart_config __initdata = { ...@@ -92,6 +87,63 @@ static struct davinci_uart_config uart_config __initdata = {
.enabled_uarts = (1 << 0), .enabled_uarts = (1 << 0),
}; };
/* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot
* and U-Boot environment this avoids dependency on any particular combination
* of UBL, U-Boot or flashing tools etc.
*/
static struct mtd_partition davinci_nand_partitions[] = {
{
/* UBL, U-Boot with environment */
.name = "bootloader",
.offset = MTDPART_OFS_APPEND,
.size = 16 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_4M,
.mask_flags = 0,
}, {
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
.mask_flags = 0,
}
};
static struct davinci_nand_pdata davinci_nand_data = {
.mask_cle = 0x80000,
.mask_ale = 0x40000,
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
.ecc_mode = NAND_ECC_HW,
.options = 0,
};
static struct resource davinci_nand_resources[] = {
{
.start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
.end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
.flags = IORESOURCE_MEM,
}, {
.start = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
.end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device davinci_nand_device = {
.name = "davinci_nand",
.id = 0,
.num_resources = ARRAY_SIZE(davinci_nand_resources),
.resource = davinci_nand_resources,
.dev = {
.platform_data = &davinci_nand_data,
},
};
/* CPLD Register 0 Client: used for I/O Control */ /* CPLD Register 0 Client: used for I/O Control */
static int cpld_reg0_probe(struct i2c_client *client, static int cpld_reg0_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
...@@ -142,7 +194,7 @@ static struct gpio_led evm_leds[] = { ...@@ -142,7 +194,7 @@ static struct gpio_led evm_leds[] = {
{ .name = "DS4", .active_low = 1, }, { .name = "DS4", .active_low = 1, },
}; };
static __initconst struct gpio_led_platform_data evm_led_data = { static const struct gpio_led_platform_data evm_led_data = {
.num_leds = ARRAY_SIZE(evm_leds), .num_leds = ARRAY_SIZE(evm_leds),
.leds = evm_leds, .leds = evm_leds,
}; };
...@@ -647,6 +699,8 @@ static __init void evm_init(void) ...@@ -647,6 +699,8 @@ static __init void evm_init(void)
dm646x_init_mcasp0(&dm646x_evm_snd_data[0]); dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
dm646x_init_mcasp1(&dm646x_evm_snd_data[1]); dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
platform_device_register(&davinci_nand_device);
if (HAS_ATA) if (HAS_ATA)
dm646x_init_ide(); dm646x_init_ide();
......
/*
* Neuros Technologies OSD2 board support
*
* Modified from original 644X-EVM board support.
* 2008 (c) Neuros Technology, LLC.
* 2009 (c) Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
* 2009 (c) Andrey A. Porodko <Andrey.Porodko@gmail.com>
*
* The Neuros OSD 2.0 is the hardware component of the Neuros Open
* Internet Television Platform. Hardware is very close to TI
* DM644X-EVM board. It has:
* DM6446M02 module with 256MB NAND, 256MB RAM, TLV320AIC32 AIC,
* USB, Ethernet, SD/MMC, UART, THS8200, TVP7000 for video.
* Additionaly realtime clock, IR remote control receiver,
* IR Blaster based on MSP430 (firmware although is different
* from used in DM644X-EVM), internal ATA-6 3.5” HDD drive
* with PATA interface, two muxed red-green leds.
*
* For more information please refer to
* http://wiki.neurostechnology.com/index.php/OSD_2.0_HD
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/mtd/partitions.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/dm644x.h>
#include <mach/i2c.h>
#include <mach/serial.h>
#include <mach/mux.h>
#include <mach/nand.h>
#include <mach/mmc.h>
#include <mach/usb.h>
#define NEUROS_OSD2_PHY_MASK 0x2
#define NEUROS_OSD2_MDIO_FREQUENCY 2200000 /* PHY bus frequency */
#define DAVINCI_CFC_ATA_BASE 0x01C66000
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
#define LXT971_PHY_ID 0x001378e2
#define LXT971_PHY_MASK 0xfffffff0
#define NTOSD2_AUDIOSOC_I2C_ADDR 0x18
#define NTOSD2_MSP430_I2C_ADDR 0x59
#define NTOSD2_MSP430_IRQ 2
/* Neuros OSD2 has a Samsung 256 MByte NAND flash (Dev ID of 0xAA,
* 2048 blocks in the device, 64 pages per block, 2048 bytes per
* page.
*/
#define NAND_BLOCK_SIZE SZ_128K
struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
{
/* UBL (a few copies) plus U-Boot */
.name = "bootloader",
.offset = 0,
.size = 15 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
/* U-Boot environment */
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 1 * NAND_BLOCK_SIZE,
.mask_flags = 0,
}, {
/* Kernel */
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_4M,
.mask_flags = 0,
}, {
/* File System */
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
.mask_flags = 0,
}
/* A few blocks at end hold a flash Bad Block Table. */
};
static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
.parts = davinci_ntosd2_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
};
static struct resource davinci_ntosd2_nandflash_resource[] = {
{
.start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
.end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
.flags = IORESOURCE_MEM,
}, {
.start = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
.end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device davinci_ntosd2_nandflash_device = {
.name = "davinci_nand",
.id = 0,
.dev = {
.platform_data = &davinci_ntosd2_nandflash_data,
},
.num_resources = ARRAY_SIZE(davinci_ntosd2_nandflash_resource),
.resource = davinci_ntosd2_nandflash_resource,
};
static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
static struct platform_device davinci_fb_device = {
.name = "davincifb",
.id = -1,
.dev = {
.dma_mask = &davinci_fb_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = 0,
};
static struct resource ide_resources[] = {
{
.start = DAVINCI_CFC_ATA_BASE,
.end = DAVINCI_CFC_ATA_BASE + 0x7ff,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_IDE,
.end = IRQ_IDE,
.flags = IORESOURCE_IRQ,
},
};
static u64 ide_dma_mask = DMA_BIT_MASK(32);
static struct platform_device ide_dev = {
.name = "palm_bk3710",
.id = -1,
.resource = ide_resources,
.num_resources = ARRAY_SIZE(ide_resources),
.dev = {
.dma_mask = &ide_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static struct snd_platform_data dm644x_ntosd2_snd_data;
static struct gpio_led ntosd2_leds[] = {
{ .name = "led1_green", .gpio = GPIO(10), },
{ .name = "led1_red", .gpio = GPIO(11), },
{ .name = "led2_green", .gpio = GPIO(12), },
{ .name = "led2_red", .gpio = GPIO(13), },
};
static struct gpio_led_platform_data ntosd2_leds_data = {
.num_leds = ARRAY_SIZE(ntosd2_leds),
.leds = ntosd2_leds,
};
static struct platform_device ntosd2_leds_dev = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &ntosd2_leds_data,
},
};
static struct platform_device *davinci_ntosd2_devices[] __initdata = {
&davinci_fb_device,
&ntosd2_leds_dev,
};
static struct davinci_uart_config uart_config __initdata = {
.enabled_uarts = (1 << 0),
};
static void __init davinci_ntosd2_map_io(void)
{
dm644x_init();
}
/*
I2C initialization
*/
static struct davinci_i2c_platform_data ntosd2_i2c_pdata = {
.bus_freq = 20 /* kHz */,
.bus_delay = 100 /* usec */,
};
static struct i2c_board_info __initdata ntosd2_i2c_info[] = {
};
static int ntosd2_init_i2c(void)
{
int status;
davinci_init_i2c(&ntosd2_i2c_pdata);
status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type);
if (status == 0) {
status = gpio_direction_input(NTOSD2_MSP430_IRQ);
if (status == 0) {
status = gpio_to_irq(NTOSD2_MSP430_IRQ);
if (status > 0) {
ntosd2_i2c_info[0].irq = status;
i2c_register_board_info(1,
ntosd2_i2c_info,
ARRAY_SIZE(ntosd2_i2c_info));
}
}
}
return status;
}
static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
.wires = 4,
.version = MMC_CTLR_VERSION_1
};
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
#define HAS_ATA 1
#else
#define HAS_ATA 0
#endif
#if defined(CONFIG_MTD_NAND_DAVINCI) || \
defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
#define HAS_NAND 1
#else
#define HAS_NAND 0
#endif
static __init void davinci_ntosd2_init(void)
{
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
int status;
aemif_clk = clk_get(NULL, "aemif");
clk_enable(aemif_clk);
if (HAS_ATA) {
if (HAS_NAND)
pr_warning("WARNING: both IDE and Flash are "
"enabled, but they share AEMIF pins.\n"
"\tDisable IDE for NAND/NOR support.\n");
davinci_cfg_reg(DM644X_HPIEN_DISABLE);
davinci_cfg_reg(DM644X_ATAEN);
davinci_cfg_reg(DM644X_HDIREN);
platform_device_register(&ide_dev);
} else if (HAS_NAND) {
davinci_cfg_reg(DM644X_HPIEN_DISABLE);
davinci_cfg_reg(DM644X_ATAEN_DISABLE);
/* only one device will be jumpered and detected */
if (HAS_NAND)
platform_device_register(
&davinci_ntosd2_nandflash_device);
}
platform_add_devices(davinci_ntosd2_devices,
ARRAY_SIZE(davinci_ntosd2_devices));
/* Initialize I2C interface specific for this board */
status = ntosd2_init_i2c();
if (status < 0)
pr_warning("davinci_ntosd2_init: msp430 irq setup failed:"
" %d\n", status);
davinci_serial_init(&uart_config);
dm644x_init_asp(&dm644x_ntosd2_snd_data);
soc_info->emac_pdata->phy_mask = NEUROS_OSD2_PHY_MASK;
soc_info->emac_pdata->mdio_max_freq = NEUROS_OSD2_MDIO_FREQUENCY;
davinci_setup_usb(1000, 8);
/*
* Mux the pins to be GPIOs, VLYNQEN is already done at startup.
* The AEAWx are five new AEAW pins that can be muxed by separately.
* They are a bitmask for GPIO management. According TI
* documentation (http://www.ti.com/lit/gpn/tms320dm6446) to employ
* gpio(10,11,12,13) for leds any combination of bits works except
* four last. So we are to reset all five.
*/
davinci_cfg_reg(DM644X_AEAW0);
davinci_cfg_reg(DM644X_AEAW1);
davinci_cfg_reg(DM644X_AEAW2);
davinci_cfg_reg(DM644X_AEAW3);
davinci_cfg_reg(DM644X_AEAW4);
davinci_setup_mmc(0, &davinci_ntosd2_mmc_config);
}
static __init void davinci_ntosd2_irq_init(void)
{
davinci_irq_init();
}
MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
/* Maintainer: Neuros Technologies <neuros@groups.google.com> */
.phys_io = IO_PHYS,
.io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DAVINCI_DDR_BASE + 0x100),
.map_io = davinci_ntosd2_map_io,
.init_irq = davinci_ntosd2_irq_init,
.timer = &davinci_timer,
.init_machine = davinci_ntosd2_init,
MACHINE_END
...@@ -23,35 +23,24 @@ ...@@ -23,35 +23,24 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c/at24.h> #include <linux/i2c/at24.h>
#include <linux/etherdevice.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/io.h>
#include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
#include <mach/dm644x.h> #include <mach/dm644x.h>
#include <mach/common.h> #include <mach/common.h>
#include <mach/i2c.h> #include <mach/i2c.h>
#include <mach/serial.h> #include <mach/serial.h>
#include <mach/psc.h>
#include <mach/mux.h> #include <mach/mux.h>
#include <mach/usb.h>
#define SFFSDR_PHY_MASK (0x2) #define SFFSDR_PHY_MASK (0x2)
#define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ #define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
...@@ -107,11 +96,6 @@ static struct platform_device davinci_sffsdr_nandflash_device = { ...@@ -107,11 +96,6 @@ static struct platform_device davinci_sffsdr_nandflash_device = {
.resource = davinci_sffsdr_nandflash_resource, .resource = davinci_sffsdr_nandflash_resource,
}; };
static struct emac_platform_data sffsdr_emac_pdata = {
.phy_mask = SFFSDR_PHY_MASK,
.mdio_max_freq = SFFSDR_MDIO_FREQUENCY,
};
static struct at24_platform_data eeprom_info = { static struct at24_platform_data eeprom_info = {
.byte_len = (64*1024) / 8, .byte_len = (64*1024) / 8,
.page_size = 32, .page_size = 32,
...@@ -164,7 +148,7 @@ static __init void davinci_sffsdr_init(void) ...@@ -164,7 +148,7 @@ static __init void davinci_sffsdr_init(void)
davinci_serial_init(&uart_config); davinci_serial_init(&uart_config);
soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK; soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK;
soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY; soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY;
setup_usb(0, 0); /* We support only peripheral mode. */ davinci_setup_usb(0, 0); /* We support only peripheral mode. */
/* mux VLYNQ pins */ /* mux VLYNQ pins */
davinci_cfg_reg(DM644X_VLYNQEN); davinci_cfg_reg(DM644X_VLYNQEN);
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/delay.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -42,8 +42,7 @@ static void __clk_enable(struct clk *clk) ...@@ -42,8 +42,7 @@ static void __clk_enable(struct clk *clk)
if (clk->parent) if (clk->parent)
__clk_enable(clk->parent); __clk_enable(clk->parent);
if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
davinci_psc_config(psc_domain(clk), clk->psc_ctlr, davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 1);
clk->lpsc, 1);
} }
static void __clk_disable(struct clk *clk) static void __clk_disable(struct clk *clk)
...@@ -51,8 +50,7 @@ static void __clk_disable(struct clk *clk) ...@@ -51,8 +50,7 @@ static void __clk_disable(struct clk *clk)
if (WARN_ON(clk->usecount == 0)) if (WARN_ON(clk->usecount == 0))
return; return;
if (--clk->usecount == 0 && !(clk->flags & CLK_PLL)) if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
davinci_psc_config(psc_domain(clk), clk->psc_ctlr, davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
clk->lpsc, 0);
if (clk->parent) if (clk->parent)
__clk_disable(clk->parent); __clk_disable(clk->parent);
} }
...@@ -99,20 +97,74 @@ long clk_round_rate(struct clk *clk, unsigned long rate) ...@@ -99,20 +97,74 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
if (clk == NULL || IS_ERR(clk)) if (clk == NULL || IS_ERR(clk))
return -EINVAL; return -EINVAL;
if (clk->round_rate)
return clk->round_rate(clk, rate);
return clk->rate; return clk->rate;
} }
EXPORT_SYMBOL(clk_round_rate); EXPORT_SYMBOL(clk_round_rate);
/* Propagate rate to children */
static void propagate_rate(struct clk *root)
{
struct clk *clk;
list_for_each_entry(clk, &root->children, childnode) {
if (clk->recalc)
clk->rate = clk->recalc(clk);
propagate_rate(clk);
}
}
int clk_set_rate(struct clk *clk, unsigned long rate) int clk_set_rate(struct clk *clk, unsigned long rate)
{ {
unsigned long flags;
int ret = -EINVAL;
if (clk == NULL || IS_ERR(clk)) if (clk == NULL || IS_ERR(clk))
return -EINVAL; return ret;
/* changing the clk rate is not supported */ spin_lock_irqsave(&clockfw_lock, flags);
return -EINVAL; if (clk->set_rate)
ret = clk->set_rate(clk, rate);
if (ret == 0) {
if (clk->recalc)
clk->rate = clk->recalc(clk);
propagate_rate(clk);
}
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
} }
EXPORT_SYMBOL(clk_set_rate); EXPORT_SYMBOL(clk_set_rate);
int clk_set_parent(struct clk *clk, struct clk *parent)
{
unsigned long flags;
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
/* Cannot change parent on enabled clock */
if (WARN_ON(clk->usecount))
return -EINVAL;
mutex_lock(&clocks_mutex);
clk->parent = parent;
list_del_init(&clk->childnode);
list_add(&clk->childnode, &clk->parent->children);
mutex_unlock(&clocks_mutex);
spin_lock_irqsave(&clockfw_lock, flags);
if (clk->recalc)
clk->rate = clk->recalc(clk);
propagate_rate(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return 0;
}
EXPORT_SYMBOL(clk_set_parent);
int clk_register(struct clk *clk) int clk_register(struct clk *clk)
{ {
if (clk == NULL || IS_ERR(clk)) if (clk == NULL || IS_ERR(clk))
...@@ -123,16 +175,24 @@ int clk_register(struct clk *clk) ...@@ -123,16 +175,24 @@ int clk_register(struct clk *clk)
clk->name, clk->parent->name)) clk->name, clk->parent->name))
return -EINVAL; return -EINVAL;
INIT_LIST_HEAD(&clk->children);
mutex_lock(&clocks_mutex); mutex_lock(&clocks_mutex);
list_add_tail(&clk->node, &clocks); list_add_tail(&clk->node, &clocks);
if (clk->parent)
list_add_tail(&clk->childnode, &clk->parent->children);
mutex_unlock(&clocks_mutex); mutex_unlock(&clocks_mutex);
/* If rate is already set, use it */ /* If rate is already set, use it */
if (clk->rate) if (clk->rate)
return 0; return 0;
/* Else, see if there is a way to calculate it */
if (clk->recalc)
clk->rate = clk->recalc(clk);
/* Otherwise, default to parent rate */ /* Otherwise, default to parent rate */
if (clk->parent) else if (clk->parent)
clk->rate = clk->parent->rate; clk->rate = clk->parent->rate;
return 0; return 0;
...@@ -146,6 +206,7 @@ void clk_unregister(struct clk *clk) ...@@ -146,6 +206,7 @@ void clk_unregister(struct clk *clk)
mutex_lock(&clocks_mutex); mutex_lock(&clocks_mutex);
list_del(&clk->node); list_del(&clk->node);
list_del(&clk->childnode);
mutex_unlock(&clocks_mutex); mutex_unlock(&clocks_mutex);
} }
EXPORT_SYMBOL(clk_unregister); EXPORT_SYMBOL(clk_unregister);
...@@ -166,11 +227,11 @@ static int __init clk_disable_unused(void) ...@@ -166,11 +227,11 @@ static int __init clk_disable_unused(void)
continue; continue;
/* ignore if in Disabled or SwRstDisable states */ /* ignore if in Disabled or SwRstDisable states */
if (!davinci_psc_is_clk_active(ck->psc_ctlr, ck->lpsc)) if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
continue; continue;
pr_info("Clocks: disable unused %s\n", ck->name); pr_info("Clocks: disable unused %s\n", ck->name);
davinci_psc_config(psc_domain(ck), ck->psc_ctlr, ck->lpsc, 0); davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, 0);
} }
spin_unlock_irq(&clockfw_lock); spin_unlock_irq(&clockfw_lock);
...@@ -179,50 +240,62 @@ static int __init clk_disable_unused(void) ...@@ -179,50 +240,62 @@ static int __init clk_disable_unused(void)
late_initcall(clk_disable_unused); late_initcall(clk_disable_unused);
#endif #endif
static void clk_sysclk_recalc(struct clk *clk) static unsigned long clk_sysclk_recalc(struct clk *clk)
{ {
u32 v, plldiv; u32 v, plldiv;
struct pll_data *pll; struct pll_data *pll;
unsigned long rate = clk->rate;
/* If this is the PLL base clock, no more calculations needed */ /* If this is the PLL base clock, no more calculations needed */
if (clk->pll_data) if (clk->pll_data)
return; return rate;
if (WARN_ON(!clk->parent)) if (WARN_ON(!clk->parent))
return; return rate;
clk->rate = clk->parent->rate; rate = clk->parent->rate;
/* Otherwise, the parent must be a PLL */ /* Otherwise, the parent must be a PLL */
if (WARN_ON(!clk->parent->pll_data)) if (WARN_ON(!clk->parent->pll_data))
return; return rate;
pll = clk->parent->pll_data; pll = clk->parent->pll_data;
/* If pre-PLL, source clock is before the multiplier and divider(s) */ /* If pre-PLL, source clock is before the multiplier and divider(s) */
if (clk->flags & PRE_PLL) if (clk->flags & PRE_PLL)
clk->rate = pll->input_rate; rate = pll->input_rate;
if (!clk->div_reg) if (!clk->div_reg)
return; return rate;
v = __raw_readl(pll->base + clk->div_reg); v = __raw_readl(pll->base + clk->div_reg);
if (v & PLLDIV_EN) { if (v & PLLDIV_EN) {
plldiv = (v & PLLDIV_RATIO_MASK) + 1; plldiv = (v & PLLDIV_RATIO_MASK) + 1;
if (plldiv) if (plldiv)
clk->rate /= plldiv; rate /= plldiv;
} }
return rate;
}
static unsigned long clk_leafclk_recalc(struct clk *clk)
{
if (WARN_ON(!clk->parent))
return clk->rate;
return clk->parent->rate;
} }
static void __init clk_pll_init(struct clk *clk) static unsigned long clk_pllclk_recalc(struct clk *clk)
{ {
u32 ctrl, mult = 1, prediv = 1, postdiv = 1; u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
u8 bypass; u8 bypass;
struct pll_data *pll = clk->pll_data; struct pll_data *pll = clk->pll_data;
unsigned long rate = clk->rate;
pll->base = IO_ADDRESS(pll->phys_base); pll->base = IO_ADDRESS(pll->phys_base);
ctrl = __raw_readl(pll->base + PLLCTL); ctrl = __raw_readl(pll->base + PLLCTL);
clk->rate = pll->input_rate = clk->parent->rate; rate = pll->input_rate = clk->parent->rate;
if (ctrl & PLLCTL_PLLEN) { if (ctrl & PLLCTL_PLLEN) {
bypass = 0; bypass = 0;
...@@ -255,9 +328,9 @@ static void __init clk_pll_init(struct clk *clk) ...@@ -255,9 +328,9 @@ static void __init clk_pll_init(struct clk *clk)
} }
if (!bypass) { if (!bypass) {
clk->rate /= prediv; rate /= prediv;
clk->rate *= mult; rate *= mult;
clk->rate /= postdiv; rate /= postdiv;
} }
pr_debug("PLL%d: input = %lu MHz [ ", pr_debug("PLL%d: input = %lu MHz [ ",
...@@ -270,8 +343,90 @@ static void __init clk_pll_init(struct clk *clk) ...@@ -270,8 +343,90 @@ static void __init clk_pll_init(struct clk *clk)
pr_debug("* %d ", mult); pr_debug("* %d ", mult);
if (postdiv > 1) if (postdiv > 1)
pr_debug("/ %d ", postdiv); pr_debug("/ %d ", postdiv);
pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000); pr_debug("] --> %lu MHz output.\n", rate / 1000000);
return rate;
}
/**
* davinci_set_pllrate - set the output rate of a given PLL.
*
* Note: Currently tested to work with OMAP-L138 only.
*
* @pll: pll whose rate needs to be changed.
* @prediv: The pre divider value. Passing 0 disables the pre-divider.
* @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
* @postdiv: The post divider value. Passing 0 disables the post-divider.
*/
int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
unsigned int mult, unsigned int postdiv)
{
u32 ctrl;
unsigned int locktime;
if (pll->base == NULL)
return -EINVAL;
/*
* PLL lock time required per OMAP-L138 datasheet is
* (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
* as 4 and OSCIN cycle as 25 MHz.
*/
if (prediv) {
locktime = ((2000 * prediv) / 100);
prediv = (prediv - 1) | PLLDIV_EN;
} else {
locktime = 20;
}
if (postdiv)
postdiv = (postdiv - 1) | PLLDIV_EN;
if (mult)
mult = mult - 1;
ctrl = __raw_readl(pll->base + PLLCTL);
/* Switch the PLL to bypass mode */
ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
__raw_writel(ctrl, pll->base + PLLCTL);
/*
* Wait for 4 OSCIN/CLKIN cycles to ensure that the PLLC has switched
* to bypass mode. Delay of 1us ensures we are good for all > 4MHz
* OSCIN/CLKIN inputs. Typically the input is ~25MHz.
*/
udelay(1);
/* Reset and enable PLL */
ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
__raw_writel(ctrl, pll->base + PLLCTL);
if (pll->flags & PLL_HAS_PREDIV)
__raw_writel(prediv, pll->base + PREDIV);
__raw_writel(mult, pll->base + PLLM);
if (pll->flags & PLL_HAS_POSTDIV)
__raw_writel(postdiv, pll->base + POSTDIV);
/*
* Wait for PLL to reset properly, OMAP-L138 datasheet says
* 'min' time = 125ns
*/
udelay(1);
/* Bring PLL out of reset */
ctrl |= PLLCTL_PLLRST;
__raw_writel(ctrl, pll->base + PLLCTL);
udelay(locktime);
/* Remove PLL from bypass mode */
ctrl |= PLLCTL_PLLEN;
__raw_writel(ctrl, pll->base + PLLCTL);
return 0;
} }
EXPORT_SYMBOL(davinci_set_pllrate);
int __init davinci_clk_init(struct davinci_clk *clocks) int __init davinci_clk_init(struct davinci_clk *clocks)
{ {
...@@ -281,12 +436,23 @@ int __init davinci_clk_init(struct davinci_clk *clocks) ...@@ -281,12 +436,23 @@ int __init davinci_clk_init(struct davinci_clk *clocks)
for (c = clocks; c->lk.clk; c++) { for (c = clocks; c->lk.clk; c++) {
clk = c->lk.clk; clk = c->lk.clk;
if (clk->pll_data) if (!clk->recalc) {
clk_pll_init(clk);
/* Check if clock is a PLL */
if (clk->pll_data)
clk->recalc = clk_pllclk_recalc;
/* Else, if it is a PLL-derived clock */
else if (clk->flags & CLK_PLL)
clk->recalc = clk_sysclk_recalc;
/* Otherwise, it is a leaf clock (PSC clock) */
else if (clk->parent)
clk->recalc = clk_leafclk_recalc;
}
/* Calculate rates for PLL-derived clocks */ if (clk->recalc)
else if (clk->flags & CLK_PLL) clk->rate = clk->recalc(clk);
clk_sysclk_recalc(clk);
if (clk->lpsc) if (clk->lpsc)
clk->flags |= CLK_PSC; clk->flags |= CLK_PSC;
...@@ -352,9 +518,8 @@ dump_clock(struct seq_file *s, unsigned nest, struct clk *parent) ...@@ -352,9 +518,8 @@ dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
/* REVISIT show device associations too */ /* REVISIT show device associations too */
/* cost is now small, but not linear... */ /* cost is now small, but not linear... */
list_for_each_entry(clk, &clocks, node) { list_for_each_entry(clk, &parent->children, childnode) {
if (clk->parent == parent) dump_clock(s, nest + NEST_DELTA, clk);
dump_clock(s, nest + NEST_DELTA, clk);
} }
} }
......
...@@ -22,6 +22,10 @@ ...@@ -22,6 +22,10 @@
/* PLL/Reset register offsets */ /* PLL/Reset register offsets */
#define PLLCTL 0x100 #define PLLCTL 0x100
#define PLLCTL_PLLEN BIT(0) #define PLLCTL_PLLEN BIT(0)
#define PLLCTL_PLLPWRDN BIT(1)
#define PLLCTL_PLLRST BIT(3)
#define PLLCTL_PLLDIS BIT(4)
#define PLLCTL_PLLENSRC BIT(5)
#define PLLCTL_CLKMODE BIT(8) #define PLLCTL_CLKMODE BIT(8)
#define PLLM 0x110 #define PLLM 0x110
...@@ -65,15 +69,20 @@ struct clk { ...@@ -65,15 +69,20 @@ struct clk {
const char *name; const char *name;
unsigned long rate; unsigned long rate;
u8 usecount; u8 usecount;
u8 flags;
u8 lpsc; u8 lpsc;
u8 psc_ctlr; u8 gpsc;
u32 flags;
struct clk *parent; struct clk *parent;
struct list_head children; /* list of children */
struct list_head childnode; /* parent's child list node */
struct pll_data *pll_data; struct pll_data *pll_data;
u32 div_reg; u32 div_reg;
unsigned long (*recalc) (struct clk *);
int (*set_rate) (struct clk *clk, unsigned long rate);
int (*round_rate) (struct clk *clk, unsigned long rate);
}; };
/* Clock flags */ /* Clock flags: SoC-specific flags start at BIT(16) */
#define ALWAYS_ENABLED BIT(1) #define ALWAYS_ENABLED BIT(1)
#define CLK_PSC BIT(2) #define CLK_PSC BIT(2)
#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */ #define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */
...@@ -94,6 +103,8 @@ struct davinci_clk { ...@@ -94,6 +103,8 @@ struct davinci_clk {
} }
int davinci_clk_init(struct davinci_clk *clocks); int davinci_clk_init(struct davinci_clk *clocks);
int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
unsigned int mult, unsigned int postdiv);
extern struct platform_device davinci_wdt_device; extern struct platform_device davinci_wdt_device;
......
...@@ -86,6 +86,8 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) ...@@ -86,6 +86,8 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
dip = davinci_get_id(davinci_soc_info.jtag_id); dip = davinci_get_id(davinci_soc_info.jtag_id);
if (!dip) { if (!dip) {
ret = -EINVAL; ret = -EINVAL;
pr_err("Unknown DaVinci JTAG ID 0x%x\n",
davinci_soc_info.jtag_id);
goto err; goto err;
} }
...@@ -104,5 +106,5 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) ...@@ -104,5 +106,5 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
return; return;
err: err:
pr_err("davinci_common_init: SoC Initialization failed\n"); panic("davinci_common_init: SoC Initialization failed\n");
} }
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/io.h> #include <linux/io.h>
......
/*
* CPU frequency scaling for DaVinci
*
* Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
*
* Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows:
*
* Copyright (C) 2005 Nokia Corporation
* Written by Tony Lindgren <tony@atomide.com>
*
* Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
*
* Copyright (C) 2007-2008 Texas Instruments, Inc.
* Updated to support OMAP3
* Rajendra Nayak <rnayak@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <mach/cpufreq.h>
#include <mach/common.h>
#include "clock.h"
struct davinci_cpufreq {
struct device *dev;
struct clk *armclk;
};
static struct davinci_cpufreq cpufreq;
static int davinci_verify_speed(struct cpufreq_policy *policy)
{
struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
struct cpufreq_frequency_table *freq_table = pdata->freq_table;
struct clk *armclk = cpufreq.armclk;
if (freq_table)
return cpufreq_frequency_table_verify(policy, freq_table);
if (policy->cpu)
return -EINVAL;
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000;
policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000;
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
return 0;
}
static unsigned int davinci_getspeed(unsigned int cpu)
{
if (cpu)
return 0;
return clk_get_rate(cpufreq.armclk) / 1000;
}
static int davinci_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
{
int ret = 0;
unsigned int idx;
struct cpufreq_freqs freqs;
struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
struct clk *armclk = cpufreq.armclk;
/*
* Ensure desired rate is within allowed range. Some govenors
* (ondemand) will just pass target_freq=0 to get the minimum.
*/
if (target_freq < policy->cpuinfo.min_freq)
target_freq = policy->cpuinfo.min_freq;
if (target_freq > policy->cpuinfo.max_freq)
target_freq = policy->cpuinfo.max_freq;
freqs.old = davinci_getspeed(0);
freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
freqs.cpu = 0;
if (freqs.old == freqs.new)
return ret;
cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,
dev_driver_string(cpufreq.dev),
"transition: %u --> %u\n", freqs.old, freqs.new);
ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
freqs.new, relation, &idx);
if (ret)
return -EINVAL;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
/* if moving to higher frequency, up the voltage beforehand */
if (pdata->set_voltage && freqs.new > freqs.old)
pdata->set_voltage(idx);
ret = clk_set_rate(armclk, idx);
/* if moving to lower freq, lower the voltage after lowering freq */
if (pdata->set_voltage && freqs.new < freqs.old)
pdata->set_voltage(idx);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return ret;
}
static int __init davinci_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
struct cpufreq_frequency_table *freq_table = pdata->freq_table;
if (policy->cpu != 0)
return -EINVAL;
/* Finish platform specific initialization */
if (pdata->init) {
result = pdata->init();
if (result)
return result;
}
policy->cur = policy->min = policy->max = davinci_getspeed(0);
if (freq_table) {
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
if (!result)
cpufreq_frequency_table_get_attr(freq_table,
policy->cpu);
} else {
policy->cpuinfo.min_freq = policy->min;
policy->cpuinfo.max_freq = policy->max;
}
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
policy->cur = davinci_getspeed(0);
/*
* Time measurement across the target() function yields ~1500-1800us
* time taken with no drivers on notification list.
* Setting the latency to 2000 us to accomodate addition of drivers
* to pre/post change notification list.
*/
policy->cpuinfo.transition_latency = 2000 * 1000;
return 0;
}
static int davinci_cpu_exit(struct cpufreq_policy *policy)
{
cpufreq_frequency_table_put_attr(policy->cpu);
return 0;
}
static struct freq_attr *davinci_cpufreq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
static struct cpufreq_driver davinci_driver = {
.flags = CPUFREQ_STICKY,
.verify = davinci_verify_speed,
.target = davinci_target,
.get = davinci_getspeed,
.init = davinci_cpu_init,
.exit = davinci_cpu_exit,
.name = "davinci",
.attr = davinci_cpufreq_attr,
};
static int __init davinci_cpufreq_probe(struct platform_device *pdev)
{
struct davinci_cpufreq_config *pdata = pdev->dev.platform_data;
if (!pdata)
return -EINVAL;
if (!pdata->freq_table)
return -EINVAL;
cpufreq.dev = &pdev->dev;
cpufreq.armclk = clk_get(NULL, "arm");
if (IS_ERR(cpufreq.armclk)) {
dev_err(cpufreq.dev, "Unable to get ARM clock\n");
return PTR_ERR(cpufreq.armclk);
}
return cpufreq_register_driver(&davinci_driver);
}
static int __exit davinci_cpufreq_remove(struct platform_device *pdev)
{
clk_put(cpufreq.armclk);
return cpufreq_unregister_driver(&davinci_driver);
}
static struct platform_driver davinci_cpufreq_driver = {
.driver = {
.name = "cpufreq-davinci",
.owner = THIS_MODULE,
},
.remove = __exit_p(davinci_cpufreq_remove),
};
static int __init davinci_cpufreq_init(void)
{
return platform_driver_probe(&davinci_cpufreq_driver,
davinci_cpufreq_probe);
}
late_initcall(davinci_cpufreq_init);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -9,15 +9,11 @@ ...@@ -9,15 +9,11 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/mach/map.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/i2c.h> #include <mach/i2c.h>
#include <mach/irqs.h> #include <mach/irqs.h>
...@@ -177,7 +173,7 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) ...@@ -177,7 +173,7 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
mmcsd1_resources[0].start = DM365_MMCSD1_BASE; mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
mmcsd1_resources[0].end = DM365_MMCSD1_BASE + mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
SZ_4K - 1; SZ_4K - 1;
mmcsd0_resources[2].start = IRQ_DM365_SDIOINT1; mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
} else } else
break; break;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment