Commit 206323c1 authored by Russell King's avatar Russell King

Merge branch 'davinci-next' of...

Merge branch 'davinci-next' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci into devel-stable
parents 25cf0398 28bd2c34
......@@ -61,6 +61,8 @@ config MACH_DAVINCI_EVM
bool "TI DM644x EVM"
default ARCH_DAVINCI_DM644x
depends on ARCH_DAVINCI_DM644x
select MISC_DEVICES
select EEPROM_AT24
help
Configure this option to specify the whether the board used
for development is a DM644x EVM
......@@ -68,6 +70,8 @@ config MACH_DAVINCI_EVM
config MACH_SFFSDR
bool "Lyrtech SFFSDR"
depends on ARCH_DAVINCI_DM644x
select MISC_DEVICES
select EEPROM_AT24
help
Say Y here to select the Lyrtech Small Form Factor
Software Defined Radio (SFFSDR) board.
......@@ -99,6 +103,8 @@ config MACH_DAVINCI_DM6467_EVM
default ARCH_DAVINCI_DM646x
depends on ARCH_DAVINCI_DM646x
select MACH_DAVINCI_DM6467TEVM
select MISC_DEVICES
select EEPROM_AT24
help
Configure this option to specify the whether the board used
for development is a DM6467 EVM
......@@ -110,6 +116,8 @@ config MACH_DAVINCI_DM365_EVM
bool "TI DM365 EVM"
default ARCH_DAVINCI_DM365
depends on ARCH_DAVINCI_DM365
select MISC_DEVICES
select EEPROM_AT24
help
Configure this option to specify whether the board used
for development is a DM365 EVM
......@@ -119,6 +127,8 @@ config MACH_DAVINCI_DA830_EVM
default ARCH_DAVINCI_DA830
depends on ARCH_DAVINCI_DA830
select GPIO_PCF857X
select MISC_DEVICES
select EEPROM_AT24
help
Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
......@@ -148,7 +158,6 @@ config MACH_DAVINCI_DA850_EVM
bool "TI DA850/OMAP-L138/AM18x Reference Platform"
default ARCH_DAVINCI_DA850
depends on ARCH_DAVINCI_DA850
select GPIO_PCA953X
help
Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module.
......@@ -178,6 +187,12 @@ config DA850_UI_RMII
endchoice
config GPIO_PCA953X
default MACH_DAVINCI_DA850_EVM
config KEYBOARD_GPIO_POLLED
default MACH_DAVINCI_DA850_EVM
config MACH_TNETV107X
bool "TI TNETV107X Reference Platform"
default ARCH_DAVINCI_TNETV107X
......@@ -188,6 +203,8 @@ config MACH_TNETV107X
config MACH_MITYOMAPL138
bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
depends on ARCH_DAVINCI_DA850
select MISC_DEVICES
select EEPROM_AT24
help
Say Y here to select the Critical Link MityDSP-L138/MityARM-1808
System on Module. Information on this SoM may be found at
......
......@@ -90,7 +90,7 @@ int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
void __iomem *base, unsigned cs)
{
unsigned set, val;
unsigned ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
unsigned offset = A1CR_OFFSET + cs * 4;
struct clk *aemif_clk;
unsigned long clkrate;
......
......@@ -17,8 +17,10 @@
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/i2c/pca953x.h>
#include <linux/input.h>
#include <linux/mfd/tps6507x.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
......@@ -266,34 +268,115 @@ static inline void da850_evm_setup_emac_rmii(int rmii_sel)
struct davinci_soc_info *soc_info = &davinci_soc_info;
soc_info->emac_pdata->rmii_en = 1;
gpio_set_value(rmii_sel, 0);
gpio_set_value_cansleep(rmii_sel, 0);
}
#else
static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
#endif
#define DA850_KEYS_DEBOUNCE_MS 10
/*
* At 200ms polling interval it is possible to miss an
* event by tapping very lightly on the push button but most
* pushes do result in an event; longer intervals require the
* user to hold the button whereas shorter intervals require
* more CPU time for polling.
*/
#define DA850_GPIO_KEYS_POLL_MS 200
enum da850_evm_ui_exp_pins {
DA850_EVM_UI_EXP_SEL_C = 5,
DA850_EVM_UI_EXP_SEL_B,
DA850_EVM_UI_EXP_SEL_A,
DA850_EVM_UI_EXP_PB8,
DA850_EVM_UI_EXP_PB7,
DA850_EVM_UI_EXP_PB6,
DA850_EVM_UI_EXP_PB5,
DA850_EVM_UI_EXP_PB4,
DA850_EVM_UI_EXP_PB3,
DA850_EVM_UI_EXP_PB2,
DA850_EVM_UI_EXP_PB1,
};
static const char const *da850_evm_ui_exp[] = {
[DA850_EVM_UI_EXP_SEL_C] = "sel_c",
[DA850_EVM_UI_EXP_SEL_B] = "sel_b",
[DA850_EVM_UI_EXP_SEL_A] = "sel_a",
[DA850_EVM_UI_EXP_PB8] = "pb8",
[DA850_EVM_UI_EXP_PB7] = "pb7",
[DA850_EVM_UI_EXP_PB6] = "pb6",
[DA850_EVM_UI_EXP_PB5] = "pb5",
[DA850_EVM_UI_EXP_PB4] = "pb4",
[DA850_EVM_UI_EXP_PB3] = "pb3",
[DA850_EVM_UI_EXP_PB2] = "pb2",
[DA850_EVM_UI_EXP_PB1] = "pb1",
};
#define DA850_N_UI_PB 8
static struct gpio_keys_button da850_evm_ui_keys[] = {
[0 ... DA850_N_UI_PB - 1] = {
.type = EV_KEY,
.active_low = 1,
.wakeup = 0,
.debounce_interval = DA850_KEYS_DEBOUNCE_MS,
.code = -1, /* assigned at runtime */
.gpio = -1, /* assigned at runtime */
.desc = NULL, /* assigned at runtime */
},
};
static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = {
.buttons = da850_evm_ui_keys,
.nbuttons = ARRAY_SIZE(da850_evm_ui_keys),
.poll_interval = DA850_GPIO_KEYS_POLL_MS,
};
static struct platform_device da850_evm_ui_keys_device = {
.name = "gpio-keys-polled",
.id = 0,
.dev = {
.platform_data = &da850_evm_ui_keys_pdata
},
};
static void da850_evm_ui_keys_init(unsigned gpio)
{
int i;
struct gpio_keys_button *button;
for (i = 0; i < DA850_N_UI_PB; i++) {
button = &da850_evm_ui_keys[i];
button->code = KEY_F8 - i;
button->desc = (char *)
da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
}
}
static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
unsigned ngpio, void *c)
{
int sel_a, sel_b, sel_c, ret;
sel_a = gpio + 7;
sel_b = gpio + 6;
sel_c = gpio + 5;
sel_a = gpio + DA850_EVM_UI_EXP_SEL_A;
sel_b = gpio + DA850_EVM_UI_EXP_SEL_B;
sel_c = gpio + DA850_EVM_UI_EXP_SEL_C;
ret = gpio_request(sel_a, "sel_a");
ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]);
if (ret) {
pr_warning("Cannot open UI expander pin %d\n", sel_a);
goto exp_setup_sela_fail;
}
ret = gpio_request(sel_b, "sel_b");
ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]);
if (ret) {
pr_warning("Cannot open UI expander pin %d\n", sel_b);
goto exp_setup_selb_fail;
}
ret = gpio_request(sel_c, "sel_c");
ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]);
if (ret) {
pr_warning("Cannot open UI expander pin %d\n", sel_c);
goto exp_setup_selc_fail;
......@@ -304,6 +387,13 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
gpio_direction_output(sel_b, 1);
gpio_direction_output(sel_c, 1);
da850_evm_ui_keys_init(gpio);
ret = platform_device_register(&da850_evm_ui_keys_device);
if (ret) {
pr_warning("Could not register UI GPIO expander push-buttons");
goto exp_setup_keys_fail;
}
ui_card_detected = 1;
pr_info("DA850/OMAP-L138 EVM UI card detected\n");
......@@ -313,6 +403,8 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
return 0;
exp_setup_keys_fail:
gpio_free(sel_c);
exp_setup_selc_fail:
gpio_free(sel_b);
exp_setup_selb_fail:
......@@ -324,14 +416,192 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
static int da850_evm_ui_expander_teardown(struct i2c_client *client,
unsigned gpio, unsigned ngpio, void *c)
{
platform_device_unregister(&da850_evm_ui_keys_device);
/* deselect all functionalities */
gpio_set_value(gpio + 5, 1);
gpio_set_value(gpio + 6, 1);
gpio_set_value(gpio + 7, 1);
gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_C, 1);
gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_B, 1);
gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_A, 1);
gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
return 0;
}
/* assign the baseboard expander's GPIOs after the UI board's */
#define DA850_UI_EXPANDER_N_GPIOS ARRAY_SIZE(da850_evm_ui_exp)
#define DA850_BB_EXPANDER_GPIO_BASE (DAVINCI_N_GPIO + DA850_UI_EXPANDER_N_GPIOS)
enum da850_evm_bb_exp_pins {
DA850_EVM_BB_EXP_DEEP_SLEEP_EN = 0,
DA850_EVM_BB_EXP_SW_RST,
DA850_EVM_BB_EXP_TP_23,
DA850_EVM_BB_EXP_TP_22,
DA850_EVM_BB_EXP_TP_21,
DA850_EVM_BB_EXP_USER_PB1,
DA850_EVM_BB_EXP_USER_LED2,
DA850_EVM_BB_EXP_USER_LED1,
DA850_EVM_BB_EXP_USER_SW1,
DA850_EVM_BB_EXP_USER_SW2,
DA850_EVM_BB_EXP_USER_SW3,
DA850_EVM_BB_EXP_USER_SW4,
DA850_EVM_BB_EXP_USER_SW5,
DA850_EVM_BB_EXP_USER_SW6,
DA850_EVM_BB_EXP_USER_SW7,
DA850_EVM_BB_EXP_USER_SW8
};
static const char const *da850_evm_bb_exp[] = {
[DA850_EVM_BB_EXP_DEEP_SLEEP_EN] = "deep_sleep_en",
[DA850_EVM_BB_EXP_SW_RST] = "sw_rst",
[DA850_EVM_BB_EXP_TP_23] = "tp_23",
[DA850_EVM_BB_EXP_TP_22] = "tp_22",
[DA850_EVM_BB_EXP_TP_21] = "tp_21",
[DA850_EVM_BB_EXP_USER_PB1] = "user_pb1",
[DA850_EVM_BB_EXP_USER_LED2] = "user_led2",
[DA850_EVM_BB_EXP_USER_LED1] = "user_led1",
[DA850_EVM_BB_EXP_USER_SW1] = "user_sw1",
[DA850_EVM_BB_EXP_USER_SW2] = "user_sw2",
[DA850_EVM_BB_EXP_USER_SW3] = "user_sw3",
[DA850_EVM_BB_EXP_USER_SW4] = "user_sw4",
[DA850_EVM_BB_EXP_USER_SW5] = "user_sw5",
[DA850_EVM_BB_EXP_USER_SW6] = "user_sw6",
[DA850_EVM_BB_EXP_USER_SW7] = "user_sw7",
[DA850_EVM_BB_EXP_USER_SW8] = "user_sw8",
};
#define DA850_N_BB_USER_SW 8
static struct gpio_keys_button da850_evm_bb_keys[] = {
[0] = {
.type = EV_KEY,
.active_low = 1,
.wakeup = 0,
.debounce_interval = DA850_KEYS_DEBOUNCE_MS,
.code = KEY_PROG1,
.desc = NULL, /* assigned at runtime */
.gpio = -1, /* assigned at runtime */
},
[1 ... DA850_N_BB_USER_SW] = {
.type = EV_SW,
.active_low = 1,
.wakeup = 0,
.debounce_interval = DA850_KEYS_DEBOUNCE_MS,
.code = -1, /* assigned at runtime */
.desc = NULL, /* assigned at runtime */
.gpio = -1, /* assigned at runtime */
},
};
static struct gpio_keys_platform_data da850_evm_bb_keys_pdata = {
.buttons = da850_evm_bb_keys,
.nbuttons = ARRAY_SIZE(da850_evm_bb_keys),
.poll_interval = DA850_GPIO_KEYS_POLL_MS,
};
static struct platform_device da850_evm_bb_keys_device = {
.name = "gpio-keys-polled",
.id = 1,
.dev = {
.platform_data = &da850_evm_bb_keys_pdata
},
};
static void da850_evm_bb_keys_init(unsigned gpio)
{
int i;
struct gpio_keys_button *button;
button = &da850_evm_bb_keys[0];
button->desc = (char *)
da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_PB1];
button->gpio = gpio + DA850_EVM_BB_EXP_USER_PB1;
for (i = 0; i < DA850_N_BB_USER_SW; i++) {
button = &da850_evm_bb_keys[i + 1];
button->code = SW_LID + i;
button->desc = (char *)
da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_SW1 + i];
button->gpio = gpio + DA850_EVM_BB_EXP_USER_SW1 + i;
}
}
gpio_free(gpio + 5);
gpio_free(gpio + 6);
gpio_free(gpio + 7);
#define DA850_N_BB_USER_LED 2
static struct gpio_led da850_evm_bb_leds[] = {
[0 ... DA850_N_BB_USER_LED - 1] = {
.active_low = 1,
.gpio = -1, /* assigned at runtime */
.name = NULL, /* assigned at runtime */
},
};
static struct gpio_led_platform_data da850_evm_bb_leds_pdata = {
.leds = da850_evm_bb_leds,
.num_leds = ARRAY_SIZE(da850_evm_bb_leds),
};
static struct platform_device da850_evm_bb_leds_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &da850_evm_bb_leds_pdata
}
};
static void da850_evm_bb_leds_init(unsigned gpio)
{
int i;
struct gpio_led *led;
for (i = 0; i < DA850_N_BB_USER_LED; i++) {
led = &da850_evm_bb_leds[i];
led->gpio = gpio + DA850_EVM_BB_EXP_USER_LED2 + i;
led->name =
da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_LED2 + i];
}
}
static int da850_evm_bb_expander_setup(struct i2c_client *client,
unsigned gpio, unsigned ngpio,
void *c)
{
int ret;
/*
* Register the switches and pushbutton on the baseboard as a gpio-keys
* device.
*/
da850_evm_bb_keys_init(gpio);
ret = platform_device_register(&da850_evm_bb_keys_device);
if (ret) {
pr_warning("Could not register baseboard GPIO expander keys");
goto io_exp_setup_sw_fail;
}
da850_evm_bb_leds_init(gpio);
ret = platform_device_register(&da850_evm_bb_leds_device);
if (ret) {
pr_warning("Could not register baseboard GPIO expander LEDS");
goto io_exp_setup_leds_fail;
}
return 0;
io_exp_setup_leds_fail:
platform_device_unregister(&da850_evm_bb_keys_device);
io_exp_setup_sw_fail:
return ret;
}
static int da850_evm_bb_expander_teardown(struct i2c_client *client,
unsigned gpio, unsigned ngpio, void *c)
{
platform_device_unregister(&da850_evm_bb_leds_device);
platform_device_unregister(&da850_evm_bb_keys_device);
return 0;
}
......@@ -340,6 +610,14 @@ static struct pca953x_platform_data da850_evm_ui_expander_info = {
.gpio_base = DAVINCI_N_GPIO,
.setup = da850_evm_ui_expander_setup,
.teardown = da850_evm_ui_expander_teardown,
.names = da850_evm_ui_exp,
};
static struct pca953x_platform_data da850_evm_bb_expander_info = {
.gpio_base = DA850_BB_EXPANDER_GPIO_BASE,
.setup = da850_evm_bb_expander_setup,
.teardown = da850_evm_bb_expander_teardown,
.names = da850_evm_bb_exp,
};
static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
......@@ -350,6 +628,10 @@ static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
I2C_BOARD_INFO("tca6416", 0x20),
.platform_data = &da850_evm_ui_expander_info,
},
{
I2C_BOARD_INFO("tca6416", 0x21),
.platform_data = &da850_evm_bb_expander_info,
},
};
static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
......@@ -540,7 +822,7 @@ static struct regulator_init_data tps65070_regulator_data[] = {
{
.constraints = {
.min_uV = 950000,
.max_uV = 1320000,
.max_uV = 1350000,
.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS),
.boot_on = 1,
......@@ -591,7 +873,7 @@ static struct tps6507x_board tps_board = {
.tps6507x_ts_init_data = &tps6507x_touchscreen_data,
};
static struct i2c_board_info __initdata da850evm_tps65070_info[] = {
static struct i2c_board_info __initdata da850_evm_tps65070_info[] = {
{
I2C_BOARD_INFO("tps6507x", 0x48),
.platform_data = &tps_board,
......@@ -600,8 +882,8 @@ static struct i2c_board_info __initdata da850evm_tps65070_info[] = {
static int __init pmic_tps65070_init(void)
{
return i2c_register_board_info(1, da850evm_tps65070_info,
ARRAY_SIZE(da850evm_tps65070_info));
return i2c_register_board_info(1, da850_evm_tps65070_info,
ARRAY_SIZE(da850_evm_tps65070_info));
}
static const short da850_evm_lcdc_pins[] = {
......@@ -736,6 +1018,27 @@ static struct edma_rsv_info *da850_edma_rsv[2] = {
&da850_edma_cc1_rsv,
};
#ifdef CONFIG_CPU_FREQ
static __init int da850_evm_init_cpufreq(void)
{
switch (system_rev & 0xF) {
case 3:
da850_max_speed = 456000;
break;
case 2:
da850_max_speed = 408000;
break;
case 1:
da850_max_speed = 372000;
break;
}
return da850_register_cpufreq("pll0_sysclk3");
}
#else
static __init int da850_evm_init_cpufreq(void) { return 0; }
#endif
static __init void da850_evm_init(void)
{
int ret;
......@@ -836,7 +1139,7 @@ static __init void da850_evm_init(void)
if (ret)
pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
ret = da850_register_cpufreq("pll0_sysclk3");
ret = da850_evm_init_cpufreq();
if (ret)
pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
ret);
......
......@@ -336,7 +336,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
ratio--;
}
if (ratio > PLLDIV_RATIO_MASK)
if (ratio > pll->div_ratio_mask)
return -EINVAL;
do {
......@@ -344,7 +344,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
} while (v & PLLSTAT_GOSTAT);
v = __raw_readl(pll->base + clk->div_reg);
v &= ~PLLDIV_RATIO_MASK;
v &= ~pll->div_ratio_mask;
v |= ratio | PLLDIV_EN;
__raw_writel(v, pll->base + clk->div_reg);
......
......@@ -830,8 +830,7 @@ static void da850_set_async3_src(int pllnum)
* According to the TRM, minimum PLLM results in maximum power savings.
* The OPP definitions below should keep the PLLM as low as possible.
*
* The output of the PLLM must be between 400 to 600 MHz.
* This rules out prediv of anything but divide-by-one for 24Mhz OSC input.
* The output of the PLLM must be between 300 to 600 MHz.
*/
struct da850_opp {
unsigned int freq; /* in KHz */
......@@ -842,6 +841,33 @@ struct da850_opp {
unsigned int cvdd_max; /* in uV */
};
static const struct da850_opp da850_opp_456 = {
.freq = 456000,
.prediv = 1,
.mult = 19,
.postdiv = 1,
.cvdd_min = 1300000,
.cvdd_max = 1350000,
};
static const struct da850_opp da850_opp_408 = {
.freq = 408000,
.prediv = 1,
.mult = 17,
.postdiv = 1,
.cvdd_min = 1300000,
.cvdd_max = 1350000,
};
static const struct da850_opp da850_opp_372 = {
.freq = 372000,
.prediv = 2,
.mult = 31,
.postdiv = 1,
.cvdd_min = 1200000,
.cvdd_max = 1320000,
};
static const struct da850_opp da850_opp_300 = {
.freq = 300000,
.prediv = 1,
......@@ -876,6 +902,9 @@ static const struct da850_opp da850_opp_96 = {
}
static struct cpufreq_frequency_table da850_freq_table[] = {
OPP(456),
OPP(408),
OPP(372),
OPP(300),
OPP(200),
OPP(96),
......@@ -885,6 +914,19 @@ static struct cpufreq_frequency_table da850_freq_table[] = {
},
};
#ifdef CONFIG_REGULATOR
static int da850_set_voltage(unsigned int index);
static int da850_regulator_init(void);
#endif
static struct davinci_cpufreq_config cpufreq_info = {
.freq_table = da850_freq_table,
#ifdef CONFIG_REGULATOR
.init = da850_regulator_init,
.set_voltage = da850_set_voltage,
#endif
};
#ifdef CONFIG_REGULATOR
static struct regulator *cvdd;
......@@ -895,7 +937,7 @@ static int da850_set_voltage(unsigned int index)
if (!cvdd)
return -ENODEV;
opp = (struct da850_opp *) da850_freq_table[index].index;
opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
}
......@@ -912,14 +954,6 @@ static int da850_regulator_init(void)
}
#endif
static struct davinci_cpufreq_config cpufreq_info = {
.freq_table = &da850_freq_table[0],
#ifdef CONFIG_REGULATOR
.init = da850_regulator_init,
.set_voltage = da850_set_voltage,
#endif
};
static struct platform_device da850_cpufreq_device = {
.name = "cpufreq-davinci",
.dev = {
......@@ -928,12 +962,22 @@ static struct platform_device da850_cpufreq_device = {
.id = -1,
};
unsigned int da850_max_speed = 300000;
int __init da850_register_cpufreq(char *async_clk)
{
int i;
/* cpufreq driver can help keep an "async" clock constant */
if (async_clk)
clk_add_alias("async", da850_cpufreq_device.name,
async_clk, NULL);
for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
if (da850_freq_table[i].frequency <= da850_max_speed) {
cpufreq_info.freq_table = &da850_freq_table[i];
break;
}
}
return platform_device_register(&da850_cpufreq_device);
}
......@@ -942,17 +986,18 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
int i, ret = 0, diff;
unsigned int best = (unsigned int) -1;
struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
rate /= 1000; /* convert to kHz */
for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
diff = da850_freq_table[i].frequency - rate;
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
diff = table[i].frequency - rate;
if (diff < 0)
diff = -diff;
if (diff < best) {
best = diff;
ret = da850_freq_table[i].frequency;
ret = table[i].frequency;
}
}
......@@ -973,7 +1018,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index)
struct pll_data *pll = clk->pll_data;
int ret;
opp = (struct da850_opp *) da850_freq_table[index].index;
opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
prediv = opp->prediv;
mult = opp->mult;
postdiv = opp->postdiv;
......
......@@ -344,7 +344,20 @@ static struct platform_device tsc_device = {
void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
{
int i;
int i, error;
struct clk *tsc_clk;
/*
* The reset defaults for tnetv107x tsc clock divider is set too high.
* This forces the clock down to a range that allows the ADC to
* complete sample conversion in time.
*/
tsc_clk = clk_get(NULL, "sys_tsc_clk");
if (tsc_clk) {
error = clk_set_rate(tsc_clk, 5000000);
WARN_ON(error < 0);
clk_put(tsc_clk);
}
platform_device_register(&edma_device);
platform_device_register(&tnetv107x_wdt_device);
......
......@@ -27,6 +27,13 @@
extern void __iomem *da8xx_syscfg0_base;
extern void __iomem *da8xx_syscfg1_base;
/*
* If the DA850/OMAP-L138/AM18x SoC on board is of a higher speed grade
* (than the regular 300Mhz variant), the board code should set this up
* with the supported speed before calling da850_register_cpufreq().
*/
extern unsigned int da850_max_speed;
/*
* The cp_intc interrupt controller for the da8xx isn't in the same
* chunk of physical memory space as the other registers (like it is
......
......@@ -83,20 +83,15 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr,
pdctl1 = __raw_readl(psc_base + PDCTL1);
pdctl1 |= 0x100;
__raw_writel(pdctl1, psc_base + PDCTL1);
do {
ptstat = __raw_readl(psc_base +
PTSTAT);
} while (!(((ptstat >> domain) & 1) == 0));
} else {
ptcmd = 1 << domain;
__raw_writel(ptcmd, psc_base + PTCMD);
do {
ptstat = __raw_readl(psc_base + PTSTAT);
} while (!(((ptstat >> domain) & 1) == 0));
}
do {
ptstat = __raw_readl(psc_base + PTSTAT);
} while (!(((ptstat >> domain) & 1) == 0));
do {
mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
......
......@@ -272,14 +272,35 @@ static cycle_t read_cycles(struct clocksource *cs)
return (cycles_t)timer32_read(t);
}
/*
* Kernel assumes that sched_clock can be called early but may not have
* things ready yet.
*/
static cycle_t read_dummy(struct clocksource *cs)
{
return 0;
}
static struct clocksource clocksource_davinci = {
.rating = 300,
.read = read_cycles,
.read = read_dummy,
.mask = CLOCKSOURCE_MASK(32),
.shift = 24,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
/*
* Overwrite weak default sched_clock with something more precise
*/
unsigned long long notrace sched_clock(void)
{
const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci);
return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
clocksource_davinci.shift);
}
/*
* clockevent
*/
......@@ -377,6 +398,7 @@ static void __init davinci_timer_init(void)
davinci_clock_tick_rate = clk_get_rate(timer_clk);
/* setup clocksource */
clocksource_davinci.read = read_cycles;
clocksource_davinci.name = id_to_name[clocksource_id];
clocksource_davinci.mult =
clocksource_khz2mult(davinci_clock_tick_rate/1000,
......
......@@ -131,12 +131,13 @@ define_pll_clk(tdm, 1, 0x0ff, 0x200);
define_pll_clk(eth, 2, 0x0ff, 0x400);
/* Level 2 - divided outputs from the PLLs */
#define define_pll_div_clk(pll, cname, div) \
static struct clk pll##_##cname##_clk = { \
.name = #pll "_" #cname "_clk",\
.parent = &pll_##pll##_clk, \
.flags = CLK_PLL, \
.div_reg = PLLDIV##div, \
#define define_pll_div_clk(pll, cname, div) \
static struct clk pll##_##cname##_clk = { \
.name = #pll "_" #cname "_clk", \
.parent = &pll_##pll##_clk, \
.flags = CLK_PLL, \
.div_reg = PLLDIV##div, \
.set_rate = davinci_set_sysclk_rate, \
}
define_pll_div_clk(sys, arm1176, 1);
......@@ -192,6 +193,7 @@ lpsc_clk_enabled(system, sys_half_clk, SYSTEM);
lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST);
lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST);
lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM);
lpsc_clk_enabled(timer1, sys_half_clk, TIMER1);
lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE);
lpsc_clk(ethss, eth_125mhz_clk, ETHSS);
......@@ -205,16 +207,15 @@ lpsc_clk(mdio, sys_half_clk, MDIO);
lpsc_clk(sdio0, sys_half_clk, SDIO0);
lpsc_clk(sdio1, sys_half_clk, SDIO1);
lpsc_clk(timer0, sys_half_clk, TIMER0);
lpsc_clk(timer1, sys_half_clk, TIMER1);
lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP);
lpsc_clk(ssp, sys_half_clk, SSP);
lpsc_clk(tdm0, tdm_0_clk, TDM0);
lpsc_clk(tdm1, tdm_1_clk, TDM1);
lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ);
lpsc_clk(mcdma, sys_half_clk, MCDMA);
lpsc_clk(usb0, sys_half_clk, USB0);
lpsc_clk(usb1, sys_half_clk, USB1);
lpsc_clk(usbss, sys_half_clk, USBSS);
lpsc_clk(usb0, clk_usbss, USB0);
lpsc_clk(usb1, clk_usbss, USB1);
lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII);
lpsc_clk(imcop, sys_dsp_clk, IMCOP);
lpsc_clk(spare, sys_half_clk, SPARE);
......@@ -281,7 +282,9 @@ static struct clk_lookup clks[] = {
CLK(NULL, "clk_tdm0", &clk_tdm0),
CLK(NULL, "clk_vlynq", &clk_vlynq),
CLK(NULL, "clk_mcdma", &clk_mcdma),
CLK(NULL, "clk_usbss", &clk_usbss),
CLK(NULL, "clk_usb0", &clk_usb0),
CLK(NULL, "clk_usb1", &clk_usb1),
CLK(NULL, "clk_tdm1", &clk_tdm1),
CLK(NULL, "clk_debugss", &clk_debugss),
CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii),
......@@ -289,8 +292,6 @@ static struct clk_lookup clks[] = {
CLK(NULL, "clk_imcop", &clk_imcop),
CLK(NULL, "clk_spare", &clk_spare),
CLK("davinci_mmc.1", NULL, &clk_sdio1),
CLK(NULL, "clk_usb1", &clk_usb1),
CLK(NULL, "clk_usbss", &clk_usbss),
CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst),
CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst),
CLK(NULL, NULL, NULL),
......
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