diff options
124 files changed, 15562 insertions, 6697 deletions
diff --git a/arch/arm/configs/tegra3_android_defconfig b/arch/arm/configs/tegra3_android_defconfig index ba20b0ee943f..2b4aee13812b 100644 --- a/arch/arm/configs/tegra3_android_defconfig +++ b/arch/arm/configs/tegra3_android_defconfig @@ -340,6 +340,7 @@ CONFIG_VIDEO_AR0832=y CONFIG_TORCH_SSL3250A=y CONFIG_TORCH_TPS61050=y CONFIG_VIDEO_SH532U=y +CONFIG_VIDEO_AD5816=y CONFIG_USB_VIDEO_CLASS=y # CONFIG_USB_GSPCA is not set # CONFIG_RADIO_ADAPTERS is not set diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 1aa448c44fcd..82306bc4aff5 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -22,6 +22,7 @@ config ARCH_TEGRA_2x_SOC select PCI_MSI if TEGRA_PCI select CPA select ARM_ERRATA_716044 + select ARM_ERRATA_764369 if SMP select ARCH_HAS_SUSPEND_PAGETABLE help Support for NVIDIA Tegra AP20 and T20 processors, based on the @@ -46,6 +47,7 @@ config ARCH_TEGRA_3x_SOC select ARCH_SUPPORTS_MSI if TEGRA_PCI select PCI_MSI if TEGRA_PCI select ARM_ERRATA_754322 + select ARM_ERRATA_764369 if SMP select TEGRA_LP2_ARM_TWD if HAVE_ARM_TWD && !TEGRA_RAIL_OFF_MULTIPLE_CPUS select CPA select ARCH_HAS_SUSPEND_PAGETABLE @@ -259,6 +261,13 @@ config TEGRA_CARDHU_DSI help Support for DSI Panel on Nvidia Cardhu +config TEGRA_CARDHU_DUAL_DSI_PANEL + bool "Support Dual DSI panel on Cardhu" + default n + depends on TEGRA_CARDHU_DSI + help + Support for Dual DSI Panel on Nvidia Cardhu + config TEGRA_EMC_SCALING_ENABLE bool "Enable scaling the memory frequency" depends on TEGRA_SILICON_PLATFORM diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 6b1c4c52c713..3153203c6efc 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -44,6 +44,8 @@ obj-y += i2c_error_recovery.o obj-y += mc.o obj-$(CONFIG_TEGRA_STAT_MON) += tegra2_statmon.o obj-$(CONFIG_USB_SUPPORT) += usb_phy.o +obj-$(CONFIG_USB_SUPPORT) += tegra3_usb_phy.o +obj-$(CONFIG_USB_SUPPORT) += tegra2_usb_phy.o obj-$(CONFIG_FIQ) += fiq.o obj-$(CONFIG_TEGRA_FIQ_DEBUGGER) += tegra_fiq_debugger.o obj-$(CONFIG_TEGRA_PWM) += pwm.o diff --git a/arch/arm/mach-tegra/baseband-xmm-power.c b/arch/arm/mach-tegra/baseband-xmm-power.c index 20f8d306f901..4da5d412cf41 100644 --- a/arch/arm/mach-tegra/baseband-xmm-power.c +++ b/arch/arm/mach-tegra/baseband-xmm-power.c @@ -33,6 +33,7 @@ #include <linux/suspend.h> #include <linux/pm_qos_params.h> #include <mach/usb_phy.h> +#include <linux/regulator/consumer.h> #include "board.h" #include "board-enterprise.h" #include "devices.h" diff --git a/arch/arm/mach-tegra/board-cardhu-kbc.c b/arch/arm/mach-tegra/board-cardhu-kbc.c index 16e83bbb03f8..c3971403148f 100644 --- a/arch/arm/mach-tegra/board-cardhu-kbc.c +++ b/arch/arm/mach-tegra/board-cardhu-kbc.c @@ -196,8 +196,8 @@ static struct gpio_keys_button cardhu_int_keys[] = { }; static struct gpio_keys_button cardhu_pm298_int_keys[] = { - [0] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_FALLING, 1, 100), - [1] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_1SEC, 1, 3000), + [0] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_FALLING, 0, 100), + [1] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_1SEC, 0, 3000), }; static struct gpio_keys_button cardhu_pm299_int_keys[] = { @@ -252,8 +252,6 @@ int __init cardhu_keys_init(void) if (get_tegra_image_type() == rck_image) cardhu_keys_e1291_pdata.buttons[i].code = KEY_ENTER; - } else { - tegra_gpio_enable(gpio_nr); } } @@ -265,8 +263,6 @@ int __init cardhu_keys_init(void) if (gpio_nr < 0) { if (get_tegra_image_type() == rck_image) cardhu_keys_e1198[i].code = KEY_ENTER; - } else { - tegra_gpio_enable(gpio_nr); } } diff --git a/arch/arm/mach-tegra/board-cardhu-panel.c b/arch/arm/mach-tegra/board-cardhu-panel.c index 4899dee38042..a62171060b84 100644 --- a/arch/arm/mach-tegra/board-cardhu-panel.c +++ b/arch/arm/mach-tegra/board-cardhu-panel.c @@ -144,8 +144,6 @@ static int cardhu_backlight_init(struct device *dev) pr_err("bl_output array does not have 256 elements\n"); #ifndef CONFIG_TEGRA_CARDHU_DSI - tegra_gpio_disable(cardhu_bl_pwm); - ret = gpio_request(cardhu_bl_enb, "backlight_enb"); if (ret < 0) return ret; @@ -153,8 +151,6 @@ static int cardhu_backlight_init(struct device *dev) ret = gpio_direction_output(cardhu_bl_enb, 1); if (ret < 0) gpio_free(cardhu_bl_enb); - else - tegra_gpio_enable(cardhu_bl_enb); return ret; #endif @@ -168,8 +164,6 @@ static int cardhu_backlight_init(struct device *dev) ret = gpio_direction_output(cardhu_dsia_bl_enb, 1); if (ret < 0) gpio_free(cardhu_dsia_bl_enb); - else - tegra_gpio_enable(cardhu_dsia_bl_enb); /* Enable back light for DSIb panel */ ret = gpio_request(cardhu_dsib_bl_enb, "dsib_bl_enable"); @@ -179,8 +173,6 @@ static int cardhu_backlight_init(struct device *dev) ret = gpio_direction_output(cardhu_dsib_bl_enb, 1); if (ret < 0) gpio_free(cardhu_dsib_bl_enb); - else - tegra_gpio_enable(cardhu_dsib_bl_enb); #endif #if DSI_PANEL_219 @@ -192,8 +184,6 @@ static int cardhu_backlight_init(struct device *dev) ret = gpio_direction_output(cardhu_dsia_bl_enb, 1); if (ret < 0) gpio_free(cardhu_dsia_bl_enb); - else - tegra_gpio_enable(cardhu_dsia_bl_enb); #endif return ret; @@ -206,7 +196,6 @@ static void cardhu_backlight_exit(struct device *dev) /*ret = gpio_request(cardhu_bl_enb, "backlight_enb");*/ gpio_set_value(cardhu_bl_enb, 0); gpio_free(cardhu_bl_enb); - tegra_gpio_disable(cardhu_bl_enb); return; #endif @@ -214,12 +203,11 @@ static void cardhu_backlight_exit(struct device *dev) /* Disable back light for DSIa panel */ gpio_set_value(cardhu_dsia_bl_enb, 0); gpio_free(cardhu_dsia_bl_enb); - tegra_gpio_disable(cardhu_dsia_bl_enb); + /* Disable back light for DSIb panel */ gpio_set_value(cardhu_dsib_bl_enb, 0); gpio_free(cardhu_dsib_bl_enb); - tegra_gpio_disable(cardhu_dsib_bl_enb); gpio_set_value(cardhu_lvds_shutdown, 1); mdelay(20); @@ -229,7 +217,7 @@ static void cardhu_backlight_exit(struct device *dev) /* Disable back light for DSIa panel */ gpio_set_value(cardhu_dsia_bl_enb, 0); gpio_free(cardhu_dsia_bl_enb); - tegra_gpio_disable(cardhu_dsia_bl_enb); + gpio_set_value(cardhu_lvds_shutdown, 1); mdelay(20); @@ -762,8 +750,6 @@ static int cardhu_dsi_panel_enable(void) ret = gpio_direction_output(AVDD_LCD, 1); if (ret < 0) gpio_free(AVDD_LCD); - else - tegra_gpio_enable(AVDD_LCD); #if DSI_PANEL_219 @@ -774,8 +760,7 @@ static int cardhu_dsi_panel_enable(void) if (ret < 0) { gpio_free(cardhu_bl_pwm); return ret; - } else - tegra_gpio_enable(cardhu_bl_pwm); + } ret = gpio_request(cardhu_bl_enb, "bl_enb"); if (ret < 0) @@ -784,8 +769,7 @@ static int cardhu_dsi_panel_enable(void) if (ret < 0) { gpio_free(cardhu_bl_enb); return ret; - } else - tegra_gpio_enable(cardhu_bl_enb); + } gpio_set_value(cardhu_lvds_shutdown, 1); mdelay(20); @@ -805,8 +789,7 @@ static int cardhu_dsi_panel_enable(void) if (ret < 0) { gpio_free(cardhu_dsi_218_panel_reset); return ret; - } else - tegra_gpio_enable(cardhu_dsi_218_panel_reset); + } gpio_set_value(cardhu_dsi_218_panel_reset, 1); gpio_set_value(cardhu_dsi_218_panel_reset, 0); @@ -823,8 +806,7 @@ static int cardhu_dsi_panel_enable(void) if (ret < 0) { gpio_free(cardhu_dsi_219_panel_reset); return ret; - } else - tegra_gpio_enable(cardhu_dsi_219_panel_reset); + } gpio_set_value(cardhu_dsi_219_panel_reset, 0); gpio_set_value(cardhu_dsi_219_panel_reset, 1); @@ -847,18 +829,13 @@ static int cardhu_dsi_panel_disable(void) printk(KERN_INFO "DSI panel disable\n"); #if DSI_PANEL_219 - tegra_gpio_disable(cardhu_dsi_219_panel_reset); gpio_free(cardhu_dsi_219_panel_reset); - tegra_gpio_disable(cardhu_bl_enb); gpio_free(cardhu_bl_enb); - tegra_gpio_disable(cardhu_bl_pwm); gpio_free(cardhu_bl_pwm); - tegra_gpio_disable(cardhu_lvds_shutdown); gpio_free(cardhu_lvds_shutdown); #endif #if DSI_PANEL_218 - tegra_gpio_disable(cardhu_dsi_218_panel_reset); gpio_free(cardhu_dsi_218_panel_reset); #endif @@ -882,7 +859,6 @@ static int cardhu_dsi_panel_postsuspend(void) } #if DSI_PANEL_218 - tegra_gpio_disable(AVDD_LCD); gpio_free(AVDD_LCD); #endif @@ -1222,28 +1198,22 @@ int __init cardhu_panel_init(void) /* lvds configuration */ err = gpio_request(pm313_R_FDE, "R_FDE"); err |= gpio_direction_output(pm313_R_FDE, 1); - tegra_gpio_enable(pm313_R_FDE); err |= gpio_request(pm313_R_FB, "R_FB"); err |= gpio_direction_output(pm313_R_FB, 1); - tegra_gpio_enable(pm313_R_FB); err |= gpio_request(pm313_MODE0, "MODE0"); err |= gpio_direction_output(pm313_MODE0, 1); - tegra_gpio_enable(pm313_MODE0); err |= gpio_request(pm313_MODE1, "MODE1"); err |= gpio_direction_output(pm313_MODE1, 0); - tegra_gpio_enable(pm313_MODE1); err |= gpio_request(pm313_BPP, "BPP"); err |= gpio_direction_output(pm313_BPP, PM313_LVDS_PANEL_BPP); - tegra_gpio_enable(pm313_BPP); err = gpio_request(pm313_lvds_shutdown, "lvds_shutdown"); /* free ride provided by bootloader */ err |= gpio_direction_output(pm313_lvds_shutdown, 1); - tegra_gpio_enable(pm313_lvds_shutdown); if (err) printk(KERN_ERR "ERROR(s) in LVDS configuration\n"); @@ -1254,15 +1224,12 @@ int __init cardhu_panel_init(void) (board_info.board_id == BOARD_PM311)) { gpio_request(e1247_pm269_lvds_shutdown, "lvds_shutdown"); gpio_direction_output(e1247_pm269_lvds_shutdown, 1); - tegra_gpio_enable(e1247_pm269_lvds_shutdown); } else { gpio_request(cardhu_lvds_shutdown, "lvds_shutdown"); gpio_direction_output(cardhu_lvds_shutdown, 1); - tegra_gpio_enable(cardhu_lvds_shutdown); } #endif - tegra_gpio_enable(cardhu_hdmi_hpd); gpio_request(cardhu_hdmi_hpd, "hdmi_hpd"); gpio_direction_input(cardhu_hdmi_hpd); diff --git a/arch/arm/mach-tegra/board-cardhu-pinmux.c b/arch/arm/mach-tegra/board-cardhu-pinmux.c index fd0a6ae34ffc..05e2179682b1 100644 --- a/arch/arm/mach-tegra/board-cardhu-pinmux.c +++ b/arch/arm/mach-tegra/board-cardhu-pinmux.c @@ -472,7 +472,6 @@ static __initdata struct tegra_pingroup_config cardhu_pinmux_cardhu_a03[] = { static __initdata struct tegra_pingroup_config cardhu_pinmux_e1291_a04[] = { DEFAULT_PINMUX(GMI_AD15, NAND, PULL_DOWN, NORMAL, OUTPUT), - DEFAULT_PINMUX(ULPI_DATA5, UARTA, PULL_UP, NORMAL, INPUT), DEFAULT_PINMUX(ULPI_DATA6, UARTA, NORMAL, NORMAL, OUTPUT), DEFAULT_PINMUX(SPI2_MOSI, SPI6, NORMAL, NORMAL, INPUT), DEFAULT_PINMUX(DAP3_SCLK, RSVD1, NORMAL, NORMAL, OUTPUT), @@ -544,11 +543,8 @@ static __initdata struct tegra_pingroup_config gmi_pins_269[] = { static void __init cardhu_pinmux_audio_init(void) { - tegra_gpio_enable(TEGRA_GPIO_CDC_IRQ); gpio_request(TEGRA_GPIO_CDC_IRQ, "wm8903"); gpio_direction_input(TEGRA_GPIO_CDC_IRQ); - - tegra_gpio_enable(TEGRA_GPIO_HP_DET); } #define GPIO_INIT_PIN_MODE(_gpio, _is_input, _value) \ @@ -755,7 +751,6 @@ static void set_unused_pin_gpio(struct gpio_init_pin_info *lpm_pin_info, gpio_free(pin_info->gpio_nr); continue; } - tegra_gpio_enable(pin_info->gpio_nr); } } diff --git a/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c index 0305ee702cbd..f0dc8afa56fe 100644 --- a/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c +++ b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c @@ -698,12 +698,5 @@ int __init cardhu_pm298_gpio_switch_regulator_init(void) break; } - for (i = 0; i < nfixreg_devs; ++i) { - struct fixed_voltage_config *fixed_reg_pdata = - fixed_reg_devs[i]->dev.platform_data; - int gpio_nr = fixed_reg_pdata->gpio; - if (gpio_nr < TEGRA_NR_GPIOS) - tegra_gpio_enable(gpio_nr); - } return platform_add_devices(fixed_reg_devs, nfixreg_devs); } diff --git a/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c index 0c55aa49acc0..6d4db73b6ecd 100644 --- a/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c +++ b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c @@ -688,12 +688,5 @@ int __init cardhu_pm299_gpio_switch_regulator_init(void) break; } - for (i = 0; i < nfixreg_devs; ++i) { - struct fixed_voltage_config *fixed_reg_pdata = - fixed_reg_devs[i]->dev.platform_data; - int gpio_nr = fixed_reg_pdata->gpio; - if (gpio_nr < TEGRA_NR_GPIOS) - tegra_gpio_enable(gpio_nr); - } return platform_add_devices(fixed_reg_devs, nfixreg_devs); } diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c index 79d8d6116edc..61b5a15ed5c7 100644 --- a/arch/arm/mach-tegra/board-cardhu-power.c +++ b/arch/arm/mach-tegra/board-cardhu-power.c @@ -1,7 +1,7 @@ /* * arch/arm/mach-tegra/board-cardhu-power.c * - * Copyright (C) 2011 NVIDIA, Inc. + * Copyright (C) 2011-2012 NVIDIA, Inc. * * 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 @@ -604,6 +604,7 @@ static struct regulator_consumer_supply fixed_reg_en_vdd_pnl1_supply[] = { static struct regulator_consumer_supply fixed_reg_cam1_ldo_en_supply[] = { REGULATOR_SUPPLY("vdd_2v8_cam1", NULL), REGULATOR_SUPPLY("avdd", "6-0072"), + REGULATOR_SUPPLY("vdd", "6-000e"), }; /* CAM2_LDO_EN from AP GPIO KB_ROW7 R07*/ @@ -649,6 +650,7 @@ static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = { REGULATOR_SUPPLY("vdd_1v8_cam3", NULL), REGULATOR_SUPPLY("dvdd", "6-0072"), REGULATOR_SUPPLY("dvdd", "7-0072"), + REGULATOR_SUPPLY("vdd_i2c", "6-000e"), REGULATOR_SUPPLY("vdd_i2c", "2-0033"), }; @@ -1072,13 +1074,6 @@ int __init cardhu_fixed_regulator_init(void) break; } - for (i = 0; i < nfixreg_devs; ++i) { - struct fixed_voltage_config *fixed_reg_pdata = - fixed_reg_devs[i]->dev.platform_data; - int gpio_nr = fixed_reg_pdata->gpio; - if (gpio_nr < TEGRA_NR_GPIOS) - tegra_gpio_enable(gpio_nr); - } return platform_add_devices(fixed_reg_devs, nfixreg_devs); } subsys_initcall_sync(cardhu_fixed_regulator_init); diff --git a/arch/arm/mach-tegra/board-cardhu-sdhci.c b/arch/arm/mach-tegra/board-cardhu-sdhci.c index c4e631ddc108..cb0684bcc742 100644 --- a/arch/arm/mach-tegra/board-cardhu-sdhci.c +++ b/arch/arm/mach-tegra/board-cardhu-sdhci.c @@ -280,10 +280,6 @@ static int __init cardhu_wifi_init(void) if (rc) pr_err("WLAN_WOW gpio request failed:%d\n", rc); - tegra_gpio_enable(CARDHU_WLAN_PWR); - tegra_gpio_enable(CARDHU_WLAN_RST); - tegra_gpio_enable(CARDHU_WLAN_WOW); - rc = gpio_direction_output(CARDHU_WLAN_PWR, 0); if (rc) pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc); diff --git a/arch/arm/mach-tegra/board-cardhu-sensors.c b/arch/arm/mach-tegra/board-cardhu-sensors.c index 66b3c9dc8ef3..042f740c2935 100644 --- a/arch/arm/mach-tegra/board-cardhu-sensors.c +++ b/arch/arm/mach-tegra/board-cardhu-sensors.c @@ -49,6 +49,7 @@ #include "board.h" #include <linux/mpu.h> #include <media/sh532u.h> +#include <media/ad5816.h> #include <linux/bq27x00.h> #include <mach/gpio.h> #include <mach/edp.h> @@ -87,24 +88,20 @@ static int cardhu_camera_init(void) * and donot have TCA6416 exp for camera */ if ((board_info.board_id == BOARD_E1198) || (board_info.board_id == BOARD_E1291)) { - tegra_gpio_enable(CAM1_POWER_DWN_GPIO); ret = gpio_request(CAM1_POWER_DWN_GPIO, "camera_power_en"); if (ret < 0) pr_err("%s: gpio_request failed for gpio %s\n", __func__, "CAM1_POWER_DWN_GPIO"); - tegra_gpio_enable(CAM3_POWER_DWN_GPIO); ret = gpio_request(CAM3_POWER_DWN_GPIO, "cam3_power_en"); if (ret < 0) pr_err("%s: gpio_request failed for gpio %s\n", __func__, "CAM3_POWER_DWN_GPIO"); - tegra_gpio_enable(CAM2_POWER_DWN_GPIO); ret = gpio_request(CAM2_POWER_DWN_GPIO, "camera2_power_en"); if (ret < 0) pr_err("%s: gpio_request failed for gpio %s\n", __func__, "CAM2_POWER_DWN_GPIO"); - tegra_gpio_enable(OV5650_RESETN_GPIO); ret = gpio_request(OV5650_RESETN_GPIO, "camera_reset"); if (ret < 0) pr_err("%s: gpio_request failed for gpio %s\n", @@ -124,7 +121,6 @@ static int cardhu_camera_init(void) } /* To select the CSIB MUX either for cam2 or cam3 */ - tegra_gpio_enable(CAMERA_CSI_MUX_SEL_GPIO); ret = gpio_request(CAMERA_CSI_MUX_SEL_GPIO, "camera_csi_sel"); if (ret < 0) pr_err("%s: gpio_request failed for gpio %s\n", @@ -601,6 +597,54 @@ static struct sh532u_platform_data pm269_sh532u_right_pdata = { .gpio = pm269_sh532u_right_gpio_pdata, }; +static struct nvc_gpio_pdata ad5816_gpio_pdata[] = { + { AD5816_GPIO_RESET, TEGRA_GPIO_PBB0, false, 0, }, +}; + +static struct ad5816_platform_data ad5816_left_pdata = { + .cfg = NVC_CFG_NODEV, + .num = 1, + .sync = 2, + .dev_name = "focuser", + .gpio_count = ARRAY_SIZE(ad5816_gpio_pdata), + .gpio = ad5816_gpio_pdata, +}; + +static struct ad5816_platform_data ad5816_right_pdata = { + .cfg = NVC_CFG_NODEV, + .num = 2, + .sync = 1, + .dev_name = "focuser", + .gpio_count = ARRAY_SIZE(ad5816_gpio_pdata), + .gpio = ad5816_gpio_pdata, +}; + +static struct nvc_gpio_pdata pm269_ad5816_left_gpio_pdata[] = { + { AD5816_GPIO_RESET, CAM1_RST_L_GPIO, false, 0, }, +}; + +static struct ad5816_platform_data pm269_ad5816_left_pdata = { + .cfg = 0, + .num = 1, + .sync = 2, + .dev_name = "focuser", + .gpio_count = ARRAY_SIZE(pm269_ad5816_left_gpio_pdata), + .gpio = pm269_ad5816_left_gpio_pdata, +}; + +static struct nvc_gpio_pdata pm269_ad5816_right_gpio_pdata[] = { + { AD5816_GPIO_RESET, CAM2_RST_L_GPIO, false, 0, }, +}; + +static struct ad5816_platform_data pm269_ad5816_right_pdata = { + .cfg = 0, + .num = 2, + .sync = 1, + .dev_name = "focuser", + .gpio_count = ARRAY_SIZE(pm269_ad5816_right_gpio_pdata), + .gpio = pm269_ad5816_right_gpio_pdata, +}; + static struct nvc_torch_pin_state cardhu_tps61050_pinstate = { .mask = 0x0008, /*VGP3*/ @@ -628,6 +672,10 @@ static struct i2c_board_info cardhu_i2c6_board_info[] = { I2C_BOARD_INFO("sh532u", 0x72), .platform_data = &sh532u_left_pdata, }, + { + I2C_BOARD_INFO("ad5816", 0x0E), + .platform_data = &ad5816_left_pdata, + }, }; static struct i2c_board_info cardhu_i2c7_board_info[] = { @@ -639,6 +687,10 @@ static struct i2c_board_info cardhu_i2c7_board_info[] = { I2C_BOARD_INFO("sh532u", 0x72), .platform_data = &sh532u_right_pdata, }, + { + I2C_BOARD_INFO("ad5816", 0x0E), + .platform_data = &ad5816_right_pdata, + }, }; static struct i2c_board_info pm269_i2c6_board_info[] = { @@ -650,6 +702,10 @@ static struct i2c_board_info pm269_i2c6_board_info[] = { I2C_BOARD_INFO("sh532u", 0x72), .platform_data = &pm269_sh532u_left_pdata, }, + { + I2C_BOARD_INFO("ad5816", 0x0E), + .platform_data = &pm269_ad5816_left_pdata, + }, }; static struct i2c_board_info pm269_i2c7_board_info[] = { @@ -661,6 +717,10 @@ static struct i2c_board_info pm269_i2c7_board_info[] = { I2C_BOARD_INFO("sh532u", 0x72), .platform_data = &pm269_sh532u_right_pdata, }, + { + I2C_BOARD_INFO("ad5816", 0x0E), + .platform_data = &pm269_ad5816_right_pdata, + }, }; static struct i2c_board_info cardhu_i2c8_board_info[] = { @@ -785,8 +845,6 @@ static int cardhu_nct1008_init(void) ret = gpio_direction_input(nct1008_port); if (ret < 0) gpio_free(nct1008_port); - else - tegra_gpio_enable(nct1008_port); } return ret; @@ -916,7 +974,6 @@ static void mpuirq_init(void) #if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050) #if MPU_ACCEL_IRQ_GPIO /* ACCEL-IRQ assignment */ - tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO); ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME); if (ret < 0) { pr_err("%s: gpio_request failed %d\n", __func__, ret); @@ -933,7 +990,6 @@ static void mpuirq_init(void) #endif /* MPU-IRQ assignment */ - tegra_gpio_enable(MPU_GYRO_IRQ_GPIO); ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME); if (ret < 0) { pr_err("%s: gpio_request failed %d\n", __func__, ret); diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c index 9083828b8352..4480ab3ef47b 100644 --- a/arch/arm/mach-tegra/board-cardhu.c +++ b/arch/arm/mach-tegra/board-cardhu.c @@ -86,43 +86,6 @@ static struct tegra_thermal_data thermal_data = { #endif }; -/* !!!TODO: Change for cardhu (Taken from Ventana) */ -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [2] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - static struct resource cardhu_bcm4329_rfkill_resources[] = { { .name = "bcm4329_nshutdown_gpio", @@ -170,8 +133,6 @@ static struct platform_device cardhu_bluesleep_device = { static noinline void __init cardhu_setup_bluesleep(void) { platform_device_register(&cardhu_bluesleep_device); - tegra_gpio_enable(TEGRA_GPIO_PU6); - tegra_gpio_enable(TEGRA_GPIO_PU1); return; } @@ -845,9 +806,6 @@ static int __init cardhu_touch_init(void) touch_init_raydium(TEGRA_GPIO_PH4, TEGRA_GPIO_PH6, 2); } else { - tegra_gpio_enable(TEGRA_GPIO_PH4); - tegra_gpio_enable(TEGRA_GPIO_PH6); - gpio_request(TEGRA_GPIO_PH4, "atmel-irq"); gpio_direction_input(TEGRA_GPIO_PH4); @@ -869,135 +827,287 @@ static int __init cardhu_touch_init(void) return 0; } -static struct tegra_uhsic_config uhsic_phy_config = { - .enable_gpio = EN_HSIC_GPIO, - .reset_gpio = -1, - .sync_start_delay = 9, - .idle_wait_delay = 17, - .term_range_adj = 0, - .elastic_underrun_limit = 16, - .elastic_overrun_limit = 16, -}; - -static struct tegra_ehci_platform_data tegra_ehci_uhsic_pdata = { - .phy_type = TEGRA_USB_PHY_TYPE_HSIC, - .phy_config = &uhsic_phy_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = true, -}; - -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = true, - }, - [1] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = true, - }, - [2] = { - .phy_config = &utmi_phy_config[2], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .hotplug = 1, - .default_enable = true, - }, -}; - -static struct tegra_otg_platform_data tegra_otg_pdata = { - .ehci_device = &tegra_ehci1_device, - .ehci_pdata = &tegra_ehci_pdata[0], -}; - -#ifdef CONFIG_USB_SUPPORT -static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { - [0] = { - .instance = 0, - .vbus_gpio = -1, - .vbus_reg_supply = "vdd_vbus_micro_usb", - }, - [1] = { - .instance = 1, - .vbus_gpio = -1, - }, - [2] = { - .instance = 2, - .vbus_gpio = -1, - .vbus_reg_supply = "vdd_vbus_typea_usb", - }, -}; - -static int cardhu_usb_hsic_postsupend(void) +static void cardu_usb_hsic_postsupend(void) { #ifdef CONFIG_TEGRA_BB_XMM_POWER baseband_xmm_set_power_status(BBXMM_PS_L2); #endif - return 0; } -static int cardhu_usb_hsic_preresume(void) +static void cardu_usb_hsic_preresume(void) { #ifdef CONFIG_TEGRA_BB_XMM_POWER baseband_xmm_set_power_status(BBXMM_PS_L2TOL0); #endif - return 0; } -static int cardhu_usb_hsic_phy_ready(void) +static void cardu_usb_hsic_phy_ready(void) { #ifdef CONFIG_TEGRA_BB_XMM_POWER baseband_xmm_set_power_status(BBXMM_PS_L0); #endif - return 0; } -static int cardhu_usb_hsic_phy_off(void) +static void cardu_usb_hsic_phy_off(void) { #ifdef CONFIG_TEGRA_BB_XMM_POWER baseband_xmm_set_power_status(BBXMM_PS_L3); #endif - return 0; } +static struct tegra_usb_phy_platform_ops hsic_xmm_plat_ops = { + .post_suspend = cardu_usb_hsic_postsupend, + .pre_resume = cardu_usb_hsic_preresume, + .port_power = cardu_usb_hsic_phy_ready, + .post_phy_off = cardu_usb_hsic_phy_off, +}; + +static struct tegra_usb_platform_data tegra_ehci2_hsic_xmm_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_HSIC, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .hot_plug = false, + .remote_wakeup_supported = false, + .power_off_on_suspend = false, + }, + .u_cfg.hsic = { + .sync_start_delay = 9, + .idle_wait_delay = 17, + .term_range_adj = 0, + .elastic_underrun_limit = 16, + .elastic_overrun_limit = 16, + }, + .ops = &hsic_xmm_plat_ops, +}; + + +static int hsic_enable_gpio = -1; +static int hsic_reset_gpio = -1; + +void hsic_platform_open(void) +{ + int reset_gpio = 0, enable_gpio = 0; + + if (hsic_enable_gpio != -1) + enable_gpio = gpio_request(hsic_enable_gpio, "uhsic_enable"); + if (hsic_reset_gpio != -1) + reset_gpio = gpio_request(hsic_reset_gpio, "uhsic_reset"); + /* hsic enable signal deasserted, hsic reset asserted */ + if (!enable_gpio) + gpio_direction_output(hsic_enable_gpio, 0 /* deasserted */); + if (!reset_gpio) + gpio_direction_output(hsic_reset_gpio, 0 /* asserted */); + if (!enable_gpio) + tegra_gpio_enable(hsic_enable_gpio); + if (!reset_gpio) + tegra_gpio_enable(hsic_reset_gpio); + /* keep hsic reset asserted for 1 ms */ + udelay(1000); + /* enable (power on) hsic */ + if (!enable_gpio) + gpio_set_value_cansleep(hsic_enable_gpio, 1); + udelay(1000); + /* deassert reset */ + if (!reset_gpio) + gpio_set_value_cansleep(hsic_reset_gpio, 1); + +} + +void hsic_platform_close(void) +{ + if (hsic_enable_gpio != -1) { + gpio_set_value(hsic_enable_gpio, 0); + gpio_free(hsic_enable_gpio); + } + if (hsic_reset_gpio != -1) { + gpio_set_value(hsic_reset_gpio, 0); + gpio_free(hsic_reset_gpio); + } +} + +void hsic_power_on(void) +{ + if (hsic_enable_gpio != -1) { + gpio_set_value_cansleep(hsic_enable_gpio, 1); + udelay(1000); + } +} + +void hsic_power_off(void) +{ + if (hsic_enable_gpio != -1) { + gpio_set_value_cansleep(hsic_enable_gpio, 0); + udelay(1000); + } +} + +static struct tegra_usb_phy_platform_ops hsic_plat_ops = { + .open = hsic_platform_open, + .close = hsic_platform_close, + .pre_phy_on = hsic_power_on, + .post_phy_off = hsic_power_off, +}; + +static struct tegra_usb_platform_data tegra_ehci2_hsic_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_HSIC, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .hot_plug = false, + .remote_wakeup_supported = false, + .power_off_on_suspend = false, + }, + .u_cfg.hsic = { + .sync_start_delay = 9, + .idle_wait_delay = 17, + .term_range_adj = 0, + .elastic_underrun_limit = 16, + .elastic_overrun_limit = 16, + }, + .ops = &hsic_plat_ops, +}; + +static struct tegra_usb_platform_data tegra_udc_pdata = { + .port_otg = true, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_DEVICE, + .u_data.dev = { + .vbus_pmu_irq = 0, + .vbus_gpio = -1, + .charging_supported = false, + .remote_wakeup_supported = false, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, +}; + +static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { + .port_otg = true, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = "vdd_vbus_micro_usb", + .hot_plug = true, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, +}; + +static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .hot_plug = false, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, +}; + +static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = "vdd_vbus_typea_usb", + .hot_plug = true, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, +}; + +static struct tegra_usb_otg_data tegra_otg_pdata = { + .ehci_device = &tegra_ehci1_device, + .ehci_pdata = &tegra_ehci1_utmi_pdata, +}; + +#if CONFIG_USB_SUPPORT static void cardhu_usb_init(void) { struct board_info bi; tegra_get_board_info(&bi); - tegra_usb_phy_init(tegra_usb_phy_pdata, - ARRAY_SIZE(tegra_usb_phy_pdata)); - + /* OTG should be the first to be registered */ tegra_otg_device.dev.platform_data = &tegra_otg_pdata; platform_device_register(&tegra_otg_device); + + /* setup the udc platform data */ + tegra_udc_device.dev.platform_data = &tegra_udc_pdata; + if (bi.board_id == BOARD_PM267) { - uhsic_phy_config.reset_gpio = - PM267_SMSC4640_HSIC_HUB_RESET_GPIO; - tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata; + hsic_enable_gpio = EN_HSIC_GPIO; + hsic_reset_gpio = PM267_SMSC4640_HSIC_HUB_RESET_GPIO; + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_hsic_pdata; platform_device_register(&tegra_ehci2_device); } else if (bi.board_id == BOARD_E1256) { - tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata; + hsic_enable_gpio = EN_HSIC_GPIO; + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_hsic_pdata; platform_device_register(&tegra_ehci2_device); } else if (bi.board_id == BOARD_E1186) { - /* for baseband devices do not switch off phy during suspend */ - tegra_ehci_uhsic_pdata.power_down_on_bus_suspend = 0; - uhsic_phy_config.postsuspend = cardhu_usb_hsic_postsupend; - uhsic_phy_config.preresume = cardhu_usb_hsic_preresume; - uhsic_phy_config.usb_phy_ready = cardhu_usb_hsic_phy_ready; - uhsic_phy_config.post_phy_off = cardhu_usb_hsic_phy_off; - tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata; - /* baseband registration happens in baseband-xmm-power */ + tegra_ehci2_device.dev.platform_data = + &tegra_ehci2_hsic_xmm_pdata; + /* ehci2 registration happens in baseband-xmm-power */ } else { - tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_utmi_pdata; platform_device_register(&tegra_ehci2_device); } - tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2]; + tegra_ehci3_device.dev.platform_data = &tegra_ehci3_utmi_pdata; platform_device_register(&tegra_ehci3_device); } @@ -1005,19 +1115,6 @@ static void cardhu_usb_init(void) static void cardhu_usb_init(void) { } #endif -static void cardhu_gps_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PU2); - tegra_gpio_enable(TEGRA_GPIO_PU3); -} - -static void cardhu_nfc_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PX0); - tegra_gpio_enable(TEGRA_GPIO_PP3); - tegra_gpio_enable(TEGRA_GPIO_PO7); -} - static struct baseband_power_platform_data tegra_baseband_power_data = { .baseband_type = BASEBAND_XMM, .modem = { @@ -1095,7 +1192,7 @@ static void cardhu_modem_init(void) } else { w_disable_gpio = TEGRA_GPIO_PDD5; } - tegra_gpio_enable(w_disable_gpio); + ret = gpio_request(w_disable_gpio, "w_disable_gpio"); if (ret < 0) pr_err("%s: gpio_request failed for gpio %d\n", @@ -1115,22 +1212,9 @@ static void cardhu_modem_init(void) break; } gpio_direction_output(TEGRA_GPIO_PH7, 1); - tegra_gpio_enable(TEGRA_GPIO_PH7); } break; case BOARD_E1186: - tegra_gpio_enable( - tegra_baseband_power_data.modem.xmm.bb_rst); - tegra_gpio_enable( - tegra_baseband_power_data.modem.xmm.bb_on); - tegra_gpio_enable( - tegra_baseband_power_data.modem.xmm.ipc_bb_wake); - tegra_gpio_enable( - tegra_baseband_power_data.modem.xmm.ipc_ap_wake); - tegra_gpio_enable( - tegra_baseband_power_data.modem.xmm.ipc_hsic_active); - tegra_gpio_enable( - tegra_baseband_power_data.modem.xmm.ipc_hsic_sus_req); platform_device_register(&tegra_baseband_power_device); platform_device_register(&tegra_baseband_power2_device); break; @@ -1168,7 +1252,6 @@ static void __init tegra_cardhu_init(void) cardhu_dtv_init(); cardhu_suspend_init(); cardhu_touch_init(); - cardhu_gps_init(); cardhu_modem_init(); cardhu_kbc_init(); cardhu_scroll_init(); @@ -1182,7 +1265,6 @@ static void __init tegra_cardhu_init(void) cardhu_pins_state_init(); cardhu_emc_init(); tegra_release_bootloader_fb(); - cardhu_nfc_init(); cardhu_pci_init(); #ifdef CONFIG_TEGRA_WDT_RECOVERY tegra_wdt_recovery_init(); diff --git a/arch/arm/mach-tegra/board-enterprise-baseband.c b/arch/arm/mach-tegra/board-enterprise-baseband.c index 7552e2871541..9143103fd036 100644 --- a/arch/arm/mach-tegra/board-enterprise-baseband.c +++ b/arch/arm/mach-tegra/board-enterprise-baseband.c @@ -67,35 +67,42 @@ static struct gpio modem_gpios[] = { {ULPI_D1, GPIOF_OUT_INIT_LOW, "ULPI_D1"}, }; -static int baseband_phy_on(void); -static int baseband_phy_off(void); -static void baseband_phy_restore_start(void); -static void baseband_phy_restore_end(void); +static void baseband_phy_init(void); +static void baseband_phy_on(void); +static void baseband_phy_off(void); -static struct tegra_ulpi_trimmer e1219_trimmer = { 10, 1, 1, 1 }; - -static struct tegra_ulpi_config ehci2_null_ulpi_phy_config = { - .trimmer = &e1219_trimmer, - .post_phy_on = baseband_phy_on, +static struct tegra_usb_phy_platform_ops ulpi_null_plat_ops = { + .init = baseband_phy_init, .pre_phy_off = baseband_phy_off, - .phy_restore_start = baseband_phy_restore_start, - .phy_restore_end = baseband_phy_restore_end, - .phy_restore_gpio = MDM2AP_ACK, - .ulpi_dir_gpio = ULPI_DIR, - .ulpi_d0_gpio = ULPI_D0, - .ulpi_d1_gpio = ULPI_D1, + .post_phy_on = baseband_phy_on, }; -static struct tegra_ehci_platform_data ehci2_null_ulpi_platform_data = { - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 0, - .phy_config = &ehci2_null_ulpi_phy_config, - .phy_type = TEGRA_USB_PHY_TYPE_NULL_ULPI, +static struct tegra_usb_platform_data tegra_ehci2_ulpi_null_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_ULPI_NULL, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = false, + .power_off_on_suspend = true, + }, + .u_cfg.ulpi = { + .shadow_clk_delay = 10, + .clock_out_delay = 1, + .data_trimmer = 1, + .stpdirnxt_trimmer = 1, + .dir_trimmer = 1, + .clk = NULL, + }, + .ops = &ulpi_null_plat_ops, }; static int __init tegra_null_ulpi_init(void) { - tegra_ehci2_device.dev.platform_data = &ehci2_null_ulpi_platform_data; + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_ulpi_null_pdata; platform_device_register(&tegra_ehci2_device); return 0; } @@ -114,7 +121,7 @@ static irqreturn_t mdm_start_thread(int irq, void *data) return IRQ_HANDLED; } -static int baseband_phy_on(void) +static void baseband_phy_init(void) { static bool phy_init = false; @@ -124,22 +131,15 @@ static int baseband_phy_on(void) phy_init = true; } pr_info("%s\n", __func__); - return 0; -} - -static int baseband_phy_off(void) -{ - pr_info("%s\n", __func__); - return 0; } -static void baseband_phy_restore_start(void) +static void baseband_phy_off(void) { /* set AP2MDM_ACK2 high */ gpio_set_value(AP2MDM_ACK2, 1); } -static void baseband_phy_restore_end(void) +static void baseband_phy_on(void) { /* set AP2MDM_ACK2 low */ gpio_set_value(AP2MDM_ACK2, 0); diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c index a95ee617b1a8..d92ac57dd054 100644 --- a/arch/arm/mach-tegra/board-enterprise.c +++ b/arch/arm/mach-tegra/board-enterprise.c @@ -79,43 +79,6 @@ static struct tegra_thermal_data thermal_data = { #endif }; -/* !!!TODO: Change for enterprise (Taken from Cardhu) */ -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [2] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - static struct resource enterprise_bcm4329_rfkill_resources[] = { { .name = "bcm4329_nshutdown_gpio", @@ -653,66 +616,120 @@ static int __init enterprise_touch_init(void) return 0; } -static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { - [0] = { - .instance = 0, - .vbus_gpio = -1, - .vbus_reg_supply = "usb_vbus", - .vbus_irq = ENT_TPS80031_IRQ_BASE + - TPS80031_INT_VBUS_DET, - }, - [1] = { - .instance = 1, - .vbus_gpio = -1, - }, - [2] = { - .instance = 2, - .vbus_gpio = -1, - }, -}; +static void enterprise_usb_hsic_postsupend(void) +{ + pr_debug("%s\n", __func__); +#ifdef CONFIG_TEGRA_BB_XMM_POWER + baseband_xmm_set_power_status(BBXMM_PS_L2); +#endif +} -static struct tegra_uhsic_config uhsic_phy_config = { - .enable_gpio = -1, - .reset_gpio = -1, - .sync_start_delay = 9, - .idle_wait_delay = 17, - .term_range_adj = 0, - .elastic_underrun_limit = 16, - .elastic_overrun_limit = 16, -}; +static void enterprise_usb_hsic_preresume(void) +{ + pr_debug("%s\n", __func__); +#ifdef CONFIG_TEGRA_BB_XMM_POWER + baseband_xmm_set_power_status(BBXMM_PS_L2TOL0); +#endif +} -static struct tegra_ehci_platform_data tegra_ehci_uhsic_pdata = { - .phy_type = TEGRA_USB_PHY_TYPE_HSIC, - .phy_config = &uhsic_phy_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = true, -}; +static void enterprise_usb_hsic_phy_power(void) +{ + pr_debug("%s\n", __func__); +#ifdef CONFIG_TEGRA_BB_XMM_POWER + baseband_xmm_set_power_status(BBXMM_PS_L0); +#endif +} -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = false, - }, - [1] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = false, - }, - [2] = { - .phy_config = &utmi_phy_config[2], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = false, - }, -}; +static void enterprise_usb_hsic_post_phy_off(void) +{ + pr_debug("%s\n", __func__); +#ifdef CONFIG_TEGRA_BB_XMM_POWER + baseband_xmm_set_power_status(BBXMM_PS_L3); +#endif +} -static struct tegra_otg_platform_data tegra_otg_pdata = { +static struct tegra_usb_phy_platform_ops hsic_xmm_plat_ops = { + .post_suspend = enterprise_usb_hsic_postsupend, + .pre_resume = enterprise_usb_hsic_preresume, + .port_power = enterprise_usb_hsic_phy_power, + .post_phy_off = enterprise_usb_hsic_post_phy_off, +}; + +static struct tegra_usb_platform_data tegra_ehci2_hsic_xmm_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_HSIC, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .hot_plug = false, + .remote_wakeup_supported = false, + .power_off_on_suspend = false, + }, + .u_cfg.hsic = { + .sync_start_delay = 9, + .idle_wait_delay = 17, + .term_range_adj = 0, + .elastic_underrun_limit = 16, + .elastic_overrun_limit = 16, + }, + .ops = &hsic_xmm_plat_ops, +}; + + + +static struct tegra_usb_platform_data tegra_udc_pdata = { + .port_otg = true, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_DEVICE, + .u_data.dev = { + .vbus_pmu_irq = 0, + .vbus_gpio = -1, + .charging_supported = false, + .remote_wakeup_supported = false, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, +}; + +static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { + .port_otg = true, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = "usb_vbus", + .hot_plug = true, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, +}; + +static struct tegra_usb_otg_data tegra_otg_pdata = { .ehci_device = &tegra_ehci1_device, - .ehci_pdata = &tegra_ehci_pdata[0], + .ehci_pdata = &tegra_ehci1_utmi_pdata, }; struct platform_device *tegra_usb_hsic_host_register(void) @@ -733,8 +750,8 @@ struct platform_device *tegra_usb_hsic_host_register(void) pdev->dev.dma_mask = tegra_ehci2_device.dev.dma_mask; pdev->dev.coherent_dma_mask = tegra_ehci2_device.dev.coherent_dma_mask; - val = platform_device_add_data(pdev, &tegra_ehci_uhsic_pdata, - sizeof(struct tegra_ehci_platform_data)); + val = platform_device_add_data(pdev, &tegra_ehci2_hsic_xmm_pdata, + sizeof(struct tegra_usb_platform_data)); if (val) goto error; @@ -755,52 +772,12 @@ void tegra_usb_hsic_host_unregister(struct platform_device *pdev) platform_device_unregister(pdev); } -static int enterprise_usb_hsic_postsupend(void) -{ - pr_debug("%s\n", __func__); -#ifdef CONFIG_TEGRA_BB_XMM_POWER - baseband_xmm_set_power_status(BBXMM_PS_L2); -#endif - return 0; -} - -static int enterprise_usb_hsic_preresume(void) -{ - pr_debug("%s\n", __func__); -#ifdef CONFIG_TEGRA_BB_XMM_POWER - baseband_xmm_set_power_status(BBXMM_PS_L2TOL0); -#endif - return 0; -} - -static int enterprise_usb_hsic_phy_ready(void) -{ - pr_debug("%s\n", __func__); -#ifdef CONFIG_TEGRA_BB_XMM_POWER - baseband_xmm_set_power_status(BBXMM_PS_L0); -#endif - return 0; -} - -static int enterprise_usb_hsic_phy_off(void) -{ - pr_debug("%s\n", __func__); -#ifdef CONFIG_TEGRA_BB_XMM_POWER - baseband_xmm_set_power_status(BBXMM_PS_L3); -#endif - return 0; -} - static void enterprise_usb_init(void) { - struct fsl_usb2_platform_data *udc_pdata; - - tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata)); + tegra_udc_device.dev.platform_data = &tegra_udc_pdata; tegra_otg_device.dev.platform_data = &tegra_otg_pdata; platform_device_register(&tegra_otg_device); - - udc_pdata = tegra_udc_device.dev.platform_data; } static struct platform_device *enterprise_audio_devices[] __initdata = { @@ -910,12 +887,9 @@ static void enterprise_baseband_init(void) enterprise_modem_init(); break; case TEGRA_BB_XMM6260: /* XMM6260 HSIC */ - /* xmm baseband - do not switch off phy during suspend */ - tegra_ehci_uhsic_pdata.power_down_on_bus_suspend = 0; - uhsic_phy_config.postsuspend = enterprise_usb_hsic_postsupend; - uhsic_phy_config.preresume = enterprise_usb_hsic_preresume; - uhsic_phy_config.usb_phy_ready = enterprise_usb_hsic_phy_ready; - uhsic_phy_config.post_phy_off = enterprise_usb_hsic_phy_off; + /* baseband-power.ko will register ehci2 device */ + tegra_ehci2_device.dev.platform_data = + &tegra_ehci2_hsic_xmm_pdata; /* enable XMM6260 baseband gpio(s) */ tegra_gpio_enable(tegra_baseband_power_data.modem.generic .mdm_reset); @@ -938,9 +912,9 @@ static void enterprise_baseband_init(void) break; #ifdef CONFIG_TEGRA_BB_M7400 case TEGRA_BB_M7400: /* M7400 HSIC */ - tegra_ehci_uhsic_pdata.power_down_on_bus_suspend = 0; + tegra_ehci2_hsic_xmm_pdata.u_data.host.power_off_on_suspend = 0; tegra_ehci2_device.dev.platform_data - = &tegra_ehci_uhsic_pdata; + = &tegra_ehci2_hsic_xmm_pdata; platform_device_register(&tegra_baseband_m7400_device); break; #endif diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c index f3db0eeba2c9..f73cde4c5570 100644 --- a/arch/arm/mach-tegra/board-harmony-pcie.c +++ b/arch/arm/mach-tegra/board-harmony-pcie.c @@ -4,6 +4,8 @@ * Copyright (C) 2010 CompuLab, Ltd. * Mike Rapoport <mike@compulab.co.il> * + * Copyright (C) 2011-2012 NVIDIA Corporation. + * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. @@ -68,7 +70,6 @@ int __init harmony_pcie_init(void) return 0; -err_pcie: tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_TRISTATE); tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE); tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE); diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 9bf8cde056a3..638c851fa7a8 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -32,6 +32,8 @@ #include <linux/i2c-tegra.h> #include <linux/memblock.h> #include <linux/delay.h> +#include <linux/mfd/tps6586x.h> +#include <linux/platform_data/tegra_usb.h> #include <sound/wm8903.h> @@ -81,20 +83,52 @@ static int __init parse_tag_nvidia(const struct tag *tag) } __tagtable(ATAG_NVIDIA, parse_tag_nvidia); -static struct tegra_utmip_config utmi_phy_config = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 9, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, + +static struct tegra_usb_platform_data tegra_udc_pdata = { + .port_otg = false, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_DEVICE, + .u_data.dev = { + .vbus_pmu_irq = 0, + .vbus_gpio = -1, + .charging_supported = false, + .remote_wakeup_supported = false, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, }; -static struct tegra_ehci_platform_data tegra_ehci_pdata = { - .phy_config = &utmi_phy_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, +static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = { + .port_otg = false, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = TEGRA_GPIO_PD3, + .vbus_reg = NULL, + .hot_plug = true, + .remote_wakeup_supported = false, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 9, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + }, }; static struct tegra_nand_chip_parms nand_chip_parms[] = { @@ -283,39 +317,6 @@ static void __init harmony_i2c_init(void) i2c_register_board_info(0, &wm8903_board_info, 1); } -/* OTG gadget device */ -/*static u64 tegra_otg_dmamask = DMA_BIT_MASK(32); - - -static struct resource tegra_otg_resources[] = { - [0] = { - .start = TEGRA_USB_BASE, - .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_USB, - .end = INT_USB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct fsl_usb2_platform_data tegra_otg_pdata = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, -}; - -static struct platform_device tegra_otg = { - .name = "fsl-tegra-udc", - .id = -1, - .dev = { - .dma_mask = &tegra_otg_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &tegra_otg_pdata, - }, - .resource = tegra_otg_resources, - .num_resources = ARRAY_SIZE(tegra_otg_resources), -};*/ /* PDA power */ static struct pda_power_pdata pda_power_pdata = { @@ -476,7 +477,8 @@ static void __init tegra_harmony_init(void) tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2; tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; - tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata; + tegra_udc_device.dev.platform_data = &tegra_udc_pdata; + tegra_ehci3_device.dev.platform_data = &tegra_ehci3_utmi_pdata; platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); harmony_i2c_init(); diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c index c455fba4cef9..193d68632d52 100644 --- a/arch/arm/mach-tegra/board-kai.c +++ b/arch/arm/mach-tegra/board-kai.c @@ -82,42 +82,6 @@ static struct tegra_thermal_data thermal_data = { #endif }; -/* !!!TODO: Change for kai (Taken from Ventana) */ -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [2] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; /* wl128x BT, FM, GPS connectivity chip */ struct ti_st_plat_data kai_wilink_pdata = { @@ -165,8 +129,15 @@ static struct platform_device kai_bluesleep_device = { static noinline void __init kai_tegra_setup_tibluesleep(void) { + int ret; + + ret = gpio_request(TEGRA_GPIO_PU6, "host_wake"); + if (ret) + pr_err("gpio_request failed for gpio: %d\n", TEGRA_GPIO_PU6); + else + gpio_direction_input(TEGRA_GPIO_PU6); + platform_device_register(&kai_bluesleep_device); - tegra_gpio_enable(TEGRA_GPIO_PU6); } static __initdata struct tegra_clk_init_table kai_clk_init_table[] = { @@ -695,47 +666,97 @@ static int __init kai_touch_init(void) return 0; } -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = true, +static struct tegra_usb_platform_data tegra_udc_pdata = { + .port_otg = true, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_DEVICE, + .u_data.dev = { + .vbus_pmu_irq = 0, + .vbus_gpio = -1, + .charging_supported = false, + .remote_wakeup_supported = false, }, - [1] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = false, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, }, }; -static struct tegra_otg_platform_data tegra_otg_pdata = { - .ehci_device = &tegra_ehci1_device, - .ehci_pdata = &tegra_ehci_pdata[0], +static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { + .port_otg = true, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = true, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + }, }; -#ifdef CONFIG_USB_SUPPORT -static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { - [0] = { - .instance = 0, - .vbus_gpio = -1, + +static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, + }, - [1] = { - .instance = 1, - .vbus_gpio = -1, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, }, }; +static struct tegra_usb_otg_data tegra_otg_pdata = { + .ehci_device = &tegra_ehci1_device, + .ehci_pdata = &tegra_ehci1_utmi_pdata, +}; + +#if CONFIG_USB_SUPPORT static void kai_usb_init(void) { - tegra_usb_phy_init(tegra_usb_phy_pdata, - ARRAY_SIZE(tegra_usb_phy_pdata)); - tegra_otg_device.dev.platform_data = &tegra_otg_pdata; platform_device_register(&tegra_otg_device); - tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; + /* Setup the udc platform data */ + tegra_udc_device.dev.platform_data = &tegra_udc_pdata; + + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_utmi_pdata; platform_device_register(&tegra_ehci2_device); } diff --git a/arch/arm/mach-tegra/board-p1852.c b/arch/arm/mach-tegra/board-p1852.c index 43bef9975187..71c12756539d 100644 --- a/arch/arm/mach-tegra/board-p1852.c +++ b/arch/arm/mach-tegra/board-p1852.c @@ -57,42 +57,6 @@ #include "gpio-names.h" #include "fuse.h" -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [2] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - static __initdata struct tegra_clk_init_table p1852_clk_init_table[] = { /* name parent rate enabled */ { "pll_m", NULL, 0, true}, @@ -101,9 +65,10 @@ static __initdata struct tegra_clk_init_table p1852_clk_init_table[] = { { "pwm", "clk_32k", 32768, false}, { "blink", "clk_32k", 32768, true}, { "pll_a", NULL, 552960000, false}, - { "pll_a_out0", NULL, 12288000, false}, - { "d_audio", "pll_a_out0", 12288000, false}, - { "nor", "pll_p", 102000000, true}, + /* audio cif clock should be faster than i2s */ + { "pll_a_out0", NULL, 24576000, false}, + { "d_audio", "pll_a_out0", 24576000, false}, + { "nor", "pll_p", 86500000, true}, { "uarta", "pll_p", 480000000, true}, { "uartd", "pll_p", 480000000, true}, { "uarte", "pll_p", 480000000, true}, @@ -115,11 +80,11 @@ static __initdata struct tegra_clk_init_table p1852_clk_init_table[] = { { "sbc5", "pll_m", 100000000, true}, { "sbc6", "pll_m", 100000000, true}, { "cpu_g", "cclk_g", 900000000, true}, - { "i2s0", "pll_a_out0", 12288000, false}, - { "i2s1", "pll_a_out0", 12288000, false}, - { "i2s2", "pll_a_out0", 12288000, false}, - { "i2s3", "pll_a_out0", 12288000, false}, - { "i2s4", "pll_a_out0", 12288000, false}, + { "i2s0", "pll_a_out0", 24576000, false}, + { "i2s1", "pll_a_out0", 24576000, false}, + { "i2s2", "pll_a_out0", 24576000, false}, + { "i2s3", "pll_a_out0", 24576000, false}, + { "i2s4", "pll_a_out0", 24576000, false}, { "audio0", "i2s0_sync", 12288000, false}, { "audio1", "i2s1_sync", 12288000, false}, { "audio2", "i2s2_sync", 12288000, false}, @@ -241,16 +206,24 @@ static struct tegra_p1852_platform_data p1852_audio_pdata = { .cpu_dai_name = "tegra30-i2s.0", .codec_name = "spdif-dit.0", .name = "tegra-i2s-1", - .i2s_format = format_i2s, + .i2s_format = format_tdm, .master = 1, + .num_slots = 4, + .slot_width = 32, + .tx_mask = 0x0f, + .rx_mask = 0x0f, }, .codec_info[1] = { .codec_dai_name = "dit-hifi", - .cpu_dai_name = "tegra30-i2s.1", + .cpu_dai_name = "tegra30-i2s.4", .codec_name = "spdif-dit.1", .name = "tegra-i2s-2", - .i2s_format = format_i2s, - .master = 0, + .i2s_format = format_tdm, + .master = 1, + .num_slots = 8, + .slot_width = 32, + .tx_mask = 0xff, + .rx_mask = 0xff, }, }; @@ -278,7 +251,7 @@ static void p1852_i2s_audio_init(void) platform_device_register(&generic_codec_1); platform_device_register(&generic_codec_2); platform_device_register(&tegra_i2s_device0); - platform_device_register(&tegra_i2s_device1); + platform_device_register(&tegra_i2s_device4); platform_device_register(&tegra_ahub_device); platform_device_register(&tegra_snd_p1852); } @@ -349,56 +322,91 @@ static struct platform_device *p1852_devices[] __initdata = { &tegra_wdt_device }; -static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { - [0] = { - .instance = 0, - .vbus_gpio = -1, - .vbus_reg_supply = NULL, +static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, }, - [1] = { - .instance = 1, - .vbus_gpio = -1, - }, - [2] = { - .instance = 2, - .vbus_gpio = -1, - .vbus_reg_supply = NULL, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, }, }; -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, +static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, }, - [1] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, +}; + +static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = true, + .power_off_on_suspend = true, }, - [2] = { - .phy_config = &utmi_phy_config[2], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, }, }; static void p1852_usb_init(void) { - /* Need to parse sku info to decide host/device mode */ - tegra_usb_phy_init(tegra_usb_phy_pdata, - ARRAY_SIZE(tegra_usb_phy_pdata)); - - tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0]; + tegra_ehci1_device.dev.platform_data = &tegra_ehci1_utmi_pdata; platform_device_register(&tegra_ehci1_device); - tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_utmi_pdata; platform_device_register(&tegra_ehci2_device); - tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2]; + tegra_ehci3_device.dev.platform_data = &tegra_ehci3_utmi_pdata; platform_device_register(&tegra_ehci3_device); - } static struct tegra_nor_platform_data p1852_nor_data = { diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c index 823060ec478f..626cd1b34114 100644 --- a/arch/arm/mach-tegra/board-trimslice.c +++ b/arch/arm/mach-tegra/board-trimslice.c @@ -6,6 +6,7 @@ * * Based on board-harmony.c * Copyright (C) 2010 Google, Inc. + * Copyright (C) 2011-2012 NVIDIA Corporation. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -95,7 +96,7 @@ static struct platform_device *trimslice_devices[] __initdata = { &tegra_das_device, &tegra_pcm_device, &trimslice_audio_device, - &trimslice_pci_platform_data, + &tegra_pci_device, }; static struct i2c_board_info trimslice_i2c3_board_info[] = { diff --git a/arch/arm/mach-tegra/board-ventana.c b/arch/arm/mach-tegra/board-ventana.c index d371e720fdcf..779ffdba0f65 100644 --- a/arch/arm/mach-tegra/board-ventana.c +++ b/arch/arm/mach-tegra/board-ventana.c @@ -63,35 +63,6 @@ #include "wakeups-t2.h" #include "pm.h" -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - -static struct tegra_ulpi_config ulpi_phy_config = { - .reset_gpio = TEGRA_GPIO_PG2, - .clk = "cdev2", -}; static struct resource ventana_bcm4329_rfkill_resources[] = { { @@ -164,19 +135,6 @@ static __initdata struct tegra_clk_init_table ventana_clk_init_table[] = { { NULL, NULL, 0, 0}, }; -static struct tegra_ulpi_config ventana_ehci2_ulpi_phy_config = { - .reset_gpio = TEGRA_GPIO_PV1, - .clk = "cdev2", -}; - -static struct tegra_ehci_platform_data ventana_ehci2_ulpi_platform_data = { - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .phy_config = &ventana_ehci2_ulpi_phy_config, - .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI, - .default_enable = true, -}; - static struct tegra_i2c_platform_data ventana_i2c1_platform_data = { .adapter_nr = 0, .bus_count = 1, @@ -498,73 +456,146 @@ static int __init ventana_touch_init_panjit(void) return 0; } -static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { - [0] = { - .instance = 0, - .vbus_irq = TPS6586X_INT_BASE + TPS6586X_INT_USB_DET, - .vbus_gpio = TEGRA_GPIO_PD0, +static int __init ventana_gps_init(void) +{ + struct clk *clk32 = clk_get_sys(NULL, "blink"); + if (!IS_ERR(clk32)) { + clk_set_rate(clk32,clk32->parent->rate); + clk_enable(clk32); + } + + tegra_gpio_enable(TEGRA_GPIO_PZ3); + return 0; +} + +static struct tegra_usb_platform_data tegra_udc_pdata = { + .port_otg = true, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_DEVICE, + .u_data.dev = { + .vbus_pmu_irq = 0, + .vbus_gpio = -1, + .charging_supported = false, + .remote_wakeup_supported = false, }, - [1] = { - .instance = 1, - .vbus_gpio = -1, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, }, - [2] = { - .instance = 2, - .vbus_gpio = TEGRA_GPIO_PD3, +}; + +static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { + .port_otg = true, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = TEGRA_GPIO_PD0, + .vbus_reg = NULL, + .hot_plug = true, + .remote_wakeup_supported = false, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 9, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, }, }; -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = true, +static void ulpi_link_platform_open(void) +{ + int reset_gpio = TEGRA_GPIO_PV1; + + gpio_request(reset_gpio, "ulpi_phy_reset"); + gpio_direction_output(reset_gpio, 0); + tegra_gpio_enable(reset_gpio); + + gpio_direction_output(reset_gpio, 0); + msleep(5); + gpio_direction_output(reset_gpio, 1); +} + +static struct tegra_usb_phy_platform_ops ulpi_link_plat_ops = { + .open = ulpi_link_platform_open, +}; + +static struct tegra_usb_platform_data tegra_ehci2_ulpi_link_pdata = { + .port_otg = false, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_ULPI_LINK, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = false, + .power_off_on_suspend = true, }, - [1] = { - .phy_config = &ulpi_phy_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI, - .default_enable = true, + .u_cfg.ulpi = { + .shadow_clk_delay = 10, + .clock_out_delay = 1, + .data_trimmer = 4, + .stpdirnxt_trimmer = 4, + .dir_trimmer = 4, + .clk = "cdev2", }, - [2] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .hotplug = 1, - .default_enable = true, + .ops = &ulpi_link_plat_ops, +}; + +static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = { + .port_otg = false, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = TEGRA_GPIO_PD3, + .vbus_reg = NULL, + .hot_plug = true, + .remote_wakeup_supported = false, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 9, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, }, }; -static struct tegra_otg_platform_data tegra_otg_pdata = { +static struct tegra_usb_otg_data tegra_otg_pdata = { .ehci_device = &tegra_ehci1_device, - .ehci_pdata = &tegra_ehci_pdata[0], + .ehci_pdata = &tegra_ehci1_utmi_pdata, }; -static int __init ventana_gps_init(void) -{ - struct clk *clk32 = clk_get_sys(NULL, "blink"); - if (!IS_ERR(clk32)) { - clk_set_rate(clk32,clk32->parent->rate); - clk_enable(clk32); - } - - tegra_gpio_enable(TEGRA_GPIO_PZ3); - return 0; -} - static void ventana_usb_init(void) { - tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata)); /* OTG should be the first to be registered */ tegra_otg_device.dev.platform_data = &tegra_otg_pdata; platform_device_register(&tegra_otg_device); + tegra_udc_device.dev.platform_data = &tegra_udc_pdata; platform_device_register(&tegra_udc_device); + + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_ulpi_link_pdata; platform_device_register(&tegra_ehci2_device); - tegra_ehci3_device.dev.platform_data=&tegra_ehci_pdata[2]; + tegra_ehci3_device.dev.platform_data = &tegra_ehci3_utmi_pdata; platform_device_register(&tegra_ehci3_device); } @@ -576,8 +607,6 @@ static void __init tegra_ventana_init(void) ventana_pinmux_init(); ventana_i2c_init(); ventana_uart_init(); - tegra_ehci2_device.dev.platform_data - = &ventana_ehci2_ulpi_platform_data; platform_add_devices(ventana_devices, ARRAY_SIZE(ventana_devices)); tegra_ram_console_debug_init(); ventana_sdhci_init(); diff --git a/arch/arm/mach-tegra/board-whistler-baseband.c b/arch/arm/mach-tegra/board-whistler-baseband.c index 143d14a8721d..eb50fb2f8237 100644 --- a/arch/arm/mach-tegra/board-whistler-baseband.c +++ b/arch/arm/mach-tegra/board-whistler-baseband.c @@ -24,10 +24,9 @@ #include "board.h" #include "board-whistler-baseband.h" -static int baseband_phy_on(void); -static int baseband_phy_off(void); -static void baseband_phy_restore_start(void); -static void baseband_phy_restore_end(void); +static void baseband_phy_init(void); +static void baseband_phy_on(void); +static void baseband_phy_off(void); static struct wake_lock mdm_wake_lock; @@ -57,30 +56,38 @@ static __initdata struct tegra_pingroup_config whistler_null_ulpi_pinmux[] = { TEGRA_TRI_NORMAL}, }; -static struct tegra_ulpi_trimmer e1219_trimmer = { 10, 1, 1, 1 }; - -static struct tegra_ulpi_config ehci2_null_ulpi_phy_config = { - .trimmer = &e1219_trimmer, - .post_phy_on = baseband_phy_on, +static struct tegra_usb_phy_platform_ops ulpi_null_plat_ops = { + .init = baseband_phy_init, .pre_phy_off = baseband_phy_off, - .phy_restore_start = baseband_phy_restore_start, - .phy_restore_end = baseband_phy_restore_end, - .phy_restore_gpio = MDM2AP_ACK, - .ulpi_dir_gpio = ULPI_DIR, - .ulpi_d0_gpio = ULPI_D0, - .ulpi_d1_gpio = ULPI_D1, + .post_phy_on = baseband_phy_on, }; -static struct tegra_ehci_platform_data ehci2_null_ulpi_platform_data = { - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 0, - .phy_config = &ehci2_null_ulpi_phy_config, - .phy_type = TEGRA_USB_PHY_TYPE_NULL_ULPI, +static struct tegra_usb_platform_data tegra_ehci2_ulpi_null_pdata = { + .port_otg = false, + .has_hostpc = true, + .phy_intf = TEGRA_USB_PHY_INTF_ULPI_NULL, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = false, + .power_off_on_suspend = false, + }, + .u_cfg.ulpi = { + .shadow_clk_delay = 10, + .clock_out_delay = 1, + .data_trimmer = 1, + .stpdirnxt_trimmer = 1, + .dir_trimmer = 1, + .clk = NULL, + }, + .ops = &ulpi_null_plat_ops, }; static int __init tegra_null_ulpi_init(void) { - tegra_ehci2_device.dev.platform_data = &ehci2_null_ulpi_platform_data; + tegra_ehci2_device.dev.platform_data = &tegra_ehci2_ulpi_null_pdata; platform_device_register(&tegra_ehci2_device); return 0; } @@ -98,7 +105,7 @@ static irqreturn_t mdm_start_thread(int irq, void *data) return IRQ_HANDLED; } -static int baseband_phy_on(void) +static void baseband_phy_init(void) { static bool phy_init; @@ -108,22 +115,15 @@ static int baseband_phy_on(void) phy_init = true; } pr_info("%s\n", __func__); - return 0; -} - -static int baseband_phy_off(void) -{ - pr_info("%s\n", __func__); - return 0; } -static void baseband_phy_restore_start(void) +static void baseband_phy_off(void) { /* set AP2MDM_ACK2 high */ gpio_set_value(AP2MDM_ACK2, 1); } -static void baseband_phy_restore_end(void) +static void baseband_phy_on (void) { /* set AP2MDM_ACK2 low */ gpio_set_value(AP2MDM_ACK2, 0); diff --git a/arch/arm/mach-tegra/board-whistler-sdhci.c b/arch/arm/mach-tegra/board-whistler-sdhci.c index d98b1d53a52e..2d2a9c8c01f8 100644 --- a/arch/arm/mach-tegra/board-whistler-sdhci.c +++ b/arch/arm/mach-tegra/board-whistler-sdhci.c @@ -2,7 +2,7 @@ * arch/arm/mach-tegra/board-whistler-sdhci.c * * Copyright (C) 2010 Google, Inc. - * Copyright (C) 2011 NVIDIA Corporation. + * Copyright (C) 2011-2012 NVIDIA Corporation. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -256,8 +256,6 @@ static int __init whistler_wifi_init(void) } int __init whistler_sdhci_init(void) { - int ret; - tegra_gpio_enable(WHISTLER_EXT_SDCARD_DETECT); platform_device_register(&tegra_sdhci_device3); diff --git a/arch/arm/mach-tegra/board-whistler.c b/arch/arm/mach-tegra/board-whistler.c index ede0d0b11104..874ef18900e7 100644 --- a/arch/arm/mach-tegra/board-whistler.c +++ b/arch/arm/mach-tegra/board-whistler.c @@ -1,7 +1,7 @@ /* * arch/arm/mach-tegra/board-whistler.c * - * Copyright (c) 2010 - 2011, NVIDIA Corporation. + * Copyright (c) 2010-2012 NVIDIA Corporation. * * 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 @@ -222,32 +222,6 @@ static void __init whistler_setup_bluesleep(void) return; } -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - -static struct tegra_ulpi_config ulpi_phy_config = { - .reset_gpio = TEGRA_GPIO_PG2, - .clk = "cdev2", -}; - static __initdata struct tegra_clk_init_table whistler_clk_init_table[] = { /* name parent rate enabled */ { "pwm", "clk_32k", 32768, false}, @@ -455,61 +429,71 @@ static int __init whistler_scroll_init(void) return 0; } -static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { - [0] = { - .instance = 0, - .vbus_irq = MAX8907C_INT_BASE + MAX8907C_IRQ_VCHG_DC_R, - .vbus_gpio = USB1_VBUS_GPIO, - }, - [1] = { - .instance = 1, - .vbus_gpio = -1, +static int __init whistler_gps_init(void) +{ + tegra_gpio_enable(TEGRA_GPIO_PU4); + return 0; +} + +static struct tegra_usb_platform_data tegra_udc_pdata = { + .port_otg = true, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_DEVICE, + .u_data.dev = { + .vbus_pmu_irq = 0, + .vbus_gpio = -1, + .charging_supported = false, + .remote_wakeup_supported = false, }, - [2] = { - .instance = 2, - .vbus_gpio = -1, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, }, }; -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = false, - }, - [1] = { - .phy_config = &ulpi_phy_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = false, - }, - [2] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - .default_enable = false, +static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { + .port_otg = true, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = TEGRA_GPIO_PN6, + .vbus_reg = NULL, + .hot_plug = true, + .remote_wakeup_supported = false, + .power_off_on_suspend = true, + }, + .u_cfg.utmi = { + .hssync_start_delay = 9, + .elastic_limit = 16, + .idle_wait_delay = 17, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, }, }; -static struct tegra_otg_platform_data tegra_otg_pdata = { +static struct tegra_usb_otg_data tegra_otg_pdata = { .ehci_device = &tegra_ehci1_device, - .ehci_pdata = &tegra_ehci_pdata[0], + .ehci_pdata = &tegra_ehci1_utmi_pdata, }; -static int __init whistler_gps_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PU4); - return 0; -} - +#define SERIAL_NUMBER_LENGTH 20 static void whistler_usb_init(void) { - tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata)); - tegra_otg_device.dev.platform_data = &tegra_otg_pdata; platform_device_register(&tegra_otg_device); + tegra_udc_device.dev.platform_data = &tegra_udc_pdata; } static void __init tegra_whistler_init(void) diff --git a/arch/arm/mach-tegra/common-t2.c b/arch/arm/mach-tegra/common-t2.c index 6f9b177892ce..f90dfce6a690 100644 --- a/arch/arm/mach-tegra/common-t2.c +++ b/arch/arm/mach-tegra/common-t2.c @@ -3,7 +3,7 @@ * * Tegra 2 SoC-specific initialization (memory controller, etc.) * - * Copyright (c) 2009-2011, NVIDIA Corporation. + * Copyright (c) 2009-2012 NVIDIA Corporation. * * 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 @@ -177,16 +177,18 @@ out: return IRQ_HANDLED; } -void __init tegra_mc_init(void) +static int __init tegra_mc_init(void) { if (request_irq(INT_MC_GENERAL, tegra_mc_error_isr, 0, "mc_status", NULL)) { pr_err("%s: unable to register MC error interrupt\n", __func__); + return -EINVAL; } else { void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); u32 reg = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE | MC_INT_DECERR_EMEM_OTHERS; writel(reg, mc + MC_INT_MASK); } + return 0; } arch_initcall(tegra_mc_init); diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 78bd77dfb7d2..2986f1cf61ac 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -974,12 +974,14 @@ void cpufreq_store_default_gov(void) int cpufreq_change_gov(char *target_gov) { - unsigned int cpu = 0; + unsigned int cpu = 0, ret = -EINVAL; #ifndef CONFIG_TEGRA_AUTO_HOTPLUG for_each_online_cpu(cpu) #endif - return cpufreq_set_gov(target_gov, cpu); + ret = cpufreq_set_gov(target_gov, cpu); + + return ret; } int cpufreq_restore_default_gov(void) diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c index 2a4f94c4e22d..377772ff4291 100644 --- a/arch/arm/mach-tegra/devices.c +++ b/arch/arm/mach-tegra/devices.c @@ -584,28 +584,6 @@ static struct resource tegra_usb3_resources[] = { }, }; -static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { - /* All existing boards use GPIO PV0 for phy reset */ - .reset_gpio = TEGRA_GPIO_PV0, - .clk = "cdev2", -}; - -static struct tegra_ehci_platform_data tegra_ehci1_pdata = { - .operating_mode = TEGRA_USB_OTG, - .power_down_on_bus_suspend = 1, -}; - -static struct tegra_ehci_platform_data tegra_ehci2_pdata = { - .phy_config = &tegra_ehci2_ulpi_phy_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, -}; - -static struct tegra_ehci_platform_data tegra_ehci3_pdata = { - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, -}; - static u64 tegra_ehci_dmamask = DMA_BIT_MASK(32); struct platform_device tegra_ehci1_device = { @@ -614,7 +592,6 @@ struct platform_device tegra_ehci1_device = { .dev = { .dma_mask = &tegra_ehci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &tegra_ehci1_pdata, }, .resource = tegra_usb1_resources, .num_resources = ARRAY_SIZE(tegra_usb1_resources), @@ -626,7 +603,6 @@ struct platform_device tegra_ehci2_device = { .dev = { .dma_mask = &tegra_ehci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &tegra_ehci2_pdata, }, .resource = tegra_usb2_resources, .num_resources = ARRAY_SIZE(tegra_usb2_resources), @@ -638,7 +614,6 @@ struct platform_device tegra_ehci3_device = { .dev = { .dma_mask = &tegra_ehci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &tegra_ehci3_pdata, }, .resource = tegra_usb3_resources, .num_resources = ARRAY_SIZE(tegra_usb3_resources), @@ -1226,18 +1201,12 @@ static struct resource tegra_udc_resources[] = { static u64 tegra_udc_dmamask = DMA_BIT_MASK(32); -static struct fsl_usb2_platform_data tegra_udc_pdata = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, -}; - struct platform_device tegra_udc_device = { .name = "tegra-udc", .id = 0, .dev = { .dma_mask = &tegra_udc_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &tegra_udc_pdata, }, .resource = tegra_udc_resources, .num_resources = ARRAY_SIZE(tegra_udc_resources), diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h index ab3d4e920f46..71f1be769507 100644 --- a/arch/arm/mach-tegra/include/mach/dc.h +++ b/arch/arm/mach-tegra/include/mach/dc.h @@ -503,6 +503,7 @@ struct tegra_dc_platform_data { #define TEGRA_DC_FLAG_ENABLED (1 << 0) +int tegra_dc_get_stride(struct tegra_dc *dc, unsigned win); struct tegra_dc *tegra_dc_get_dc(unsigned idx); struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win); bool tegra_dc_get_connected(struct tegra_dc *); diff --git a/arch/arm/mach-tegra/include/mach/latency_allowance.h b/arch/arm/mach-tegra/include/mach/latency_allowance.h index f0d27f0b8ba9..8644075a88b3 100644 --- a/arch/arm/mach-tegra/include/mach/latency_allowance.h +++ b/arch/arm/mach-tegra/include/mach/latency_allowance.h @@ -1,7 +1,7 @@ /* * arch/arm/mach-tegra/include/mach/latency_allowance.h * - * Copyright (C) 2011, NVIDIA Corporation. + * Copyright (C) 2011-2012 NVIDIA Corporation. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -104,7 +104,7 @@ static inline int tegra_enable_latency_scaling(enum tegra_la_id id, static inline void tegra_disable_latency_scaling(enum tegra_la_id id) { - return 0; + return; } #else int tegra_set_latency_allowance(enum tegra_la_id id, diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h index 3ad1128e2026..c721642c4417 100644 --- a/arch/arm/mach-tegra/include/mach/usb_phy.h +++ b/arch/arm/mach-tegra/include/mach/usb_phy.h @@ -18,150 +18,120 @@ #ifndef __MACH_USB_PHY_H #define __MACH_USB_PHY_H -#include <linux/clk.h> -#include <linux/regulator/consumer.h> -#include <linux/usb/otg.h> -#include <linux/platform_data/tegra_usb.h> - -struct tegra_utmip_config { - u8 hssync_start_delay; - u8 elastic_limit; - u8 idle_wait_delay; - u8 term_range_adj; - u8 xcvr_setup; - signed char xcvr_setup_offset; - u8 xcvr_use_fuses; - u8 xcvr_lsfslew; - u8 xcvr_lsrslew; -}; - -struct tegra_ulpi_trimmer { - u8 shadow_clk_delay; /* 0 ~ 31 */ - u8 clock_out_delay; /* 0 ~ 31 */ - u8 data_trimmer; /* 0 ~ 7 */ - u8 stpdirnxt_trimmer; /* 0 ~ 7 */ -}; - -struct tegra_ulpi_config { - int enable_gpio; - int reset_gpio; - const char *clk; - const struct tegra_ulpi_trimmer *trimmer; - int (*pre_phy_on)(void); - int (*post_phy_on)(void); - int (*pre_phy_off)(void); - int (*post_phy_off)(void); - void (*phy_restore_start)(void); - void (*phy_restore_end)(void); - int phy_restore_gpio; /* null phy restore ack from device */ - int ulpi_dir_gpio; /* ulpi dir */ - int ulpi_d0_gpio; /* usb linestate[0] */ - int ulpi_d1_gpio; /* usb linestate[1] */ -}; - -struct tegra_uhsic_config { - int enable_gpio; - int reset_gpio; - u8 sync_start_delay; - u8 idle_wait_delay; - u8 term_range_adj; - u8 elastic_underrun_limit; - u8 elastic_overrun_limit; - int (*postsuspend)(void); - int (*preresume)(void); - int (*usb_phy_ready)(void); - int (*post_phy_off)(void); -}; - -enum tegra_usb_phy_port_speed { - TEGRA_USB_PHY_PORT_SPEED_FULL = 0, - TEGRA_USB_PHY_PORT_SPEED_LOW, - TEGRA_USB_PHY_PORT_SPEED_HIGH, -}; - -enum tegra_usb_phy_mode { - TEGRA_USB_PHY_MODE_DEVICE, - TEGRA_USB_PHY_MODE_HOST, -}; - -struct usb_phy_plat_data { - int instance; - int vbus_irq; - int vbus_gpio; - char * vbus_reg_supply; -}; - -struct tegra_xtal_freq; - -struct tegra_usb_phy { - int instance; - const struct tegra_xtal_freq *freq; - void __iomem *regs; - void __iomem *pad_regs; - struct clk *clk; - struct clk *pll_u; - struct clk *pad_clk; - enum tegra_usb_phy_mode mode; - void *config; - struct regulator *reg_vdd; - struct regulator *reg_vbus; - enum tegra_usb_phy_type usb_phy_type; - bool regulator_on; - struct otg_transceiver *ulpi; - int initialized; - bool power_on; - bool remote_wakeup; - int hotplug; - unsigned int xcvr_setup_value; -}; - -typedef int (*tegra_phy_fp)(struct tegra_usb_phy *phy, bool is_dpd); -typedef void (*tegra_phy_restore_start_fp)(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed); -typedef void (*tegra_phy_restore_end_fp)(struct tegra_usb_phy *phy); - -struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, - void *config, enum tegra_usb_phy_mode phy_mode, - enum tegra_usb_phy_type usb_phy_type); - -int tegra_usb_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd); - -void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy); - -void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy); - -void tegra_usb_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd); - -void tegra_usb_phy_postsuspend(struct tegra_usb_phy *phy, bool is_dpd); - -void tegra_usb_phy_preresume(struct tegra_usb_phy *phy, bool is_dpd); - -void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd); - -void tegra_ehci_pre_reset(struct tegra_usb_phy *phy, bool is_dpd); - -void tegra_ehci_post_reset(struct tegra_usb_phy *phy, bool is_dpd); - -void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed); - -void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy); +/** + * Tegra USB phy opaque handle + */ +struct tegra_usb_phy; + +/** + * Opens the usb phy associated to the USB platform device + * tegra usb phy open must be called before accessing any phy APIs + */ +struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev); +/** + * Closes the phy controller and its resources + */ void tegra_usb_phy_close(struct tegra_usb_phy *phy); -int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy); +/** + * Handles interrupts specific to the phy interface + * Note: udc or ehci driver will handle the controller interrupts + */ +int tegra_usb_phy_irq(struct tegra_usb_phy *phy); + +/** + * Initializes the phy specific functions after phy is power on + */ +int tegra_usb_phy_init(struct tegra_usb_phy *phy); + +/** + * Handles phy interface specific functionality after driver reset + */ +int tegra_usb_phy_reset(struct tegra_usb_phy *phy); + +/** + * Handles phy interface specific functionality before driver suspend + * Also, handles platform specific pre suspend functions + */ +int tegra_usb_phy_pre_suspend(struct tegra_usb_phy *phy); + +/** + * Handles phy interface specific suspend functionality + */ +int tegra_usb_phy_suspend(struct tegra_usb_phy *phy); + +/** + * Handles phy interface specific functionality after driver suspend + */ +int tegra_usb_phy_post_suspend(struct tegra_usb_phy *phy); + +/** + * Handles phy interface specific functionality before driver resume + * Also, handles platform specific pre resume functions + */ +int tegra_usb_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup); + +/** + * Handles phy interface specific resume functionality + */ +int tegra_usb_phy_resume(struct tegra_usb_phy *phy); +/** + * Handles phy interface specific functionality after driver resume + */ +int tegra_usb_phy_post_resume(struct tegra_usb_phy *phy); + +/** + * Handles phy interface specific functionality during port power on + */ +int tegra_usb_phy_port_power(struct tegra_usb_phy *phy); + +/** + * Handles phy interface specific functionality during bus reset + */ int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy); -int tegra_usb_phy_bus_idle(struct tegra_usb_phy *phy); +/** + * Handles phy interface specific functionality for turning off the phy to + * put the phy in low power mode + */ +int tegra_usb_phy_power_off(struct tegra_usb_phy *phy); -bool tegra_usb_phy_is_device_connected(struct tegra_usb_phy *phy); +/** + * Handles phy interface specific functionality for turning on the phy to + * bring phy out of low power mode + */ +int tegra_usb_phy_power_on(struct tegra_usb_phy *phy); -bool tegra_usb_phy_charger_detect(struct tegra_usb_phy *phy); +/** + * Indicates whether phy registers are accessible or not + * if phy is powered off then returns false else true + */ +bool tegra_usb_phy_hw_accessible(struct tegra_usb_phy *phy); + +/** + * Indicates whether compliance charger is connected or not + * if compliance charger is detected then returns true else false + */ +bool tegra_usb_phy_charger_detected(struct tegra_usb_phy *phy); + +/** + * Indicates whether phy resumed due to the remote wake event or not + * returns true if remote wake is detected. + */ +bool tegra_usb_phy_remote_wakeup(struct tegra_usb_phy *phy); + +/** + * Indicates controller has HOST PC register set or not + */ +bool tegra_usb_phy_has_hostpc(struct tegra_usb_phy *phy); -int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size); +/** + * Indicates controller port supports OTG or not + */ +bool tegra_usb_phy_otg_supported(struct tegra_usb_phy *phy); -bool tegra_usb_phy_is_remotewake_detected(struct tegra_usb_phy *phy); void tegra_usb_phy_memory_prefetch_on(struct tegra_usb_phy *phy); diff --git a/arch/arm/mach-tegra/iovmm-gart.c b/arch/arm/mach-tegra/iovmm-gart.c index ad1ce3a7afc3..130901cb4883 100644 --- a/arch/arm/mach-tegra/iovmm-gart.c +++ b/arch/arm/mach-tegra/iovmm-gart.c @@ -4,7 +4,7 @@ * Tegra I/O VMM implementation for GART devices in Tegra and Tegra 2 series * systems-on-a-chip. * - * Copyright (c) 2010-2012, NVIDIA Corporation. + * Copyright (c) 2010-2012 NVIDIA Corporation. * * 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 @@ -73,7 +73,7 @@ static int gart_map(struct tegra_iovmm_domain *, struct tegra_iovmm_area *); static void gart_unmap(struct tegra_iovmm_domain *, struct tegra_iovmm_area *, bool); static void gart_map_pfn(struct tegra_iovmm_domain *, - struct tegra_iovmm_area *, tegra_iovmm_addr_t, unsigned long); + struct tegra_iovmm_area *, unsigned long, unsigned long); static struct tegra_iovmm_domain *gart_alloc_domain( struct tegra_iovmm_device *, struct tegra_iovmm_client *); @@ -330,7 +330,7 @@ static void gart_unmap(struct tegra_iovmm_domain *domain, } static void gart_map_pfn(struct tegra_iovmm_domain *domain, - struct tegra_iovmm_area *iovma, tegra_iovmm_addr_t offs, + struct tegra_iovmm_area *iovma, unsigned long offs, unsigned long pfn) { struct gart_device *gart = diff --git a/arch/arm/mach-tegra/p852/board-p852.c b/arch/arm/mach-tegra/p852/board-p852.c index 21b867e15177..ffdf5d3e4bae 100644 --- a/arch/arm/mach-tegra/p852/board-p852.c +++ b/arch/arm/mach-tegra/p852/board-p852.c @@ -288,49 +288,6 @@ static struct platform_device debug_uart = { }, }; -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - -static struct tegra_ulpi_config ulpi_usb2_config = { - .reset_gpio = TEGRA_GPIO_PI5, -}; - -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 0, - }, - [1] = { - .phy_config = &ulpi_usb2_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 0, - .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI, - }, - [2] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 0, - }, -}; static void p852_usb_gpio_config(void) { @@ -529,6 +486,97 @@ static void __init p852_register_spidev(void) #define p852_register_spidev() do {} while (0) #endif +/* + FixMe: Copied below GPIO value from Ventana board. + Plz correct it accordingly for embedded board usage +*/ +#define TEGRA_GPIO_PV1 169 + +static void ulpi_link_platform_open(void) +{ + int reset_gpio = TEGRA_GPIO_PV1; + + gpio_request(reset_gpio, "ulpi_phy_reset"); + gpio_direction_output(reset_gpio, 0); + tegra_gpio_enable(reset_gpio); + + gpio_direction_output(reset_gpio, 0); + msleep(5); + gpio_direction_output(reset_gpio, 1); +} + +static struct tegra_usb_phy_platform_ops ulpi_link_plat_ops = { + .open = ulpi_link_platform_open, +}; + +static struct tegra_usb_platform_data tegra_ehci_ulpi_link_pdata = { + .port_otg = false, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_ULPI_LINK, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = false, + .remote_wakeup_supported = false, + .power_off_on_suspend = false, + }, + .u_cfg.ulpi = { + .shadow_clk_delay = 10, + .clock_out_delay = 1, + .data_trimmer = 4, + .stpdirnxt_trimmer = 4, + .dir_trimmer = 4, + .clk = "cdev2", + }, + .ops = &ulpi_link_plat_ops, +}; + +static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { + .port_otg = false, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = true, + .remote_wakeup_supported = true, + .power_off_on_suspend = false, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + }, +}; + +static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = { + .port_otg = false, + .has_hostpc = false, + .phy_intf = TEGRA_USB_PHY_INTF_UTMI, + .op_mode = TEGRA_USB_OPMODE_HOST, + .u_data.host = { + .vbus_gpio = -1, + .vbus_reg = NULL, + .hot_plug = true, + .remote_wakeup_supported = true, + .power_off_on_suspend = false, + }, + .u_cfg.utmi = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + }, +}; static void __init p852_usb_init(void) { @@ -541,16 +589,16 @@ static void __init p852_usb_init(void) else */ { - tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0]; + tegra_ehci1_device.dev.platform_data = &tegra_ehci1_utmi_pdata; platform_device_register(&tegra_ehci1_device); } if (!(p852_sku_peripherals & P852_SKU_ULPI_DISABLE)) { - tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; + tegra_ehci2_device.dev.platform_data = &tegra_ehci_ulpi_link_pdata; platform_device_register(&tegra_ehci2_device); } - tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2]; + tegra_ehci3_device.dev.platform_data = &tegra_ehci3_utmi_pdata; platform_device_register(&tegra_ehci3_device); } diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index 1c4ee1b1f5ce..80a9a121f193 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -294,6 +294,9 @@ #define PCIE_CONF_REG(r) \ (((r) & ~0x3) | (((r) < 256) ? PCIE_CFG_OFF : PCIE_EXT_CFG_OFF)) +#define PCIE_CTRL_REGS 7 +#define COMBINE_PCIE_PCIX_SPACE 2 + struct tegra_pcie_port { int index; u8 root_bus_nr; @@ -349,6 +352,12 @@ static struct resource pcie_prefetch_mem_space; static bool is_pcie_noirq_op = false; /* used to backup config space registers of all pcie devices */ static u32 *pbackup_config_space = NULL; +static u16 *pbackup_pcie_cap_space = NULL; +static u16 *pbackup_pcix_cap_space = NULL; +/* use same save state and position variables to store pcie */ +/* and pcix capability offsets at even & odd index respectively */ +static struct pci_cap_saved_state **pcie_save_state; +static int *pos; void __iomem *tegra_pcie_io_base; EXPORT_SYMBOL(tegra_pcie_io_base); @@ -986,7 +995,7 @@ static void tegra_pcie_clocks_put(void) clk_put(tegra_pcie.pcie_xclk); } -static int __init tegra_pcie_get_resources(void) +static int tegra_pcie_get_resources(void) { struct resource *res_mmio = 0; int err; @@ -1112,11 +1121,22 @@ retry: return false; } -static void __init tegra_pcie_add_port(int index, u32 offset, u32 reset_reg) +static void tegra_enable_clock_clamp(int index) { - struct tegra_pcie_port *pp; unsigned int data; + /* Power mangagement settings */ + /* Enable clock clamping by default */ + data = rp_readl(NV_PCIE2_RP_PRIV_MISC, index); + data |= (PCIE2_RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE) | + (PCIE2_RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE); + rp_writel(data, NV_PCIE2_RP_PRIV_MISC, index); +} + +static void tegra_pcie_add_port(int index, u32 offset, u32 reset_reg) +{ + struct tegra_pcie_port *pp; + pp = tegra_pcie.port + tegra_pcie.num_ports; pp->index = -1; @@ -1128,13 +1148,7 @@ static void __init tegra_pcie_add_port(int index, u32 offset, u32 reset_reg) printk(KERN_INFO "PCIE: port %d: link down, ignoring\n", index); return; } - /* Power mangagement settings */ - /* Enable clock clamping by default */ - data = rp_readl(NV_PCIE2_RP_PRIV_MISC, index); - data |= (PCIE2_RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE) | - (PCIE2_RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE); - rp_writel(data, NV_PCIE2_RP_PRIV_MISC, index); - + tegra_enable_clock_clamp(index); tegra_pcie.num_ports++; pp->index = index; pp->root_bus_nr = -1; @@ -1178,9 +1192,47 @@ static int tegra_pcie_init(void) return err; } +static int tegra_pcie_allocate_config_states(int ndev, int size) +{ + /* backup config space registers of all devices since it gets reset in + save state call from suspend noirq due to disabling of read in it */ + pbackup_config_space = kzalloc(ndev*size*sizeof(u32), GFP_KERNEL); + if (!pbackup_config_space) + return -ENODEV; + pbackup_pcie_cap_space = kzalloc(ndev*PCIE_CTRL_REGS*sizeof(u16), GFP_KERNEL); + if (!pbackup_pcie_cap_space) + return -ENODEV; + pbackup_pcix_cap_space = kzalloc(ndev*sizeof(u16), GFP_KERNEL); + if (!pbackup_pcix_cap_space) + return -ENODEV; + pcie_save_state = kzalloc(COMBINE_PCIE_PCIX_SPACE*ndev* + sizeof(struct pci_cap_saved_state*), GFP_KERNEL); + if (!pbackup_pcix_cap_space) + return -ENODEV; + pos = kzalloc(COMBINE_PCIE_PCIX_SPACE*ndev*sizeof(int), GFP_KERNEL); + if (!pos) + return -ENODEV; + + return 0; +} + +static void tegra_pcie_deallocate_config_states(void) +{ + if (pbackup_config_space) + kzfree(pbackup_config_space); + if (pbackup_pcie_cap_space) + kzfree(pbackup_pcie_cap_space); + if (pbackup_pcix_cap_space) + kzfree(pbackup_pcix_cap_space); + if (pcie_save_state) + kzfree(pcie_save_state); + if (pos) + kzfree(pos); +} + static int tegra_pci_probe(struct platform_device *pdev) { - int ret; + int ret, size = 0, ndev = 0; struct pci_dev *dev = NULL; tegra_pcie.plat_data = pdev->dev.platform_data; @@ -1194,39 +1246,91 @@ static int tegra_pci_probe(struct platform_device *pdev) /* disable async PM of pci devices to ensure right order */ /* suspend/resume calls of tegra and bus driver */ - for_each_pci_dev(dev) + for_each_pci_dev(dev){ device_disable_async_suspend(&dev->dev); + size = sizeof(dev->saved_config_space) / sizeof(u32); + ndev++; + } + tegra_pcie_allocate_config_states(ndev, size); return ret; } +static int tegra_pcie_save_state(struct pci_dev *pdev, int ndev) +{ + int size; + + /*save pcie control registers */ + pos[ndev] = pci_pcie_cap(pdev); + if (pos[ndev]){ + pcie_save_state[ndev] = pci_find_saved_cap(pdev, PCI_CAP_ID_EXP); + if (!pcie_save_state[ndev]) { + dev_err(&pdev->dev, "buffer not found in %s\n", __func__); + return -ENOMEM; + } + memcpy(&pbackup_pcie_cap_space[PCIE_CTRL_REGS*(ndev/2)], + pcie_save_state[ndev]->cap.data, PCIE_CTRL_REGS*sizeof(u16)); + } + /* save pcix state */ + pos[ndev+1] = pci_find_capability(pdev, PCI_CAP_ID_PCIX); + if (pos[ndev+1] > 0){ + pcie_save_state[ndev+1] = pci_find_saved_cap(pdev, PCI_CAP_ID_PCIX); + if (!pcie_save_state[ndev+1]) { + dev_err(&pdev->dev, "buffer not found in %s\n", __func__); + return -ENOMEM; + } + memcpy(&pbackup_pcix_cap_space[ndev/2], + pcie_save_state[ndev+1]->cap.data, sizeof(u16)); + } + /* save config space registers */ + size = sizeof(pdev->saved_config_space) / sizeof(u32); + memcpy(&pbackup_config_space[size*ndev/2], + pdev->saved_config_space, size*sizeof(u32)); + + return 0; +} + +static void tegra_pcie_restore_state(struct pci_dev *pdev, int ndev) +{ + int size; + + /* restore pcie control registers */ + if (pcie_save_state[ndev] && (pos[ndev] > 0)) + memcpy(pcie_save_state[ndev]->cap.data, + &pbackup_pcie_cap_space[PCIE_CTRL_REGS*(ndev/2)], + PCIE_CTRL_REGS*sizeof(u16)); + + /* restore pcix state */ + if (pcie_save_state[ndev+1] && (pos[ndev+1] > 0)) + memcpy(pcie_save_state[ndev+1]->cap.data, + &pbackup_pcix_cap_space[ndev/2], sizeof(u16)); + + /* restore config space registers */ + size = sizeof(pdev->saved_config_space) / sizeof(u32); + memcpy(pdev->saved_config_space, + &pbackup_config_space[size*ndev/2], size*sizeof(u32)); +} + static int tegra_pci_suspend(struct device *dev) { - int ret = 0; + int ret = 0, ndev = 0; struct pci_dev *pdev = NULL; - int i, size, ndev = 0; if (!tegra_pcie.num_ports) - return ret; + return ret; for_each_pci_dev(pdev) { /* save state of pcie devices before powering off regulators */ pci_save_state(pdev); - size = sizeof(pdev->saved_config_space) / sizeof(u32); - ndev++; + if (!pdev->subordinate) + pci_prepare_to_sleep(pdev); } - /* backup config space registers of all devices since it gets reset in - save state call from suspend noirq due to disabling of read in it */ - pbackup_config_space = kzalloc(ndev * size* sizeof(u32), GFP_KERNEL); - if (!pbackup_config_space) - return -ENODEV; - ndev = 0; for_each_pci_dev(pdev) { - for (i = 0;i < size;i++) { - memcpy(&pbackup_config_space[i + size*ndev], - &pdev->saved_config_space[i], sizeof(u32)); - } + /* save control and config space registers*/ + ret = tegra_pcie_save_state(pdev, ndev*2); + if (ret < 0) + return ret; ndev++; } @@ -1239,50 +1343,45 @@ static int tegra_pci_resume_noirq(struct device *dev) { struct pci_dev *pdev = NULL; - for_each_pci_dev(pdev) { - /* set this flag to avoid restore state in resume noirq */ + /* set this flag to avoid restore state in resume noirq */ + for_each_pci_dev(pdev) pdev->state_saved = 0; - } + return 0; } static int tegra_pci_resume(struct device *dev) { - int ret = 0; - int i, size, ndev = 0; + int ret = 0, ndev = 0; struct pci_dev *pdev = NULL; + int port; if (!tegra_pcie.num_ports) - return ret; + return ret; ret = tegra_pcie_power_on(); + /* enable read/write registers after powering on */ + is_pcie_noirq_op = false; tegra_pcie_enable_controller(); tegra_pcie_setup_translations(); - /* enable read/write registers after powering on */ - is_pcie_noirq_op = false; + for (port = 0; port < MAX_PCIE_SUPPORTED_PORTS; port++) + if (tegra_pcie.plat_data->port_status[port]) + tegra_enable_clock_clamp(port); for_each_pci_dev(pdev) { - /* do fixup here for all dev's since not done in resume noirq */ - pci_fixup_device(pci_fixup_resume_early, pdev); - + /* restore control and config space registers*/ + tegra_pcie_restore_state(pdev, ndev*2); /* set this flag to force restore state in resume */ pdev->state_saved = 1; - - /* restore config space registers from backup buffer */ - size = sizeof(pdev->saved_config_space) / sizeof(u32); - for (i = 0;i < size;i++) { - memcpy(&pdev->saved_config_space[i], - &pbackup_config_space[i + size*ndev], sizeof(u32)); - } ndev++; } - kzfree(pbackup_config_space); return ret; } static int tegra_pci_remove(struct platform_device *pdev) { + tegra_pcie_deallocate_config_states(); return 0; } #ifdef CONFIG_PM diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index af30cf2ea18c..fa88b11552d9 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -779,8 +779,9 @@ static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate) if (sel->input_rate == 0) { unsigned long cfreq; - BUG_ON(c->flags & PLLU); struct clk_pll_freq_table cfg; + + BUG_ON(c->flags & PLLU); sel = &cfg; switch (input_rate) { @@ -2771,7 +2772,7 @@ unsigned long tegra_emc_to_cpu_ratio(unsigned long cpu_rate) #ifdef CONFIG_PM_SLEEP static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM + - PERIPH_CLK_SOURCE_NUM + 22]; + PERIPH_CLK_SOURCE_NUM + 24]; static int tegra_clk_suspend(void) { @@ -2779,6 +2780,8 @@ static int tegra_clk_suspend(void) u32 *ctx = clk_rst_suspend; *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK; + *ctx++ = clk_readl(tegra_pll_p_out1.reg); + *ctx++ = clk_readl(tegra_pll_p_out3.reg); *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE); *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c)); *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE); @@ -2831,11 +2834,26 @@ static void tegra_clk_resume(void) unsigned long off, i; const u32 *ctx = clk_rst_suspend; u32 val; + u32 pll_p_out12, pll_p_out34; + u32 pll_m_out1, pll_a_out0, pll_c_out1; val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK; val |= *ctx++; clk_writel(val, OSC_CTRL); + /* Since we are going to reset devices and switch clock sources in this + * function, plls and secondary dividers is required to be enabled. The + * actual value will be restored back later. Note that boot plls: pllm, + * pllp, and pllu are already configured and enabled. + */ + + val = PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE; + val |= val << 16; + pll_p_out12 = *ctx++; + clk_writel(pll_p_out12 | val, tegra_pll_p_out1.reg); + pll_p_out34 = *ctx++; + clk_writel(pll_p_out34 | val, tegra_pll_p_out3.reg); + clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE); clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c)); clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE); @@ -2848,9 +2866,13 @@ static void tegra_clk_resume(void) clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u)); udelay(1000); - clk_writel(*ctx++, tegra_pll_m_out1.reg); - clk_writel(*ctx++, tegra_pll_a_out0.reg); - clk_writel(*ctx++, tegra_pll_c_out1.reg); + val = PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE; + pll_m_out1 = *ctx++; + clk_writel(pll_m_out1 | val, tegra_pll_m_out1.reg); + pll_a_out0 = *ctx++; + clk_writel(pll_a_out0 | val, tegra_pll_a_out0.reg); + pll_c_out1 = *ctx++; + clk_writel(pll_c_out1 | val, tegra_pll_c_out1.reg); clk_writel(*ctx++, tegra_clk_cclk.reg); clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER); @@ -2887,6 +2909,13 @@ static void tegra_clk_resume(void) clk_writel(*ctx++, MISC_CLK_ENB); clk_writel(*ctx++, CLK_MASK_ARM); + + /* Restore back the actual pll and secondary divider values */ + clk_writel(pll_p_out12, tegra_pll_p_out1.reg); + clk_writel(pll_p_out34, tegra_pll_p_out3.reg); + clk_writel(pll_m_out1, tegra_pll_m_out1.reg); + clk_writel(pll_a_out0, tegra_pll_a_out0.reg); + clk_writel(pll_c_out1, tegra_pll_c_out1.reg); } #else diff --git a/arch/arm/mach-tegra/tegra2_mc.c b/arch/arm/mach-tegra/tegra2_mc.c index 6df9c232c02f..1b72af0735f6 100644 --- a/arch/arm/mach-tegra/tegra2_mc.c +++ b/arch/arm/mach-tegra/tegra2_mc.c @@ -896,8 +896,10 @@ static enum hrtimer_restart sample_timer_function(struct hrtimer *handle) #define REGISTER_SYSFS(_name, _val) \ tegra_mc_dram_##_name##_kobj = \ kobject_create_and_add(#_name, tegra_mc_dram_kobj); \ - sysfs_create_group(tegra_mc_dram_##_name##_kobj, \ - &tegra_mc_dram_##_name##_attr_group); + if (sysfs_create_group(tegra_mc_dram_##_name##_kobj, \ + &tegra_mc_dram_##_name##_attr_group)) \ + printk(KERN_ERR "\n sysfs_create_group failed at %s" \ + " line %d\n", __FILE__, __LINE__); static int tegra_mc_init(void) { diff --git a/arch/arm/mach-tegra/tegra2_usb_phy.c b/arch/arm/mach-tegra/tegra2_usb_phy.c new file mode 100644 index 000000000000..819721c49a29 --- /dev/null +++ b/arch/arm/mach-tegra/tegra2_usb_phy.c @@ -0,0 +1,1598 @@ +/* + * arch/arm/mach-tegra/tegra2_usb_phy.c + * + * Copyright (C) 2011 NVIDIA Corporation + * + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 <linux/resource.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/usb/otg.h> +#include <linux/usb/ulpi.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/regulator/consumer.h> +#include <linux/platform_data/tegra_usb.h> +#include <mach/iomap.h> +#include <mach/pinmux.h> +#include <asm/mach-types.h> +#include <mach/usb_phy.h> +#include "tegra_usb_phy.h" +#include "fuse.h" + + +#define USB_USBCMD 0x140 +#define USB_USBCMD_RS (1 << 0) +#define USB_USBCMD_RESET (1 << 1) + +#define USB_USBSTS 0x144 +#define USB_USBSTS_PCI (1 << 2) +#define USB_USBSTS_SRI (1 << 7) +#define USB_USBSTS_HCH (1 << 12) + +#define USB_ASYNCLISTADDR 0x158 + +#define USB_TXFILLTUNING 0x164 +#define USB_FIFO_TXFILL_THRES(x) (((x) & 0x1f) << 16) +#define USB_FIFO_TXFILL_MASK 0x1f0000 + +#define ULPI_VIEWPORT 0x170 +#define ULPI_WAKEUP (1 << 31) +#define ULPI_RUN (1 << 30) +#define ULPI_RD_WR (1 << 29) + +#define USB_PORTSC 0x184 +#define USB_PORTSC_PTS(x) (((x) & 0x3) << 30) +#define USB_PORTSC_PSPD(x) (((x) & 0x3) << 26) +#define USB_PORTSC_PHCD (1 << 23) +#define USB_PORTSC_WKOC (1 << 22) +#define USB_PORTSC_WKDS (1 << 21) +#define USB_PORTSC_WKCN (1 << 20) +#define USB_PORTSC_PTC(x) (((x) & 0xf) << 16) +#define USB_PORTSC_PP (1 << 12) +#define USB_PORTSC_LS(x) (((x) & 0x3) << 10) +#define USB_PORTSC_SUSP (1 << 7) +#define USB_PORTSC_OCC (1 << 5) +#define USB_PORTSC_PEC (1 << 3) +#define USB_PORTSC_PE (1 << 2) +#define USB_PORTSC_CSC (1 << 1) +#define USB_PORTSC_CCS (1 << 0) +#define USB_PORTSC_RWC_BITS (USB_PORTSC_CSC | USB_PORTSC_PEC | USB_PORTSC_OCC) +#define USB_PORTSC_PSPD_MASK 3 + +#define USB_USBMODE_REG_OFFSET 0x1a8 +#define USB_USBMODE_MASK (3 << 0) +#define USB_USBMODE_HOST (3 << 0) +#define USB_USBMODE_DEVICE (2 << 0) + +#define USB_SUSP_CTRL 0x400 +#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) +#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) +#define USB_SUSP_CLR (1 << 5) +#define USB_CLKEN (1 << 6) +#define USB_PHY_CLK_VALID (1 << 7) +#define USB_PHY_CLK_VALID_INT_ENB (1 << 9) +#define UTMIP_RESET (1 << 11) +#define UHSIC_RESET (1 << 11) +#define UTMIP_PHY_ENABLE (1 << 12) +#define UHSIC_PHY_ENABLE (1 << 12) +#define ULPI_PHY_ENABLE (1 << 13) +#define USB_SUSP_SET (1 << 14) +#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) +#define USB_PHY_CLK_VALID_INT_STS (1 << 8) + +#define USB_PHY_VBUS_WAKEUP_ID 0x408 +#define VDAT_DET_INT_EN (1 << 16) +#define VDAT_DET_CHG_DET (1 << 17) +#define VDAT_DET_STS (1 << 18) +#define USB_ID_STATUS (1 << 2) + +#define USB1_LEGACY_CTRL 0x410 +#define USB1_NO_LEGACY_MODE (1 << 0) +#define USB1_VBUS_SENSE_CTL_MASK (3 << 1) +#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1) +#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \ + (1 << 1) +#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1) +#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1) + +#define ULPIS2S_CTRL 0x418 +#define ULPIS2S_ENA (1 << 0) +#define ULPIS2S_SUPPORT_DISCONNECT (1 << 2) +#define ULPIS2S_PLLU_MASTER_BLASTER60 (1 << 3) +#define ULPIS2S_SPARE(x) (((x) & 0xF) << 8) +#define ULPIS2S_FORCE_ULPI_CLK_OUT (1 << 12) +#define ULPIS2S_DISCON_DONT_CHECK_SE0 (1 << 13) +#define ULPIS2S_SUPPORT_HS_KEEP_ALIVE (1 << 14) +#define ULPIS2S_DISABLE_STP_PU (1 << 15) +#define ULPIS2S_SLV0_CLAMP_XMIT (1 << 16) + +#define ULPI_TIMING_CTRL_0 0x424 +#define ULPI_CLOCK_OUT_DELAY(x) ((x) & 0x1F) +#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) +#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) +#define ULPI_SHADOW_CLK_LOOPBACK_EN (1 << 12) +#define ULPI_SHADOW_CLK_SEL (1 << 13) +#define ULPI_CORE_CLK_SEL (1 << 14) +#define ULPI_SHADOW_CLK_DELAY(x) (((x) & 0x1F) << 16) +#define ULPI_LBK_PAD_EN (1 << 26) +#define ULPI_LBK_PAD_E_INPUT_OR (1 << 27) +#define ULPI_CLK_OUT_ENA (1 << 28) +#define ULPI_CLK_PADOUT_ENA (1 << 29) + +#define ULPI_TIMING_CTRL_1 0x428 +#define ULPI_DATA_TRIMMER_LOAD (1 << 0) +#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) +#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) +#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) +#define ULPI_DIR_TRIMMER_LOAD (1 << 24) +#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) + +#define UTMIP_PLL_CFG1 0x804 +#define UHSIC_PLL_CFG1 0x804 +#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) +#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14) + +#define UTMIP_XCVR_UHSIC_HSRX_CFG0 0x808 +#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0) +#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2) +#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8) +#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8) +#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10) +#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13) +#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) +#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) +#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) +#define UTMIP_XCVR_LSBIAS_SEL (1 << 21) +#define UTMIP_XCVR_SETUP_MSB(x) (((x) & 0x7) << 22) +#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) +#define UTMIP_XCVR_MAX_OFFSET 2 +#define UTMIP_XCVR_SETUP_MAX_VALUE 0x7f +#define UTMIP_XCVR_SETUP_MIN_VALUE 0 +#define XCVR_SETUP_MSB_CALIB(x) ((x) >> 4) + +#define UTMIP_BIAS_CFG0 0x80c +#define UTMIP_OTGPD (1 << 11) +#define UTMIP_BIASPD (1 << 10) + +#define UHSIC_HSRX_CFG1 0x80c +#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) + +#define UTMIP_HSRX_CFG0 0x810 +#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) +#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15) + +#define UTMIP_HSRX_CFG1 0x814 +#define UHSIC_MISC_CFG0 0x814 +#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) +#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7) +#define UHSIC_DETECT_SHORT_CONNECT (1 << 8) +#define UHSIC_FORCE_XCVR_MODE (1 << 15) + +#define UHSIC_MISC_CFG1 0x818 +#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2) + +#define UHSIC_PADS_CFG0 0x81c +#define UHSIC_TX_RTUNEN 0xf000 +#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12) + +#define UTMIP_TX_CFG0 0x820 +#define UHSIC_PADS_CFG1 0x820 +#define UHSIC_PD_BG (1 << 2) +#define UHSIC_PD_TX (1 << 3) +#define UHSIC_PD_TRK (1 << 4) +#define UHSIC_PD_RX (1 << 5) +#define UHSIC_PD_ZI (1 << 6) +#define UHSIC_RX_SEL (1 << 7) +#define UHSIC_RPD_DATA (1 << 9) +#define UHSIC_RPD_STROBE (1 << 10) +#define UHSIC_RPU_DATA (1 << 11) +#define UHSIC_RPU_STROBE (1 << 12) +#define UTMIP_FS_PREABMLE_J (1 << 19) +#define UTMIP_HS_DISCON_DISABLE (1 << 8) + +#define UTMIP_MISC_CFG0 0x824 +#define UTMIP_DPDM_OBSERVE (1 << 26) +#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27) +#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf) +#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc) +#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) +#define FORCE_PULLDN_DM (1 << 8) +#define FORCE_PULLDN_DP (1 << 9) +#define COMB_TERMS (1 << 0) +#define ALWAYS_FREE_RUNNING_TERMS (1 << 1) + +#define USB1_PREFETCH_ID 6 +#define USB2_PREFETCH_ID 18 +#define USB3_PREFETCH_ID 17 + +#define UTMIP_MISC_CFG1 0x828 +#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18) +#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6) + +#define UHSIC_STAT_CFG0 0x828 +#define UHSIC_CONNECT_DETECT (1 << 0) + +#define UTMIP_DEBOUNCE_CFG0 0x82c +#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0) + +#define UTMIP_BAT_CHRG_CFG0 0x830 +#define UTMIP_PD_CHRG (1 << 0) +#define UTMIP_ON_SINK_EN (1 << 2) +#define UTMIP_OP_SRC_EN (1 << 3) + +#define UTMIP_SPARE_CFG0 0x834 +#define FUSE_SETUP_SEL (1 << 3) +#define FUSE_ATERM_SEL (1 << 4) + +#define UTMIP_XCVR_CFG1 0x838 +#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) +#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) +#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18) + +#define UTMIP_BIAS_CFG1 0x83c +#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) + +#define FUSE_USB_CALIB_0 0x1F0 +#define FUSE_USB_CALIB_XCVR_SETUP(x) (((x) & 0x7F) << 0) + +/* These values (in milli second) are taken from the battery charging spec */ +#define TDP_SRC_ON_MS 100 +#define TDPSRC_CON_MS 40 + +#ifdef DEBUG +#define DBG(stuff...) pr_info("tegra2_usb_phy: " stuff) +#else +#define DBG(stuff...) do {} while (0) +#endif + +static DEFINE_SPINLOCK(utmip_pad_lock); +static int utmip_pad_count; +static int utmip_pad_state_on; + +static struct tegra_xtal_freq utmip_freq_table[] = { + { + .freq = 12000000, + .enable_delay = 0x02, + .stable_count = 0x2F, + .active_delay = 0x04, + .xtal_freq_count = 0x76, + .debounce = 0x7530, + .pdtrk_count = 5, + }, + { + .freq = 13000000, + .enable_delay = 0x02, + .stable_count = 0x33, + .active_delay = 0x05, + .xtal_freq_count = 0x7F, + .debounce = 0x7EF4, + .pdtrk_count = 5, + }, + { + .freq = 19200000, + .enable_delay = 0x03, + .stable_count = 0x4B, + .active_delay = 0x06, + .xtal_freq_count = 0xBB, + .debounce = 0xBB80, + .pdtrk_count = 7, + }, + { + .freq = 26000000, + .enable_delay = 0x04, + .stable_count = 0x66, + .active_delay = 0x09, + .xtal_freq_count = 0xFE, + .debounce = 0xFDE8, + .pdtrk_count = 9, + }, +}; + +static struct tegra_xtal_freq uhsic_freq_table[] = { + { + .freq = 12000000, + .enable_delay = 0x02, + .stable_count = 0x2F, + .active_delay = 0x0, + .xtal_freq_count = 0x1CA, + }, + { + .freq = 13000000, + .enable_delay = 0x02, + .stable_count = 0x33, + .active_delay = 0x0, + .xtal_freq_count = 0x1F0, + }, + { + .freq = 19200000, + .enable_delay = 0x03, + .stable_count = 0x4B, + .active_delay = 0x0, + .xtal_freq_count = 0x2DD, + }, + { + .freq = 26000000, + .enable_delay = 0x04, + .stable_count = 0x66, + .active_delay = 0x0, + .xtal_freq_count = 0x3E0, + }, +}; + +static void usb_phy_fence_read(struct tegra_usb_phy *phy) +{ + /* Fence read for coherency of AHB master intiated writes */ + if (phy->inst == 0) + readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); + else if (phy->inst == 1) + readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); + else if (phy->inst == 2) + readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); + + return; +} + +static int usb_phy_bringup_host_controller(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x] port_speed[%d] - 0\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC), + phy->port_speed); + + /* enable host mode */ + val = readl(base + USB_USBMODE_REG_OFFSET); + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE_REG_OFFSET); + + /* Enable Port Power */ + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PP; + writel(val, base + USB_PORTSC); + udelay(10); + + /* Check if the phy resume from LP0. When the phy resume from LP0 + * USB register will be reset.to zero */ + if (!readl(base + USB_ASYNCLISTADDR)) { + val = readl(base + USB_USBCMD); + val |= USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + + /* Program the field PTC based on the saved speed mode */ + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_PTC(~0)); + if (phy->port_speed == USB_PHY_PORT_SPEED_HIGH) + val |= USB_PORTSC_PTC(5); + else if (phy->port_speed == USB_PHY_PORT_SPEED_FULL) + val |= USB_PORTSC_PTC(6); + else if (phy->port_speed == USB_PHY_PORT_SPEED_LOW) + val |= USB_PORTSC_PTC(7); + writel(val, base + USB_PORTSC); + udelay(10); + + /* Disable test mode by setting PTC field to NORMAL_OP */ + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_PTC(~0)); + writel(val, base + USB_PORTSC); + udelay(10); + } + + /* Poll until CCS is enabled */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_CCS, + USB_PORTSC_CCS, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_CCS\n", __func__); + } + + /* Poll until PE is enabled */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_PE, + USB_PORTSC_PE, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_PE\n", __func__); + } + + /* Clear the PCI status, to avoid an interrupt taken upon resume */ + val = readl(base + USB_USBSTS); + val |= USB_USBSTS_PCI; + writel(val, base + USB_USBSTS); + + /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ + val = readl(base + USB_PORTSC); + if ((val & USB_PORTSC_PP) && (val & USB_PORTSC_PE)) { + val |= USB_PORTSC_SUSP; + writel(val, base + USB_PORTSC); + /* Need a 4ms delay before the controller goes to suspend */ + mdelay(4); + + /* Wait until port suspend completes */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_SUSP, + USB_PORTSC_SUSP, 1000)) { + pr_err("%s: timeout waiting for PORT_SUSPEND\n", + __func__); + } + } + + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x]\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC)); + + return 0; +} + +static void usb_phy_wait_for_sof(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + USB_USBSTS); + writel(val, base + USB_USBSTS); + udelay(20); + /* wait for two SOFs */ + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_SRI, + USB_USBSTS_SRI, 2500)) + pr_err("%s: timeout waiting for SOF\n", __func__); + + val = readl(base + USB_USBSTS); + writel(val, base + USB_USBSTS); + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_SRI, 0, 2500)) + pr_err("%s: timeout waiting for SOF\n", __func__); + + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_SRI, + USB_USBSTS_SRI, 2500)) + pr_err("%s: timeout waiting for SOF\n", __func__); + + udelay(20); +} + +static unsigned int utmi_phy_xcvr_setup_value(struct tegra_usb_phy *phy) +{ + struct tegra_utmi_config *cfg = &phy->pdata->u_cfg.utmi; + signed long val; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (cfg->xcvr_use_fuses) { + val = FUSE_USB_CALIB_XCVR_SETUP( + tegra_fuse_readl(FUSE_USB_CALIB_0)); + if (cfg->xcvr_setup_offset <= UTMIP_XCVR_MAX_OFFSET) + val = val + cfg->xcvr_setup_offset; + + if (val > UTMIP_XCVR_SETUP_MAX_VALUE) { + val = UTMIP_XCVR_SETUP_MAX_VALUE; + pr_info("%s: reset XCVR_SETUP to max value\n", + __func__); + } else if (val < UTMIP_XCVR_SETUP_MIN_VALUE) { + val = UTMIP_XCVR_SETUP_MIN_VALUE; + pr_info("%s: reset XCVR_SETUP to min value\n", + __func__); + } + } else { + val = cfg->xcvr_setup; + } + + return (unsigned int) val; +} + + +static int utmi_phy_open(struct tegra_usb_phy *phy) +{ + unsigned long parent_rate; + int i; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + phy->utmi_pad_clk = clk_get_sys("utmip-pad", NULL); + if (IS_ERR(phy->utmi_pad_clk)) { + pr_err("%s: can't get utmip pad clock\n", __func__); + return PTR_ERR(phy->utmi_pad_clk); + } + + phy->utmi_xcvr_setup = utmi_phy_xcvr_setup_value(phy); + + parent_rate = clk_get_rate(clk_get_parent(phy->pllu_clk)); + for (i = 0; i < ARRAY_SIZE(utmip_freq_table); i++) { + if (utmip_freq_table[i].freq == parent_rate) { + phy->freq = &utmip_freq_table[i]; + break; + } + } + if (!phy->freq) { + pr_err("invalid pll_u parent rate %ld\n", parent_rate); + return -EINVAL; + } + + return 0; +} + +static void utmi_phy_close(struct tegra_usb_phy *phy) +{ + DBG("%s inst:[%d]\n", __func__, phy->inst); + + clk_put(phy->utmi_pad_clk); +} + +static int utmi_phy_pad_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val, flags; + void __iomem *pad_base = IO_ADDRESS(TEGRA_USB_BASE); + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + clk_enable(phy->utmi_pad_clk); + + spin_lock_irqsave(&utmip_pad_lock, flags); + + utmip_pad_count++; + val = readl(pad_base + UTMIP_BIAS_CFG0); + val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); + writel(val, pad_base + UTMIP_BIAS_CFG0); + utmip_pad_state_on = true; + + spin_unlock_irqrestore(&utmip_pad_lock, flags); + + clk_disable(phy->utmi_pad_clk); + + return 0; +} + +static int utmi_phy_pad_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val, flags; + void __iomem *pad_base = IO_ADDRESS(TEGRA_USB_BASE); + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + clk_enable(phy->utmi_pad_clk); + spin_lock_irqsave(&utmip_pad_lock, flags); + + if (!utmip_pad_count) { + pr_err("%s: utmip pad already powered off\n", __func__); + goto out; + } + if (--utmip_pad_count == 0) { + val = readl(pad_base + UTMIP_BIAS_CFG0); + val |= UTMIP_OTGPD | UTMIP_BIASPD; + writel(val, pad_base + UTMIP_BIAS_CFG0); + utmip_pad_state_on = false; + } +out: + spin_unlock_irqrestore(&utmip_pad_lock, flags); + clk_disable(phy->utmi_pad_clk); + + return 0; +} + +static int utmi_phy_irq(struct tegra_usb_phy *phy) +{ + void __iomem *base = phy->regs; + unsigned long val = 0; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + usb_phy_fence_read(phy); + if (phy->pdata->u_data.host.hot_plug) { + val = readl(base + USB_SUSP_CTRL); + if ((val & USB_PHY_CLK_VALID_INT_STS)) { + val &= ~USB_PHY_CLK_VALID_INT_ENB | + USB_PHY_CLK_VALID_INT_STS; + writel(val , (base + USB_SUSP_CTRL)); + pr_info("%s: usb device plugged-in\n", __func__); + val = readl(base + USB_USBSTS); + if (!(val & USB_USBSTS_PCI)) + return IRQ_NONE; + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_WKCN | USB_PORTSC_RWC_BITS); + writel(val , (base + USB_PORTSC)); + } + } + + return IRQ_HANDLED; +} + + +static int utmi_phy_post_resume(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + val = readl(base + UTMIP_TX_CFG0); + val &= ~UTMIP_HS_DISCON_DISABLE; + writel(val, base + UTMIP_TX_CFG0); + return 0; +} + +static int utmi_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + UTMIP_TX_CFG0); + val |= UTMIP_HS_DISCON_DISABLE; + writel(val, base + UTMIP_TX_CFG0); + + usb_phy_wait_for_sof(phy); + + return 0; +} + +static int utmi_phy_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (!phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already off\n", + __func__, __LINE__, phy->inst); + return 0; + } + + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + val = readl(base + USB_SUSP_CTRL); + val &= ~(USB_WAKEUP_DEBOUNCE_COUNT(~0)); + val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5); + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val |= UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + } + + if (!phy->pdata->u_data.host.hot_plug) { + val = readl(base + UTMIP_XCVR_UHSIC_HSRX_CFG0); + val |= (UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | + UTMIP_FORCE_PDZI_POWERDOWN); + writel(val, base + UTMIP_XCVR_UHSIC_HSRX_CFG0); + } + + val = readl(base + UTMIP_XCVR_CFG1); + val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | + UTMIP_FORCE_PDDR_POWERDOWN; + writel(val, base + UTMIP_XCVR_CFG1); + + if (phy->inst != 0) { + val = readl(base + UTMIP_BIAS_CFG0); + val |= UTMIP_OTGPD; + writel(val, base + UTMIP_BIAS_CFG0); + } + + phy->port_speed = (readl(base + USB_PORTSC) >> 26) & + USB_PORTSC_PSPD_MASK; + + if (phy->pdata->u_data.host.hot_plug) { + bool enable_hotplug = true; + /* if it is OTG port then make sure to enable hot-plug feature + only if host adaptor is connected, i.e id is low */ + if (phy->pdata->port_otg) { + val = readl(base + USB_PHY_VBUS_WAKEUP_ID); + enable_hotplug = (val & USB_ID_STATUS) ? false : true; + } + if (enable_hotplug) { + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_WKCN; + writel(val, base + USB_PORTSC); + + val = readl(base + USB_SUSP_CTRL); + val |= USB_PHY_CLK_VALID_INT_ENB; + writel(val, base + USB_SUSP_CTRL); + } else { + /* Disable PHY clock valid interrupts while going into suspend*/ + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_PHY_CLK_VALID_INT_ENB; + writel(val, base + USB_SUSP_CTRL); + } + } + + if (phy->inst == 2) { + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PHCD; + writel(val, base + USB_PORTSC); + } else { + val = readl(base + USB_SUSP_CTRL); + val |= USB_SUSP_SET; + writel(val, base + USB_SUSP_CTRL); + udelay(10); + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_SUSP_SET; + writel(val, base + USB_SUSP_CTRL); + } + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + 0, 2500)) + pr_warn("%s: timeout waiting for phy to stabilize\n", __func__); + + utmi_phy_pad_power_off(phy); + + phy->phy_clk_on = false; + phy->hw_accessible = false; + + DBG("%s(%d) inst:[%d]END\n", __func__, __LINE__, phy->inst); + + return 0; +} + +static int utmi_phy_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + struct tegra_utmi_config *config = &phy->pdata->u_cfg.utmi; + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already on\n", + __func__, __LINE__, phy->inst); + return 0; + } + + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_TX_CFG0); + val |= UTMIP_FS_PREABMLE_J; + writel(val, base + UTMIP_TX_CFG0); + + val = readl(base + UTMIP_HSRX_CFG0); + val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0)); + val |= UTMIP_IDLE_WAIT(config->idle_wait_delay); + val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit); + writel(val, base + UTMIP_HSRX_CFG0); + + val = readl(base + UTMIP_HSRX_CFG1); + val &= ~(UTMIP_HS_SYNC_START_DLY(~0)); + val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay); + writel(val, base + UTMIP_HSRX_CFG1); + + val = readl(base + UTMIP_DEBOUNCE_CFG0); + val &= ~UTMIP_BIAS_DEBOUNCE_A(~0); + val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce); + writel(val, base + UTMIP_DEBOUNCE_CFG0); + + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE; + writel(val, base + UTMIP_MISC_CFG0); + + val = readl(base + UTMIP_MISC_CFG1); + val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0)); + val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) | + UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count); + writel(val, base + UTMIP_MISC_CFG1); + + val = readl(base + UTMIP_PLL_CFG1); + val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0)); + val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) | + UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); + writel(val, base + UTMIP_PLL_CFG1); + + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + val = readl(base + USB_SUSP_CTRL); + val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV); + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val &= ~UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + } else { + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val |= UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + } + + utmi_phy_pad_power_on(phy); + + val = readl(base + UTMIP_XCVR_UHSIC_HSRX_CFG0); + val &= ~(UTMIP_XCVR_LSBIAS_SEL | UTMIP_FORCE_PD_POWERDOWN | + UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN | + UTMIP_XCVR_SETUP(~0) | UTMIP_XCVR_LSFSLEW(~0) | + UTMIP_XCVR_LSRSLEW(~0) | UTMIP_XCVR_HSSLEW_MSB(~0)); + val |= UTMIP_XCVR_SETUP(phy->utmi_xcvr_setup); + val |= UTMIP_XCVR_SETUP_MSB(XCVR_SETUP_MSB_CALIB(phy->utmi_xcvr_setup)); + val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); + val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); + + writel(val, base + UTMIP_XCVR_UHSIC_HSRX_CFG0); + + val = readl(base + UTMIP_XCVR_CFG1); + val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | + UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0)); + val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj); + writel(val, base + UTMIP_XCVR_CFG1); + + + val = readl(base + UTMIP_BIAS_CFG1); + val &= ~(UTMIP_BIAS_PDTRK_COUNT(~0)); + val |= UTMIP_BIAS_PDTRK_COUNT(phy->freq->pdtrk_count); + writel(val, base + UTMIP_BIAS_CFG1); + + val = readl(base + UTMIP_SPARE_CFG0); + val &= ~FUSE_SETUP_SEL; + writel(val, base + UTMIP_SPARE_CFG0); + + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + USB_SUSP_CTRL); + val &= ~UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + + if (phy->inst == 0) { + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_SUSP_SET; + writel(val, base + USB_SUSP_CTRL); + } else { + val = readl(base + USB_PORTSC); + val &= ~USB_PORTSC_PHCD; + writel(val, base + USB_PORTSC); + } + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, + USB_PHY_CLK_VALID, USB_PHY_CLK_VALID, 2500)) + pr_warn("%s: timeout waiting for phy to stabilize\n", __func__); + + if (phy->inst == 2) { + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_PTS(~0)); + writel(val, base + USB_PORTSC); + } + + phy->phy_clk_on = true; + phy->hw_accessible = true; + + return 0; +} + +static void utmi_phy_restore_start(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + UTMIP_MISC_CFG0); + val &= ~(UTMIP_DPDM_OBSERVE_SEL(~0)); + + if (phy->port_speed == USB_PHY_PORT_SPEED_LOW) + val |= UTMIP_DPDM_OBSERVE_SEL_FS_K; + else + val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; + writel(val, base + UTMIP_MISC_CFG0); + udelay(1); + + val = readl(base + UTMIP_MISC_CFG0); + val |= UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + udelay(10); +} + +static void utmi_phy_restore_end(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + udelay(10); +} + + +static int utmi_phy_resume(struct tegra_usb_phy *phy) +{ + int status = 0; + unsigned long val, flags; + void __iomem *base = phy->regs; + void __iomem *pad_base = IO_ADDRESS(TEGRA_USB_BASE); + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) { + if (phy->port_speed < USB_PHY_PORT_SPEED_UNKNOWN) { + utmi_phy_restore_start(phy); + usb_phy_bringup_host_controller(phy); + utmi_phy_restore_end(phy); + } else { + /* device is plugged in when system is in LP0 */ + /* bring up the controller from LP0*/ + val = readl(base + USB_USBCMD); + val |= USB_USBCMD_RESET; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, + USB_USBCMD_RESET, 0, 2500) < 0) { + pr_err("%s: timeout waiting for reset\n", __func__); + } + + val = readl(base + USB_USBMODE_REG_OFFSET); + val &= ~USB_USBMODE_MASK; + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE_REG_OFFSET); + + if (phy->inst == 2) { + val = readl(base + USB_PORTSC); + val &= ~USB_PORTSC_PTS(~0); + writel(val, base + USB_PORTSC); + } + writel(USB_USBCMD_RS, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, + USB_USBCMD_RS, USB_USBCMD_RS, 2500) < 0) { + pr_err("%s: timeout waiting for run bit\n", __func__); + } + + /* Enable Port Power */ + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PP; + writel(val, base + USB_PORTSC); + udelay(10); + + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x]\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC)); + } + } else { + /* Restoring the pad powers */ + clk_enable(phy->utmi_pad_clk); + + spin_lock_irqsave(&utmip_pad_lock, flags); + + val = readl(pad_base + UTMIP_BIAS_CFG0); + if (utmip_pad_state_on) + val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); + else + val |= (UTMIP_OTGPD | UTMIP_BIASPD); + writel(val, pad_base + UTMIP_BIAS_CFG0); + + spin_unlock_irqrestore(&utmip_pad_lock, flags); + clk_disable(phy->utmi_pad_clk); + } + + return status; +} + +static bool utmi_phy_charger_detect(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + bool status; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + /* Enable charger detection logic */ + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val |= UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + + /* Source should be on for 100 ms as per USB charging spec */ + msleep(TDP_SRC_ON_MS); + + val = readl(base + USB_PHY_VBUS_WAKEUP_ID); + /* If charger is not connected disable the interrupt */ + val &= ~VDAT_DET_INT_EN; + val |= VDAT_DET_CHG_DET; + writel(val, base + USB_PHY_VBUS_WAKEUP_ID); + + val = readl(base + USB_PHY_VBUS_WAKEUP_ID); + if (val & VDAT_DET_STS) + status = true; + else + status = false; + + /* Disable charger detection logic */ + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val &= ~(UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN); + writel(val, base + UTMIP_BAT_CHRG_CFG0); + + /* Delay of 40 ms before we pull the D+ as per battery charger spec */ + msleep(TDPSRC_CON_MS); + + return status; +} + + +static int uhsic_phy_open(struct tegra_usb_phy *phy) +{ + unsigned long parent_rate; + int i; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + parent_rate = clk_get_rate(clk_get_parent(phy->pllu_clk)); + for (i = 0; i < ARRAY_SIZE(uhsic_freq_table); i++) { + if (uhsic_freq_table[i].freq == parent_rate) { + phy->freq = &uhsic_freq_table[i]; + break; + } + } + if (!phy->freq) { + pr_err("invalid pll_u parent rate %ld\n", parent_rate); + return -EINVAL; + } + + return 0; +} + +static int uhsic_phy_irq(struct tegra_usb_phy *phy) +{ + usb_phy_fence_read(phy); + return IRQ_HANDLED; +} + +static int uhsic_phy_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + struct tegra_hsic_config *config = &phy->pdata->u_cfg.hsic; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already On\n", __func__, + __LINE__, phy->inst); + return 0; + } + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~(UHSIC_PD_BG | UHSIC_PD_TX | UHSIC_PD_TRK | UHSIC_PD_RX | + UHSIC_PD_ZI | UHSIC_RPD_DATA | UHSIC_RPD_STROBE); + val |= UHSIC_RX_SEL; + writel(val, base + UHSIC_PADS_CFG1); + udelay(2); + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel(val, base + USB_SUSP_CTRL); + udelay(30); + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_XCVR_UHSIC_HSRX_CFG0); + val |= UHSIC_IDLE_WAIT(config->idle_wait_delay); + val |= UHSIC_ELASTIC_UNDERRUN_LIMIT(config->elastic_underrun_limit); + val |= UHSIC_ELASTIC_OVERRUN_LIMIT(config->elastic_overrun_limit); + writel(val, base + UTMIP_XCVR_UHSIC_HSRX_CFG0); + + val = readl(base + UHSIC_HSRX_CFG1); + val |= UHSIC_HS_SYNC_START_DLY(config->sync_start_delay); + writel(val, base + UHSIC_HSRX_CFG1); + + val = readl(base + UHSIC_MISC_CFG0); + val |= UHSIC_SUSPEND_EXIT_ON_EDGE; + writel(val, base + UHSIC_MISC_CFG0); + + val = readl(base + UHSIC_MISC_CFG1); + val |= UHSIC_PLLU_STABLE_COUNT(phy->freq->stable_count); + writel(val, base + UHSIC_MISC_CFG1); + + val = readl(base + UHSIC_PLL_CFG1); + val |= UHSIC_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); + val |= UHSIC_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count); + writel(val, base + UHSIC_PLL_CFG1); + + val = readl(base + USB_SUSP_CTRL); + val &= ~(UHSIC_RESET); + writel(val, base + USB_SUSP_CTRL); + udelay(2); + + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_PTS(~0)); + writel(val, base + USB_PORTSC); + + val = readl(base + USB_TXFILLTUNING); + if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) { + val = USB_FIFO_TXFILL_THRES(0x10); + writel(val, base + USB_TXFILLTUNING); + } + + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_WKOC | USB_PORTSC_WKDS | USB_PORTSC_WKCN); + writel(val, base + USB_PORTSC); + + val = readl(base + UHSIC_PADS_CFG0); + val &= ~(UHSIC_TX_RTUNEN); + /* set Rtune impedance to 40 ohm */ + val |= UHSIC_TX_RTUNE(0); + writel(val, base + UHSIC_PADS_CFG0); + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID, 2500)) { + pr_err("%s: timeout waiting for phy to stabilize\n", __func__); + return -ETIMEDOUT; + } + + phy->phy_clk_on = true; + phy->hw_accessible = true; + + return 0; +} + +static int uhsic_phy_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (!phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already off\n", __func__, + __LINE__, phy->inst); + return 0; + } + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPU_STROBE; + val |= UHSIC_RPD_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel(val, base + USB_SUSP_CTRL); + udelay(30); + + val = readl(base + USB_SUSP_CTRL); + val &= ~UHSIC_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + + phy->phy_clk_on = false; + phy->hw_accessible = false; + + return 0; +} + +static int uhsic_phy_bus_port_power(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + UHSIC_MISC_CFG0); + val |= UHSIC_DETECT_SHORT_CONNECT; + writel(val, base + UHSIC_MISC_CFG0); + udelay(1); + + val = readl(base + UHSIC_MISC_CFG0); + val |= UHSIC_FORCE_XCVR_MODE; + writel(val, base + UHSIC_MISC_CFG0); + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPD_STROBE; + val |= UHSIC_RPU_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + val = readl(base + USB_USBCMD); + val &= ~USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + UHSIC_STAT_CFG0, + UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT, 2000)) { + pr_err("%s: timeout waiting for UHSIC_CONNECT_DETECT\n", + __func__); + return -ETIMEDOUT; + } + +/* FIXME : need to check whether this piece is required or not + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_LS(2), + USB_PORTSC_LS(2), 2000)) { + pr_err("%s: timeout waiting for dplus state\n", __func__); + return -ETIMEDOUT; + } +*/ + return 0; +} + + +static int uhsic_phy_bus_reset(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PTC(5); + writel(val, base + USB_PORTSC); + udelay(2); + + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_PTC(~0)); + writel(val, base + USB_PORTSC); + udelay(2); + + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_LS(0), + 0, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_LS\n", __func__); + return -ETIMEDOUT; + } + + /* Poll until CCS is enabled */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_CCS, + USB_PORTSC_CCS, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_CCS\n", __func__); + return -ETIMEDOUT; + } + + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_PSPD(2), + USB_PORTSC_PSPD(2), 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_PSPD\n", __func__); + return -ETIMEDOUT; + } + + val = readl(base + USB_USBCMD); + val &= ~USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_HCH, + USB_USBSTS_HCH, 2000)) { + pr_err("%s: timeout waiting for USB_USBSTS_HCH\n", __func__); + return -ETIMEDOUT; + } + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPU_STROBE; + val |= UHSIC_RPD_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + mdelay(50); + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPD_STROBE; + val |= UHSIC_RPU_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + val = readl(base + USB_USBCMD); + val |= USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPU_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, USB_USBCMD_RS, + USB_USBCMD_RS, 2000)) { + pr_err("%s: timeout waiting for USB_USBCMD_RS\n", __func__); + return -ETIMEDOUT; + } + + return 0; +} + + +static int uhsic_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) +{ + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + usb_phy_wait_for_sof(phy); + + return 0; +} + +static int uhsic_phy_resume(struct tegra_usb_phy *phy) +{ + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + uhsic_phy_bus_port_power(phy); + + return 0; +} + + +static int uhsic_phy_post_resume(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + USB_TXFILLTUNING); + if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) { + val = USB_FIFO_TXFILL_THRES(0x10); + writel(val, base + USB_TXFILLTUNING); + } + + return 0; +} + +static void ulpi_set_trimmer(struct tegra_usb_phy *phy) +{ + struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi; + void __iomem *base = phy->regs; + unsigned long val; + + val = ULPI_DATA_TRIMMER_SEL(config->data_trimmer); + val |= ULPI_STPDIRNXT_TRIMMER_SEL(config->stpdirnxt_trimmer); + val |= ULPI_DIR_TRIMMER_SEL(config->dir_trimmer); + writel(val, base + ULPI_TIMING_CTRL_1); + udelay(10); + + val |= ULPI_DATA_TRIMMER_LOAD; + val |= ULPI_STPDIRNXT_TRIMMER_LOAD; + val |= ULPI_DIR_TRIMMER_LOAD; + writel(val, base + ULPI_TIMING_CTRL_1); +} + + +static int ulpi_link_phy_open(struct tegra_usb_phy *phy) +{ + struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi; + int err = 0; + + phy->ulpi_clk = NULL; + + if (config->clk) { + phy->ulpi_clk = clk_get_sys(NULL, config->clk); + if (IS_ERR(phy->ulpi_clk)) { + pr_err("%s: can't get ulpi clock\n", __func__); + err = -ENXIO; + } + } + + phy->ulpi_vp = otg_ulpi_create(&ulpi_viewport_access_ops, 0); + phy->ulpi_vp->io_priv = phy->regs + ULPI_VIEWPORT; + + return err; +} + +static void ulpi_link_phy_close(struct tegra_usb_phy *phy) +{ + DBG("%s inst:[%d]\n", __func__, phy->inst); + if (phy->ulpi_clk) + clk_put(phy->ulpi_clk); +} + +static int ulpi_link_phy_irq(struct tegra_usb_phy *phy) +{ + usb_phy_fence_read(phy); + return IRQ_HANDLED; +} + +static int ulpi_link_phy_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + int ret; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (!phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already off\n", __func__, + __LINE__, phy->inst); + return 0; + } + + /* Disable VbusValid, SessEnd comparators */ + ret = otg_io_write(phy->ulpi_vp, 0x00, 0x0D); + if (ret) + pr_err("%s: ulpi write 0x0D failed\n", __func__); + + ret = otg_io_write(phy->ulpi_vp, 0x00, 0x10); + if (ret) + pr_err("%s: ulpi write 0x10 failed\n", __func__); + + /* Disable IdFloat comparator */ + ret = otg_io_write(phy->ulpi_vp, 0x00, 0x19); + if (ret) + pr_err("%s: ulpi write 0x19 failed\n", __func__); + + ret = otg_io_write(phy->ulpi_vp, 0x00, 0x1D); + if (ret) + pr_err("%s: ulpi write 0x1D failed\n", __func__); + + phy->port_speed = (readl(base + USB_PORTSC) >> 26) & + USB_PORTSC_PSPD_MASK; + + /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB + * Controller to immediately bring the ULPI PHY out of low power + */ + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_WKOC | USB_PORTSC_WKDS | USB_PORTSC_WKCN); + writel(val, base + USB_PORTSC); + + /* Put the PHY in the low power mode */ + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PHCD; + writel(val, base + USB_PORTSC); + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + 0, 2500)) { + pr_err("%s: timeout waiting for phy to stop\n", __func__); + } + + if (phy->ulpi_clk) + clk_disable(phy->ulpi_clk); + + phy->phy_clk_on = false; + phy->hw_accessible = false; + + return 0; +} + +static int ulpi_link_phy_power_on(struct tegra_usb_phy *phy) +{ + int ret; + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already On\n", __func__, + __LINE__, phy->inst); + return 0; + } + + if (phy->ulpi_clk) { + clk_enable(phy->ulpi_clk); + mdelay(1); + } + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP; + writel(val, base + ULPI_TIMING_CTRL_0); + + val = readl(base + USB_SUSP_CTRL); + val |= ULPI_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + USB_SUSP_CTRL); + val |= USB_SUSP_CLR; + writel(val, base + USB_SUSP_CTRL); + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID, 2500)) + pr_err("%s: timeout waiting for phy to stabilize\n", __func__); + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_CLKEN, + USB_CLKEN, 2500)) + pr_err("%s: timeout waiting for AHB clock\n", __func__); + + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_SUSP_CLR; + writel(val, base + USB_SUSP_CTRL); + + val = 0; + writel(val, base + ULPI_TIMING_CTRL_1); + + ulpi_set_trimmer(phy); + + /* Fix VbusInvalid due to floating VBUS */ + ret = otg_io_write(phy->ulpi_vp, 0x40, 0x08); + if (ret) { + pr_err("%s: ulpi write failed\n", __func__); + return ret; + } + + ret = otg_io_write(phy->ulpi_vp, 0x80, 0x0B); + if (ret) { + pr_err("%s: ulpi write failed\n", __func__); + return ret; + } + + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_WKOC | USB_PORTSC_WKDS | USB_PORTSC_WKCN; + writel(val, base + USB_PORTSC); + + phy->phy_clk_on = true; + phy->hw_accessible = true; + + return 0; +} + +static inline void ulpi_link_phy_set_tristate(bool enable) +{ +#ifdef CONFIG_ARCH_TEGRA_2x_SOC + int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL; + + tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate); +#endif +} + +static void ulpi_link_phy_restore_start(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + /*Tristate ulpi interface before USB controller resume*/ + ulpi_link_phy_set_tristate(true); + + val = readl(base + ULPI_TIMING_CTRL_0); + val &= ~ULPI_OUTPUT_PINMUX_BYP; + writel(val, base + ULPI_TIMING_CTRL_0); +} + +static void ulpi_link_phy_restore_end(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_OUTPUT_PINMUX_BYP; + writel(val, base + ULPI_TIMING_CTRL_0); + + ulpi_link_phy_set_tristate(false); +} + +static int ulpi_link_phy_resume(struct tegra_usb_phy *phy) +{ + int status = 0; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->pdata->u_data.host.power_off_on_suspend) { + status = ulpi_link_phy_power_on(phy); + if (phy->port_speed < USB_PHY_PORT_SPEED_UNKNOWN) { + ulpi_link_phy_restore_start(phy); + usb_phy_bringup_host_controller(phy); + ulpi_link_phy_restore_end(phy); + } + } + + return status; +} + +static struct tegra_usb_phy_ops utmi_phy_ops = { + .open = utmi_phy_open, + .close = utmi_phy_close, + .irq = utmi_phy_irq, + .power_on = utmi_phy_power_on, + .power_off = utmi_phy_power_off, + .pre_resume = utmi_phy_pre_resume, + .resume = utmi_phy_resume, + .post_resume = utmi_phy_post_resume, + .charger_detect = utmi_phy_charger_detect, +}; + +static struct tegra_usb_phy_ops uhsic_phy_ops = { + .open = uhsic_phy_open, + .irq = uhsic_phy_irq, + .power_on = uhsic_phy_power_on, + .power_off = uhsic_phy_power_off, + .pre_resume = uhsic_phy_pre_resume, + .resume = uhsic_phy_resume, + .post_resume = uhsic_phy_post_resume, + .port_power = uhsic_phy_bus_port_power, + .bus_reset = uhsic_phy_bus_reset, +}; + +static struct tegra_usb_phy_ops ulpi_link_phy_ops = { + .open = ulpi_link_phy_open, + .close = ulpi_link_phy_close, + .irq = ulpi_link_phy_irq, + .power_on = ulpi_link_phy_power_on, + .power_off = ulpi_link_phy_power_off, + .resume = ulpi_link_phy_resume, +}; + +static struct tegra_usb_phy_ops ulpi_null_phy_ops; +static struct tegra_usb_phy_ops icusb_phy_ops; + + +static struct tegra_usb_phy_ops *phy_ops[] = { + [TEGRA_USB_PHY_INTF_UTMI] = &utmi_phy_ops, + [TEGRA_USB_PHY_INTF_ULPI_LINK] = &ulpi_link_phy_ops, + [TEGRA_USB_PHY_INTF_ULPI_NULL] = &ulpi_null_phy_ops, + [TEGRA_USB_PHY_INTF_HSIC] = &uhsic_phy_ops, + [TEGRA_USB_PHY_INTF_ICUSB] = &icusb_phy_ops, +}; + +int tegra2_usb_phy_init_ops(struct tegra_usb_phy *phy) +{ + phy->ops = phy_ops[phy->pdata->phy_intf]; + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c index 2dfdb1db39b7..9ff183377c2d 100644 --- a/arch/arm/mach-tegra/tegra3_clocks.c +++ b/arch/arm/mach-tegra/tegra3_clocks.c @@ -284,7 +284,7 @@ #define PLLE_SS_COEFFICIENTS_12MHZ \ ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \ (0x24<<PLLE_SS_MAX_SHIFT)) -#define PLLE_SS_DISABLE ((1<<12) | (1<<11) | (1<<10)) +#define PLLE_SS_DISABLE ((1<<14) | (1<<12) | (1<<11) | (1<<10)) #define PLLE_AUX 0x48c #define PLLE_AUX_PLLP_SEL (1<<2) @@ -3906,7 +3906,7 @@ static struct clk tegra_clk_sclk = { .reg = 0x28, .ops = &tegra_super_ops, .max_rate = 378000000, - .min_rate = 40000000, + .min_rate = 12000000, }; static struct clk tegra_clk_virtual_cpu_g = { @@ -3961,7 +3961,7 @@ static struct clk tegra_clk_hclk = { .reg_shift = 4, .ops = &tegra_bus_ops, .max_rate = 378000000, - .min_rate = 40000000, + .min_rate = 12000000, }; static struct clk tegra_clk_pclk = { @@ -3972,7 +3972,7 @@ static struct clk tegra_clk_pclk = { .reg_shift = 0, .ops = &tegra_bus_ops, .max_rate = 167000000, - .min_rate = 40000000, + .min_rate = 12000000, }; static struct raw_notifier_head sbus_rate_change_nh; diff --git a/arch/arm/mach-tegra/tegra3_usb_phy.c b/arch/arm/mach-tegra/tegra3_usb_phy.c new file mode 100644 index 000000000000..5b3e51974d3b --- /dev/null +++ b/arch/arm/mach-tegra/tegra3_usb_phy.c @@ -0,0 +1,2409 @@ +/* + * arch/arm/mach-tegra/tegra3_usb_phy.c + * + * Copyright (C) 2011 NVIDIA Corporation + * + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 <linux/resource.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/regulator/consumer.h> +#include <linux/platform_data/tegra_usb.h> +#include <mach/iomap.h> +#include <mach/pinmux.h> +#include "tegra_usb_phy.h" +#include "fuse.h" + +#define USB_USBCMD 0x130 +#define USB_USBCMD_RS (1 << 0) +#define USB_CMD_RESET (1<<1) + +#define USB_USBSTS 0x134 +#define USB_USBSTS_PCI (1 << 2) +#define USB_USBSTS_SRI (1 << 7) +#define USB_USBSTS_HCH (1 << 12) + +#define USB_USBINTR 0x138 + +#define USB_TXFILLTUNING 0x154 +#define USB_FIFO_TXFILL_THRES(x) (((x) & 0x1f) << 16) +#define USB_FIFO_TXFILL_MASK 0x1f0000 + +#define USB_ASYNCLISTADDR 0x148 + +#define ICUSB_CTRL 0x15c + +#define USB_PORTSC 0x174 +#define USB_PORTSC_WKOC (1 << 22) +#define USB_PORTSC_WKDS (1 << 21) +#define USB_PORTSC_WKCN (1 << 20) +#define USB_PORTSC_PTC(x) (((x) & 0xf) << 16) +#define USB_PORTSC_PP (1 << 12) +#define USB_PORTSC_LS(x) (((x) & 0x3) << 10) +#define USB_PORTSC_SUSP (1 << 7) +#define USB_PORTSC_RESUME (1 << 6) +#define USB_PORTSC_OCC (1 << 5) +#define USB_PORTSC_PEC (1 << 3) +#define USB_PORTSC_PE (1 << 2) +#define USB_PORTSC_CSC (1 << 1) +#define USB_PORTSC_CCS (1 << 0) +#define USB_PORTSC_RWC_BITS (USB_PORTSC_CSC | USB_PORTSC_PEC | USB_PORTSC_OCC) + +#define HOSTPC1_DEVLC 0x1b4 +#define HOSTPC1_DEVLC_PHCD (1 << 22) +#define HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29) +#define HOSTPC1_DEVLC_PTS_MASK 7 +#define HOSTPC1_DEVLC_PTS_HSIC 4 +#define HOSTPC1_DEVLC_STS (1 << 28) +#define HOSTPC1_DEVLC_PSPD(x) (((x) & 0x3) << 25) +#define HOSTPC1_DEVLC_PSPD_MASK 3 +#define HOSTPC1_DEVLC_PSPD_HIGH_SPEED 2 + +#define USB_USBMODE 0x1f8 +#define USB_USBMODE_MASK (3 << 0) +#define USB_USBMODE_HOST (3 << 0) +#define USB_USBMODE_DEVICE (2 << 0) + +#define USB_SUSP_CTRL 0x400 +#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) +#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) +#define USB_SUSP_CLR (1 << 5) +#define USB_PHY_CLK_VALID (1 << 7) +#define USB_PHY_CLK_VALID_INT_ENB (1 << 9) +#define USB_PHY_CLK_VALID_INT_STS (1 << 8) +#define UTMIP_RESET (1 << 11) +#define UTMIP_PHY_ENABLE (1 << 12) +#define ULPI_PHY_ENABLE (1 << 13) +#define UHSIC_RESET (1 << 14) +#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) +#define UHSIC_PHY_ENABLE (1 << 19) +#define ULPIS2S_SLV0_RESET (1 << 20) +#define ULPIS2S_SLV1_RESET (1 << 21) +#define ULPIS2S_LINE_RESET (1 << 22) +#define ULPI_PADS_RESET (1 << 23) +#define ULPI_PADS_CLKEN_RESET (1 << 24) + +#define USB_PHY_VBUS_WAKEUP_ID 0x408 +#define VDAT_DET_INT_EN (1 << 16) +#define VDAT_DET_CHG_DET (1 << 17) +#define VDAT_DET_STS (1 << 18) +#define USB_ID_STATUS (1 << 2) + +#define ULPIS2S_CTRL 0x418 +#define ULPIS2S_ENA (1 << 0) +#define ULPIS2S_SUPPORT_DISCONNECT (1 << 2) +#define ULPIS2S_PLLU_MASTER_BLASTER60 (1 << 3) +#define ULPIS2S_SPARE(x) (((x) & 0xF) << 8) +#define ULPIS2S_FORCE_ULPI_CLK_OUT (1 << 12) +#define ULPIS2S_DISCON_DONT_CHECK_SE0 (1 << 13) +#define ULPIS2S_SUPPORT_HS_KEEP_ALIVE (1 << 14) +#define ULPIS2S_DISABLE_STP_PU (1 << 15) +#define ULPIS2S_SLV0_CLAMP_XMIT (1 << 16) + +#define ULPI_TIMING_CTRL_0 0x424 +#define ULPI_CLOCK_OUT_DELAY(x) ((x) & 0x1F) +#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) +#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) +#define ULPI_SHADOW_CLK_LOOPBACK_EN (1 << 12) +#define ULPI_SHADOW_CLK_SEL (1 << 13) +#define ULPI_CORE_CLK_SEL (1 << 14) +#define ULPI_SHADOW_CLK_DELAY(x) (((x) & 0x1F) << 16) +#define ULPI_LBK_PAD_EN (1 << 26) +#define ULPI_LBK_PAD_E_INPUT_OR (1 << 27) +#define ULPI_CLK_OUT_ENA (1 << 28) +#define ULPI_CLK_PADOUT_ENA (1 << 29) + +#define ULPI_TIMING_CTRL_1 0x428 +#define ULPI_DATA_TRIMMER_LOAD (1 << 0) +#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) +#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) +#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) +#define ULPI_DIR_TRIMMER_LOAD (1 << 24) +#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) + +#define UTMIP_XCVR_CFG0 0x808 +#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0) +#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8) +#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10) +#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) +#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) +#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) +#define UTMIP_XCVR_LSBIAS_SEL (1 << 21) +#define UTMIP_XCVR_SETUP_MSB(x) (((x) & 0x7) << 22) +#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) +#define UTMIP_XCVR_MAX_OFFSET 2 +#define UTMIP_XCVR_SETUP_MAX_VALUE 0x7f +#define UTMIP_XCVR_SETUP_MIN_VALUE 0 +#define XCVR_SETUP_MSB_CALIB(x) ((x) >> 4) + +#define UTMIP_BIAS_CFG0 0x80c +#define UTMIP_OTGPD (1 << 11) +#define UTMIP_BIASPD (1 << 10) +#define UTMIP_HSSQUELCH_LEVEL(x) (((x) & 0x3) << 0) +#define UTMIP_HSDISCON_LEVEL(x) (((x) & 0x3) << 2) +#define UTMIP_HSDISCON_LEVEL_MSB (1 << 24) + +#define UTMIP_HSRX_CFG0 0x810 +#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) +#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15) + +#define UTMIP_HSRX_CFG1 0x814 +#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) + +#define UTMIP_TX_CFG0 0x820 +#define UTMIP_FS_PREABMLE_J (1 << 19) +#define UTMIP_HS_DISCON_DISABLE (1 << 8) + +#define UTMIP_DEBOUNCE_CFG0 0x82c +#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0) + +#define UTMIP_BAT_CHRG_CFG0 0x830 +#define UTMIP_PD_CHRG (1 << 0) +#define UTMIP_ON_SINK_EN (1 << 2) +#define UTMIP_OP_SRC_EN (1 << 3) + +#define UTMIP_XCVR_CFG1 0x838 +#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) +#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) +#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18) + +#define UTMIP_BIAS_CFG1 0x83c +#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) +#define UTMIP_BIAS_PDTRK_POWERDOWN (1 << 0) +#define UTMIP_BIAS_PDTRK_POWERUP (1 << 1) + +#define UTMIP_MISC_CFG0 0x824 +#define UTMIP_DPDM_OBSERVE (1 << 26) +#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27) +#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf) +#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc) +#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) +#define FORCE_PULLDN_DM (1 << 8) +#define FORCE_PULLDN_DP (1 << 9) +#define COMB_TERMS (1 << 0) +#define ALWAYS_FREE_RUNNING_TERMS (1 << 1) + +#define UTMIP_SPARE_CFG0 0x834 +#define FUSE_SETUP_SEL (1 << 3) +#define FUSE_ATERM_SEL (1 << 4) + +#define UTMIP_PMC_WAKEUP0 0x84c +#define EVENT_INT_ENB (1 << 0) + +#define UTMIP_BIAS_STS0 0x840 +#define UTMIP_RCTRL_VAL(x) (((x) & 0xffff) << 0) +#define UTMIP_TCTRL_VAL(x) (((x) & (0xffff << 16)) >> 16) + +#define UHSIC_PLL_CFG1 0xc04 +#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14) + +#define UHSIC_HSRX_CFG0 0xc08 +#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2) +#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8) +#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13) + +#define UHSIC_HSRX_CFG1 0xc0c +#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) + +#define UHSIC_TX_CFG0 0xc10 +#define UHSIC_HS_READY_WAIT_FOR_VALID (1 << 9) +#define UHSIC_MISC_CFG0 0xc14 +#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7) +#define UHSIC_DETECT_SHORT_CONNECT (1 << 8) +#define UHSIC_FORCE_XCVR_MODE (1 << 15) +#define UHSIC_DISABLE_BUSRESET (1 << 20) +#define UHSIC_MISC_CFG1 0xc18 +#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2) + +#define UHSIC_PADS_CFG0 0xc1c +#define UHSIC_TX_RTUNEN 0xf000 +#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12) + +#define UHSIC_PADS_CFG1 0xc20 +#define UHSIC_PD_BG (1 << 2) +#define UHSIC_PD_TX (1 << 3) +#define UHSIC_PD_TRK (1 << 4) +#define UHSIC_PD_RX (1 << 5) +#define UHSIC_PD_ZI (1 << 6) +#define UHSIC_RX_SEL (1 << 7) +#define UHSIC_RPD_DATA (1 << 9) +#define UHSIC_RPD_STROBE (1 << 10) +#define UHSIC_RPU_DATA (1 << 11) +#define UHSIC_RPU_STROBE (1 << 12) + +#define UHSIC_STAT_CFG0 0xc28 +#define UHSIC_CONNECT_DETECT (1 << 0) + +#define PMC_USB_DEBOUNCE 0xec +#define UTMIP_LINE_DEB_CNT(x) (((x) & 0xf) << 16) + +#define PMC_USB_AO 0xf0 +#define PMC_POWER_DOWN_MASK 0xffff +#define HSIC_RESERVED_P0 (3 << 14) +#define HSIC_STOBE_VAL_PD_P0 (1 << 13) +#define HSIC_DATA_VAL_PD_P0 (1 << 12) +#define USB_ID_PD(inst) (1 << ((4*(inst))+3)) +#define VBUS_WAKEUP_PD(inst) (1 << ((4*(inst))+2)) +#define USBON_VAL_PD(inst) (1 << ((4*(inst))+1)) +#define USBON_VAL_PD_P2 (1 << 9) +#define USBON_VAL_PD_P1 (1 << 5) +#define USBON_VAL_PD_P0 (1 << 1) +#define USBOP_VAL_PD(inst) (1 << (4*(inst))) +#define USBOP_VAL_PD_P2 (1 << 8) +#define USBOP_VAL_PD_P1 (1 << 4) +#define USBOP_VAL_PD_P0 (1 << 0) +#define PMC_USB_AO_PD_P2 (0xf << 8) +#define PMC_USB_AO_ID_PD_P0 (1 << 3) +#define PMC_USB_AO_VBUS_WAKEUP_PD_P0 (1 << 2) + +#define PMC_TRIGGERS 0x1ec +#define UTMIP_CLR_WALK_PTR(inst) (1 << (inst)) +#define UTMIP_CLR_WALK_PTR_P2 (1 << 2) +#define UTMIP_CLR_WALK_PTR_P1 (1 << 1) +#define UTMIP_CLR_WALK_PTR_P0 (1 << 0) +#define UTMIP_CAP_CFG(inst) (1 << ((inst)+4)) +#define UTMIP_CAP_CFG_P2 (1 << 6) +#define UTMIP_CAP_CFG_P1 (1 << 5) +#define UTMIP_CAP_CFG_P0 (1 << 4) +#define UTMIP_CLR_WAKE_ALARM(inst) (1 << ((inst)+12)) +#define UTMIP_CLR_WAKE_ALARM_P2 (1 << 14) + +#define PMC_PAD_CFG (0x1f4) + +#define PMC_UTMIP_TERM_PAD_CFG 0x1f8 +#define PMC_TCTRL_VAL(x) (((x) & 0x1f) << 5) +#define PMC_RCTRL_VAL(x) (((x) & 0x1f) << 0) + +#define UHSIC_SLEEPWALK_REG 0x210 +#define UHSIC_DATA_RPD_D (1 << 25) +#define UHSIC_STRB_RPD_D (1 << 24) +#define UHSIC_DATA_RPD_C (1 << 17) +#define UHSIC_STRB_RPD_C (1 << 16) +#define UHSIC_DATA_RPD_B (1 << 9) +#define UHSIC_STRB_RPD_B (1 << 8) +#define UHSIC_DATA_RPD_A (1 << 1) +#define UHSIC_STRB_RPD_A (1 << 0) + +#define PMC_SLEEP_CFG 0x1fc +#define UTMIP_TCTRL_USE_PMC(inst) (1 << ((8*(inst))+3)) +#define UTMIP_TCTRL_USE_PMC_P2 (1 << 19) +#define UTMIP_TCTRL_USE_PMC_P1 (1 << 11) +#define UTMIP_TCTRL_USE_PMC_P0 (1 << 3) +#define UTMIP_RCTRL_USE_PMC(inst) (1 << ((8*(inst))+2)) +#define UTMIP_RCTRL_USE_PMC_P2 (1 << 18) +#define UTMIP_RCTRL_USE_PMC_P1 (1 << 10) +#define UTMIP_RCTRL_USE_PMC_P0 (1 << 2) +#define UTMIP_FSLS_USE_PMC(inst) (1 << ((8*(inst))+1)) +#define UTMIP_FSLS_USE_PMC_P2 (1 << 17) +#define UTMIP_FSLS_USE_PMC_P1 (1 << 9) +#define UTMIP_FSLS_USE_PMC_P0 (1 << 1) +#define UTMIP_MASTER_ENABLE(inst) (1 << (8*(inst))) +#define UTMIP_MASTER_ENABLE_P2 (1 << 16) +#define UTMIP_MASTER_ENABLE_P1 (1 << 8) +#define UTMIP_MASTER_ENABLE_P0 (1 << 0) +#define UHSIC_MASTER_ENABLE_P0 (1 << 24) +#define UHSIC_WAKE_VAL_P0(x) (((x) & 0xf) << 28) + +#define PMC_SLEEPWALK_CFG 0x200 +#define UTMIP_LINEVAL_WALK_EN(inst) (1 << ((8*(inst))+7)) +#define UTMIP_LINEVAL_WALK_EN_P2 (1 << 23) +#define UTMIP_LINEVAL_WALK_EN_P1 (1 << 15) +#define UTMIP_LINEVAL_WALK_EN_P0 (1 << 7) +#define UTMIP_WAKE_VAL(inst, x) (((x) & 0xf) << ((8*(inst))+4)) +#define UTMIP_WAKE_VAL_P2(x) (((x) & 0xf) << 20) +#define UTMIP_WAKE_VAL_P1(x) (((x) & 0xf) << 12) +#define UTMIP_WAKE_VAL_P0(x) (((x) & 0xf) << 4) +#define WAKE_VAL_NONE 0xc +#define WAKE_VAL_ANY 0xF +#define WAKE_VAL_FSJ 0x2 +#define WAKE_VAL_FSK 0x1 +#define WAKE_VAL_SE0 0x0 + +#define PMC_SLEEPWALK_REG(inst) (0x204 + (4*(inst))) +#define UTMIP_USBOP_RPD_A (1 << 0) +#define UTMIP_USBON_RPD_A (1 << 1) +#define UTMIP_AP_A (1 << 4) +#define UTMIP_AN_A (1 << 5) +#define UTMIP_HIGHZ_A (1 << 6) +#define UTMIP_USBOP_RPD_B (1 << 8) +#define UTMIP_USBON_RPD_B (1 << 9) +#define UTMIP_AP_B (1 << 12) +#define UTMIP_AN_B (1 << 13) +#define UTMIP_HIGHZ_B (1 << 14) +#define UTMIP_USBOP_RPD_C (1 << 16) +#define UTMIP_USBON_RPD_C (1 << 17) +#define UTMIP_AP_C (1 << 20) +#define UTMIP_AN_C (1 << 21) +#define UTMIP_HIGHZ_C (1 << 22) +#define UTMIP_USBOP_RPD_D (1 << 24) +#define UTMIP_USBON_RPD_D (1 << 25) +#define UTMIP_AP_D (1 << 28) +#define UTMIP_AN_D (1 << 29) +#define UTMIP_HIGHZ_D (1 << 30) + +#define UTMIP_UHSIC_STATUS 0x214 +#define UTMIP_WALK_PTR_VAL(inst) (0x3 << ((inst)*2)) +#define UTMIP_USBOP_VAL(inst) (1 << ((2*(inst)) + 8)) +#define UTMIP_USBOP_VAL_P2 (1 << 12) +#define UTMIP_USBOP_VAL_P1 (1 << 10) +#define UTMIP_USBOP_VAL_P0 (1 << 8) +#define UTMIP_USBON_VAL(inst) (1 << ((2*(inst)) + 9)) +#define UTMIP_USBON_VAL_P2 (1 << 13) +#define UTMIP_USBON_VAL_P1 (1 << 11) +#define UTMIP_USBON_VAL_P0 (1 << 9) +#define UTMIP_WAKE_ALARM(inst) (1 << ((inst) + 16)) +#define UTMIP_WAKE_ALARM_P2 (1 << 18) +#define UTMIP_WAKE_ALARM_P1 (1 << 17) +#define UTMIP_WAKE_ALARM_P0 (1 << 16) +#define UTMIP_WALK_PTR(inst) (1 << ((inst)*2)) +#define UTMIP_WALK_PTR_P2 (1 << 4) +#define UTMIP_WALK_PTR_P1 (1 << 2) +#define UTMIP_WALK_PTR_P0 (1 << 0) + +#define USB1_PREFETCH_ID 6 +#define USB2_PREFETCH_ID 18 +#define USB3_PREFETCH_ID 17 + +#define PMC_UTMIP_UHSIC_FAKE 0x218 +#define USBON_VAL(inst) (1 << ((4*(inst))+1)) +#define USBON_VAL_P2 (1 << 9) +#define USBON_VAL_P1 (1 << 5) +#define USBON_VAL_P0 (1 << 1) +#define USBOP_VAL(inst) (1 << (4*(inst))) +#define USBOP_VAL_P2 (1 << 8) +#define USBOP_VAL_P1 (1 << 4) +#define USBOP_VAL_P0 (1 << 0) + +#define PMC_UTMIP_BIAS_MASTER_CNTRL 0x30c +#define BIAS_MASTER_PROG_VAL (1 << 1) + +#define PMC_UTMIP_MASTER_CONFIG 0x310 +#define UTMIP_PWR(inst) (1 << (inst)) + +#define FUSE_USB_CALIB_0 0x1F0 +#define FUSE_USB_CALIB_XCVR_SETUP(x) (((x) & 0x7F) << 0) + +/* These values (in milli second) are taken from the battery charging spec */ +#define TDP_SRC_ON_MS 100 +#define TDPSRC_CON_MS 40 + +#ifdef DEBUG +#define DBG(stuff...) pr_info("tegra3_usb_phy: " stuff) +#else +#define DBG(stuff...) do {} while (0) +#endif + +#if 0 +#define PHY_DBG(stuff...) pr_info("tegra3_usb_phy: " stuff) +#else +#define PHY_DBG(stuff...) do {} while (0) +#endif + +static u32 utmip_rctrl_val, utmip_tctrl_val; +static DEFINE_SPINLOCK(utmip_pad_lock); +static int utmip_pad_count; + +static struct tegra_xtal_freq utmip_freq_table[] = { + { + .freq = 12000000, + .enable_delay = 0x02, + .stable_count = 0x2F, + .active_delay = 0x04, + .xtal_freq_count = 0x76, + .debounce = 0x7530, + .pdtrk_count = 5, + }, + { + .freq = 13000000, + .enable_delay = 0x02, + .stable_count = 0x33, + .active_delay = 0x05, + .xtal_freq_count = 0x7F, + .debounce = 0x7EF4, + .pdtrk_count = 5, + }, + { + .freq = 19200000, + .enable_delay = 0x03, + .stable_count = 0x4B, + .active_delay = 0x06, + .xtal_freq_count = 0xBB, + .debounce = 0xBB80, + .pdtrk_count = 7, + }, + { + .freq = 26000000, + .enable_delay = 0x04, + .stable_count = 0x66, + .active_delay = 0x09, + .xtal_freq_count = 0xFE, + .debounce = 0xFDE8, + .pdtrk_count = 9, + }, +}; + +static struct tegra_xtal_freq uhsic_freq_table[] = { + { + .freq = 12000000, + .enable_delay = 0x02, + .stable_count = 0x2F, + .active_delay = 0x0, + .xtal_freq_count = 0x1CA, + }, + { + .freq = 13000000, + .enable_delay = 0x02, + .stable_count = 0x33, + .active_delay = 0x0, + .xtal_freq_count = 0x1F0, + }, + { + .freq = 19200000, + .enable_delay = 0x03, + .stable_count = 0x4B, + .active_delay = 0x0, + .xtal_freq_count = 0x2DD, + }, + { + .freq = 26000000, + .enable_delay = 0x04, + .stable_count = 0x66, + .active_delay = 0x0, + .xtal_freq_count = 0x3E0, + }, +}; + +static void usb_phy_fence_read(struct tegra_usb_phy *phy) +{ + /* Fence read for coherency of AHB master intiated writes */ + if (phy->inst == 0) + readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); + else if (phy->inst == 1) + readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); + else if (phy->inst == 2) + readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); + + return; +} + +static void utmip_setup_pmc_wake_detect(struct tegra_usb_phy *phy) +{ + unsigned long val, pmc_pad_cfg_val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + unsigned int inst = phy->inst; + void __iomem *base = phy->regs; + bool port_connected; + enum usb_phy_port_speed port_speed; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + /* check for port connect status */ + val = readl(base + USB_PORTSC); + port_connected = val & USB_PORTSC_CCS; + + if (!port_connected) + return; + + port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) & + HOSTPC1_DEVLC_PSPD_MASK; + /*Set PMC MASTER bits to do the following + * a. Take over the UTMI drivers + * b. set up such that it will take over resume + * if remote wakeup is detected + * Prepare PMC to take over suspend-wake detect-drive resume until USB + * controller ready + */ + + /* disable master enable in PMC */ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UTMIP_MASTER_ENABLE(inst); + writel(val, pmc_base + PMC_SLEEP_CFG); + + /* UTMIP_PWR_PX=1 for power savings mode */ + val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); + val |= UTMIP_PWR(inst); + writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); + + /* config debouncer */ + val = readl(pmc_base + PMC_USB_DEBOUNCE); + val &= ~UTMIP_LINE_DEB_CNT(~0); + val |= UTMIP_LINE_DEB_CNT(4); + writel(val, pmc_base + PMC_USB_DEBOUNCE); + + /* Make sure nothing is happening on the line with respect to PMC */ + val = readl(pmc_base + PMC_UTMIP_UHSIC_FAKE); + val &= ~USBOP_VAL(inst); + val &= ~USBON_VAL(inst); + writel(val, pmc_base + PMC_UTMIP_UHSIC_FAKE); + + /* Make sure wake value for line is none */ + val = readl(pmc_base + PMC_SLEEPWALK_CFG); + val &= ~UTMIP_LINEVAL_WALK_EN(inst); + writel(val, pmc_base + PMC_SLEEPWALK_CFG); + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UTMIP_WAKE_VAL(inst, ~0); + val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); + writel(val, pmc_base + PMC_SLEEP_CFG); + + /* turn off pad detectors */ + val = readl(pmc_base + PMC_USB_AO); + val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); + writel(val, pmc_base + PMC_USB_AO); + + /* Remove fake values and make synchronizers work a bit */ + val = readl(pmc_base + PMC_UTMIP_UHSIC_FAKE); + val &= ~USBOP_VAL(inst); + val &= ~USBON_VAL(inst); + writel(val, pmc_base + PMC_UTMIP_UHSIC_FAKE); + + /* Enable which type of event can trigger a walk, + in this case usb_line_wake */ + val = readl(pmc_base + PMC_SLEEPWALK_CFG); + val |= UTMIP_LINEVAL_WALK_EN(inst); + writel(val, pmc_base + PMC_SLEEPWALK_CFG); + + /* Enable which type of event can trigger a walk, + * in this case usb_line_wake */ + val = readl(pmc_base + PMC_SLEEPWALK_CFG); + val |= UTMIP_LINEVAL_WALK_EN(inst); + writel(val, pmc_base + PMC_SLEEPWALK_CFG); + + /* Clear the walk pointers and wake alarm */ + val = readl(pmc_base + PMC_TRIGGERS); + val |= UTMIP_CLR_WAKE_ALARM(inst) | UTMIP_CLR_WALK_PTR(inst); + writel(val, pmc_base + PMC_TRIGGERS); + + + /* Capture FS/LS pad configurations */ + pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG); + val = readl(pmc_base + PMC_TRIGGERS); + val |= UTMIP_CAP_CFG(inst); + writel(val, pmc_base + PMC_TRIGGERS); + udelay(1); + pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG); + + /* BIAS MASTER_ENABLE=0 */ + val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + val &= ~BIAS_MASTER_PROG_VAL; + writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + + /* program walk sequence, maintain a J, followed by a driven K + * to signal a resume once an wake event is detected */ + val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); + val &= ~UTMIP_AP_A; + val |= UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_AN_A |UTMIP_HIGHZ_A | + UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_AP_B | UTMIP_AN_B | + UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_AP_C | UTMIP_AN_C | + UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_AP_D | UTMIP_AN_D; + writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); + + if (port_speed == USB_PHY_PORT_SPEED_LOW) { + val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); + val &= ~(UTMIP_AN_B | UTMIP_HIGHZ_B | UTMIP_AN_C | + UTMIP_HIGHZ_C | UTMIP_AN_D | UTMIP_HIGHZ_D); + writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); + } else { + val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); + val &= ~(UTMIP_AP_B | UTMIP_HIGHZ_B | UTMIP_AP_C | + UTMIP_HIGHZ_C | UTMIP_AP_D | UTMIP_HIGHZ_D); + writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); + } + + /* turn on pad detectors */ + val = readl(pmc_base + PMC_USB_AO); + val &= ~(USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); + writel(val, pmc_base + PMC_USB_AO); + + /* Add small delay before usb detectors provide stable line values */ + mdelay(1); + + /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ + val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); + val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); + writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); + + phy->remote_wakeup = false; + + /* Turn over pad configuration to PMC for line wake events*/ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UTMIP_WAKE_VAL(inst, ~0); + val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_ANY); + val |= UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst); + val |= UTMIP_MASTER_ENABLE(inst) | UTMIP_FSLS_USE_PMC(inst); + writel(val, pmc_base + PMC_SLEEP_CFG); + + val = readl(base + UTMIP_PMC_WAKEUP0); + val |= EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + PHY_DBG("%s ENABLE_PMC inst = %d\n", __func__, inst); +} + +static void utmip_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + unsigned int inst = phy->inst; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UTMIP_WAKE_VAL(inst, 0xF); + val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); + writel(val, pmc_base + PMC_SLEEP_CFG); + + val = readl(pmc_base + PMC_TRIGGERS); + val |= UTMIP_CLR_WAKE_ALARM(inst) | UTMIP_CLR_WALK_PTR(inst); + writel(val, pmc_base + PMC_TRIGGERS); + + val = readl(base + UTMIP_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + + /* Disable PMC master mode by clearing MASTER_EN */ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~(UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | + UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst)); + writel(val, pmc_base + PMC_SLEEP_CFG); + + val = readl(pmc_base + PMC_TRIGGERS); + val &= ~UTMIP_CAP_CFG(inst); + writel(val, pmc_base + PMC_TRIGGERS); + + /* turn off pad detectors */ + val = readl(pmc_base + PMC_USB_AO); + val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); + writel(val, pmc_base + PMC_USB_AO); + + phy->remote_wakeup = false; + PHY_DBG("%s DISABLE_PMC inst = %d\n", __func__, inst); +} + +bool utmi_phy_remotewake_detected(struct tegra_usb_phy *phy) +{ + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + void __iomem *base = phy->regs; + unsigned int inst = phy->inst; + u32 val; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + UTMIP_PMC_WAKEUP0); + if (val & EVENT_INT_ENB) { + val = readl(pmc_base + UTMIP_UHSIC_STATUS); + if (UTMIP_WAKE_ALARM(inst) & val) { + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UTMIP_WAKE_VAL(inst, 0xF); + val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); + writel(val, pmc_base + PMC_SLEEP_CFG); + + val = readl(pmc_base + PMC_TRIGGERS); + val |= UTMIP_CLR_WAKE_ALARM(inst) | + UTMIP_CLR_WALK_PTR(inst); + writel(val, pmc_base + PMC_TRIGGERS); + + val = readl(base + UTMIP_PMC_WAKEUP0); + val &= ~EVENT_INT_ENB; + writel(val, base + UTMIP_PMC_WAKEUP0); + phy->remote_wakeup = true; + return true; + } + } + return false; +} + +static void utmi_phy_enable_trking_data(struct tegra_usb_phy *phy) +{ + void __iomem *base = IO_ADDRESS(TEGRA_USB_BASE); + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + static bool init_done = false; + u32 val; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + /* Should be done only once after system boot */ + if (init_done) + return; + + clk_enable(phy->utmi_pad_clk); + /* Bias pad MASTER_ENABLE=1 */ + val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + val |= BIAS_MASTER_PROG_VAL; + writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + + /* Setting the tracking length time */ + val = readl(base + UTMIP_BIAS_CFG1); + val &= ~UTMIP_BIAS_PDTRK_COUNT(~0); + val |= UTMIP_BIAS_PDTRK_COUNT(5); + writel(val, base + UTMIP_BIAS_CFG1); + + /* Bias PDTRK is Shared and MUST be done from USB1 ONLY, PD_TRK=0 */ + val = readl(base + UTMIP_BIAS_CFG1); + val &= ~UTMIP_BIAS_PDTRK_POWERDOWN; + writel(val, base + UTMIP_BIAS_CFG1); + + val = readl(base + UTMIP_BIAS_CFG1); + val |= UTMIP_BIAS_PDTRK_POWERUP; + writel(val, base + UTMIP_BIAS_CFG1); + + /* Wait for 25usec */ + udelay(25); + + /* Bias pad MASTER_ENABLE=0 */ + val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + val &= ~BIAS_MASTER_PROG_VAL; + writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + + /* Wait for 1usec */ + udelay(1); + + /* Bias pad MASTER_ENABLE=1 */ + val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + val |= BIAS_MASTER_PROG_VAL; + writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); + + /* Read RCTRL and TCTRL from UTMIP space */ + val = readl(base + UTMIP_BIAS_STS0); + utmip_rctrl_val = ffz(UTMIP_RCTRL_VAL(val)); + utmip_tctrl_val = ffz(UTMIP_TCTRL_VAL(val)); + + /* PD_TRK=1 */ + val = readl(base + UTMIP_BIAS_CFG1); + val |= UTMIP_BIAS_PDTRK_POWERDOWN; + writel(val, base + UTMIP_BIAS_CFG1); + + /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ + val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); + val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); + writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); + clk_disable(phy->utmi_pad_clk); + init_done = true; +} + +static void utmip_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + unsigned int inst = phy->inst; + + /* power down UTMIP interfaces */ + val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); + val |= UTMIP_PWR(inst); + writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); + + /* setup sleep walk usb controller */ + val = UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_HIGHZ_A | + UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_HIGHZ_B | + UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_HIGHZ_C | + UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_HIGHZ_D; + writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); + + /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ + val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); + val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); + writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); + + /* Turn over pad configuration to PMC */ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UTMIP_WAKE_VAL(inst, ~0); + val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE) | + UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | + UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst); + writel(val, pmc_base + PMC_SLEEP_CFG); + PHY_DBG("%s ENABLE_PMC inst = %d\n", __func__, inst); +} + +static void utmip_powerup_pmc_wake_detect(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + unsigned int inst = phy->inst; + + /* Disable PMC master mode by clearing MASTER_EN */ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~(UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | + UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst)); + writel(val, pmc_base + PMC_SLEEP_CFG); + mdelay(1); + PHY_DBG("%s DISABLE_PMC inst = %d\n", __func__, inst); +} + +static void uhsic_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + + /* turn on pad detectors for HSIC*/ + val = readl(pmc_base + PMC_USB_AO); + val |= (HSIC_RESERVED_P0 | HSIC_STOBE_VAL_PD_P0 | HSIC_DATA_VAL_PD_P0); + writel(val, pmc_base + PMC_USB_AO); + + /* enable pull downs on HSIC PMC */ + val = UHSIC_STRB_RPD_A | UHSIC_DATA_RPD_A | UHSIC_STRB_RPD_B | + UHSIC_DATA_RPD_B | UHSIC_STRB_RPD_C | UHSIC_DATA_RPD_C | + UHSIC_STRB_RPD_D | UHSIC_DATA_RPD_D; + writel(val, pmc_base + UHSIC_SLEEPWALK_REG); + + /* Turn over pad configuration to PMC */ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UHSIC_WAKE_VAL_P0(~0); + val |= UHSIC_WAKE_VAL_P0(WAKE_VAL_NONE) | UHSIC_MASTER_ENABLE_P0; + writel(val, pmc_base + PMC_SLEEP_CFG); +} + +static void uhsic_powerup_pmc_wake_detect(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + + /* turn on pad detectors for HSIC*/ + val = readl(pmc_base + PMC_USB_AO); + val &= ~(HSIC_RESERVED_P0 | HSIC_STOBE_VAL_PD_P0 | HSIC_DATA_VAL_PD_P0); + writel(val, pmc_base + PMC_USB_AO); + + /* Disable PMC master mode by clearing MASTER_EN */ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~(UHSIC_MASTER_ENABLE_P0); + writel(val, pmc_base + PMC_SLEEP_CFG); + mdelay(1); +} + +static void usb_phy_power_down_pmc(void) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + + /* power down all 3 UTMIP interfaces */ + val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); + val |= UTMIP_PWR(0) | UTMIP_PWR(1) | UTMIP_PWR(2); + writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); + + /* turn on pad detectors */ + writel(PMC_POWER_DOWN_MASK, pmc_base + PMC_USB_AO); + + /* setup sleep walk fl all 3 usb controllers */ + val = UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_HIGHZ_A | + UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_HIGHZ_B | + UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_HIGHZ_C | + UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_HIGHZ_D; + writel(val, pmc_base + PMC_SLEEPWALK_REG(0)); + writel(val, pmc_base + PMC_SLEEPWALK_REG(1)); + writel(val, pmc_base + PMC_SLEEPWALK_REG(2)); + + /* enable pull downs on HSIC PMC */ + val = UHSIC_STRB_RPD_A | UHSIC_DATA_RPD_A | UHSIC_STRB_RPD_B | + UHSIC_DATA_RPD_B | UHSIC_STRB_RPD_C | UHSIC_DATA_RPD_C | + UHSIC_STRB_RPD_D | UHSIC_DATA_RPD_D; + writel(val, pmc_base + UHSIC_SLEEPWALK_REG); + + /* Turn over pad configuration to PMC */ + val = readl(pmc_base + PMC_SLEEP_CFG); + val &= ~UTMIP_WAKE_VAL(0, ~0); + val &= ~UTMIP_WAKE_VAL(1, ~0); + val &= ~UTMIP_WAKE_VAL(2, ~0); + val &= ~UHSIC_WAKE_VAL_P0(~0); + val |= UTMIP_WAKE_VAL(0, WAKE_VAL_NONE) | UHSIC_WAKE_VAL_P0(WAKE_VAL_NONE) | + UTMIP_WAKE_VAL(1, WAKE_VAL_NONE) | UTMIP_WAKE_VAL(2, WAKE_VAL_NONE) | + UTMIP_RCTRL_USE_PMC(0) | UTMIP_RCTRL_USE_PMC(1) | UTMIP_RCTRL_USE_PMC(2) | + UTMIP_TCTRL_USE_PMC(0) | UTMIP_TCTRL_USE_PMC(1) | UTMIP_TCTRL_USE_PMC(2) | + UTMIP_FSLS_USE_PMC(0) | UTMIP_FSLS_USE_PMC(1) | UTMIP_FSLS_USE_PMC(2) | + UTMIP_MASTER_ENABLE(0) | UTMIP_MASTER_ENABLE(1) | UTMIP_MASTER_ENABLE(2) | + UHSIC_MASTER_ENABLE_P0; + writel(val, pmc_base + PMC_SLEEP_CFG); +} + +static int usb_phy_bringup_host_controller(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + PHY_DBG("[%d] USB_USBSTS[0x%x] USB_PORTSC[0x%x] port_speed[%d]\n", __LINE__, + readl(base + USB_USBSTS), readl(base + USB_PORTSC), + phy->port_speed); + + /* Device is plugged in when system is in LP0 */ + /* Bring up the controller from LP0*/ + val = readl(base + USB_USBCMD); + val |= USB_CMD_RESET; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, + USB_CMD_RESET, 0, 2500) < 0) { + pr_err("%s: timeout waiting for reset\n", __func__); + } + + val = readl(base + USB_USBMODE); + val &= ~USB_USBMODE_MASK; + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE); + + val = readl(base + HOSTPC1_DEVLC); + val &= ~HOSTPC1_DEVLC_PTS(~0); + val |= HOSTPC1_DEVLC_STS; + writel(val, base + HOSTPC1_DEVLC); + + /* Enable Port Power */ + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PP; + writel(val, base + USB_PORTSC); + udelay(10); + + /* Check if the phy resume from LP0. When the phy resume from LP0 + * USB register will be reset.to zero */ + if (!readl(base + USB_ASYNCLISTADDR)) { + /* Program the field PTC based on the saved speed mode */ + val = readl(base + USB_PORTSC); + val &= ~USB_PORTSC_PTC(~0); + if (phy->port_speed == USB_PHY_PORT_SPEED_HIGH) + val |= USB_PORTSC_PTC(5); + else if (phy->port_speed == USB_PHY_PORT_SPEED_FULL) + val |= USB_PORTSC_PTC(6); + else if (phy->port_speed == USB_PHY_PORT_SPEED_LOW) + val |= USB_PORTSC_PTC(7); + writel(val, base + USB_PORTSC); + udelay(10); + + /* Disable test mode by setting PTC field to NORMAL_OP */ + val = readl(base + USB_PORTSC); + val &= ~USB_PORTSC_PTC(~0); + writel(val, base + USB_PORTSC); + udelay(10); + } + + /* Poll until CCS is enabled */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_CCS, + USB_PORTSC_CCS, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_CCS\n", __func__); + } + + /* Poll until PE is enabled */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_PE, + USB_PORTSC_PE, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_PE\n", __func__); + } + + /* Clear the PCI status, to avoid an interrupt taken upon resume */ + val = readl(base + USB_USBSTS); + val |= USB_USBSTS_PCI; + writel(val, base + USB_USBSTS); + + if (!phy->remote_wakeup) { + /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ + val = readl(base + USB_PORTSC); + if ((val & USB_PORTSC_PP) && (val & USB_PORTSC_PE)) { + val |= USB_PORTSC_SUSP; + writel(val, base + USB_PORTSC); + /* Need a 4ms delay before the controller goes to suspend */ + mdelay(4); + + /* Wait until port suspend completes */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_SUSP, + USB_PORTSC_SUSP, 1000)) { + pr_err("%s: timeout waiting for PORT_SUSPEND\n", + __func__); + } + } + } + PHY_DBG("[%d] USB_USBSTS[0x%x] USB_PORTSC[0x%x] port_speed[%d]\n", __LINE__, + readl(base + USB_USBSTS), readl(base + USB_PORTSC), + phy->port_speed); + + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x]\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC)); + return 0; +} + +static void usb_phy_wait_for_sof(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + val = readl(base + USB_USBSTS); + writel(val, base + USB_USBSTS); + udelay(20); + /* wait for two SOFs */ + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_SRI, + USB_USBSTS_SRI, 2500)) + pr_err("%s: timeout waiting for SOF\n", __func__); + + val = readl(base + USB_USBSTS); + writel(val, base + USB_USBSTS); + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_SRI, 0, 2500)) + pr_err("%s: timeout waiting for SOF\n", __func__); + + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_SRI, + USB_USBSTS_SRI, 2500)) + pr_err("%s: timeout waiting for SOF\n", __func__); + + udelay(20); +} + +static unsigned int utmi_phy_xcvr_setup_value(struct tegra_usb_phy *phy) +{ + struct tegra_utmi_config *cfg = &phy->pdata->u_cfg.utmi; + signed long val; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + if (cfg->xcvr_use_fuses) { + val = FUSE_USB_CALIB_XCVR_SETUP( + tegra_fuse_readl(FUSE_USB_CALIB_0)); + if (cfg->xcvr_setup_offset <= UTMIP_XCVR_MAX_OFFSET) + val = val + cfg->xcvr_setup_offset; + + if (val > UTMIP_XCVR_SETUP_MAX_VALUE) { + val = UTMIP_XCVR_SETUP_MAX_VALUE; + pr_info("%s: reset XCVR_SETUP to max value\n", + __func__); + } else if (val < UTMIP_XCVR_SETUP_MIN_VALUE) { + val = UTMIP_XCVR_SETUP_MIN_VALUE; + pr_info("%s: reset XCVR_SETUP to min value\n", + __func__); + } + } else { + val = cfg->xcvr_setup; + } + + return (unsigned int) val; +} + +static int utmi_phy_open(struct tegra_usb_phy *phy) +{ + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + unsigned long parent_rate, val; + int i; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + phy->utmi_pad_clk = clk_get_sys("utmip-pad", NULL); + if (IS_ERR(phy->utmi_pad_clk)) { + pr_err("%s: can't get utmip pad clock\n", __func__); + return PTR_ERR(phy->utmi_pad_clk); + } + + phy->utmi_xcvr_setup = utmi_phy_xcvr_setup_value(phy); + + parent_rate = clk_get_rate(clk_get_parent(phy->pllu_clk)); + for (i = 0; i < ARRAY_SIZE(utmip_freq_table); i++) { + if (utmip_freq_table[i].freq == parent_rate) { + phy->freq = &utmip_freq_table[i]; + break; + } + } + if (!phy->freq) { + pr_err("invalid pll_u parent rate %ld\n", parent_rate); + return -EINVAL; + } + + /* Power-up the VBUS detector for UTMIP PHY */ + val = readl(pmc_base + PMC_USB_AO); + val &= ~(PMC_USB_AO_VBUS_WAKEUP_PD_P0 | PMC_USB_AO_ID_PD_P0); + writel((val | PMC_USB_AO_PD_P2), (pmc_base + PMC_USB_AO)); + + utmip_powerup_pmc_wake_detect(phy); + + return 0; +} + +static void utmi_phy_close(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s inst:[%d]\n", __func__, phy->inst); + + /* Disable PHY clock valid interrupts while going into suspend*/ + if (phy->pdata->u_data.host.hot_plug) { + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_PHY_CLK_VALID_INT_ENB; + writel(val, base + USB_SUSP_CTRL); + } + + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_WKCN; + writel(val, base + USB_PORTSC); + + clk_put(phy->utmi_pad_clk); +} + +static int utmi_phy_pad_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val, flags; + void __iomem *pad_base = IO_ADDRESS(TEGRA_USB_BASE); + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + clk_enable(phy->utmi_pad_clk); + + spin_lock_irqsave(&utmip_pad_lock, flags); + utmip_pad_count++; + + val = readl(pad_base + UTMIP_BIAS_CFG0); + val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); + val |= UTMIP_HSSQUELCH_LEVEL(0x2) | UTMIP_HSDISCON_LEVEL(0x1) | + UTMIP_HSDISCON_LEVEL_MSB; + writel(val, pad_base + UTMIP_BIAS_CFG0); + + spin_unlock_irqrestore(&utmip_pad_lock, flags); + + clk_disable(phy->utmi_pad_clk); + + return 0; +} + +static int utmi_phy_pad_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val, flags; + void __iomem *pad_base = IO_ADDRESS(TEGRA_USB_BASE); + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + clk_enable(phy->utmi_pad_clk); + spin_lock_irqsave(&utmip_pad_lock, flags); + + if (!utmip_pad_count) { + pr_err("%s: utmip pad already powered off\n", __func__); + goto out; + } + if (--utmip_pad_count == 0) { + val = readl(pad_base + UTMIP_BIAS_CFG0); + val |= UTMIP_OTGPD | UTMIP_BIASPD; + val &= ~(UTMIP_HSSQUELCH_LEVEL(~0) | UTMIP_HSDISCON_LEVEL(~0) | + UTMIP_HSDISCON_LEVEL_MSB); + writel(val, pad_base + UTMIP_BIAS_CFG0); + } +out: + spin_unlock_irqrestore(&utmip_pad_lock, flags); + clk_disable(phy->utmi_pad_clk); + + return 0; +} + +static int utmi_phy_irq(struct tegra_usb_phy *phy) +{ + void __iomem *base = phy->regs; + unsigned long val = 0; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x]\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC)); + DBG("USB_USBMODE[0x%x] USB_USBCMD[0x%x]\n", + readl(base + USB_USBMODE), readl(base + USB_USBCMD)); + + usb_phy_fence_read(phy); + /* check if there is any remote wake event */ + if (utmi_phy_remotewake_detected(phy)) + pr_info("%s: utmip remote wake detected\n", __func__); + + if (phy->pdata->u_data.host.hot_plug) { + val = readl(base + USB_SUSP_CTRL); + if ((val & USB_PHY_CLK_VALID_INT_STS)) { + val &= ~USB_PHY_CLK_VALID_INT_ENB | + USB_PHY_CLK_VALID_INT_STS; + writel(val , (base + USB_SUSP_CTRL)); + pr_info("%s: usb device plugged-in\n", __func__); + val = readl(base + USB_USBSTS); + if (!(val & USB_USBSTS_PCI)) + return IRQ_NONE; + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_WKCN | USB_PORTSC_RWC_BITS); + writel(val , (base + USB_PORTSC)); + } + } + + return IRQ_HANDLED; +} + +static void utmi_phy_enable_obs_bus(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + /* (2LS WAR)is not required for LS and FS devices and is only for HS */ + if ((phy->port_speed == USB_PHY_PORT_SPEED_LOW) || + (phy->port_speed == USB_PHY_PORT_SPEED_FULL)) { + /* do not enable the OBS bus */ + val = readl(base + UTMIP_MISC_CFG0); + val &= ~(UTMIP_DPDM_OBSERVE_SEL(~0)); + writel(val, base + UTMIP_MISC_CFG0); + DBG("%s(%d) Disable OBS bus\n", __func__, __LINE__); + return; + } + /* Force DP/DM pulldown active for Host mode */ + val = readl(base + UTMIP_MISC_CFG0); + val |= FORCE_PULLDN_DM | FORCE_PULLDN_DP | + COMB_TERMS | ALWAYS_FREE_RUNNING_TERMS; + writel(val, base + UTMIP_MISC_CFG0); + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); + if (phy->port_speed == USB_PHY_PORT_SPEED_LOW) + val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; + else + val |= UTMIP_DPDM_OBSERVE_SEL_FS_K; + writel(val, base + UTMIP_MISC_CFG0); + udelay(1); + + val = readl(base + UTMIP_MISC_CFG0); + val |= UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + udelay(10); + DBG("%s(%d) Enable OBS bus\n", __func__, __LINE__); + PHY_DBG("ENABLE_OBS_BUS\n"); +} + +static int utmi_phy_disable_obs_bus(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + /* check if OBS bus is already enabled */ + val = readl(base + UTMIP_MISC_CFG0); + if (val & UTMIP_DPDM_OBSERVE) { + PHY_DBG("DISABLE_OBS_BUS\n"); + /* Change the UTMIP OBS bus to drive SE0 */ + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); + val |= UTMIP_DPDM_OBSERVE_SEL_FS_SE0; + writel(val, base + UTMIP_MISC_CFG0); + + /* Wait for 3us(2 LS bit times) */ + udelay(3); + + /* Release UTMIP OBS bus */ + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + + /* Release DP/DM pulldown for Host mode */ + val = readl(base + UTMIP_MISC_CFG0); + val &= ~(FORCE_PULLDN_DM | FORCE_PULLDN_DP | + COMB_TERMS | ALWAYS_FREE_RUNNING_TERMS); + writel(val, base + UTMIP_MISC_CFG0); + + val = readl(base + USB_USBCMD); + val |= USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + if (usb_phy_reg_status_wait(base + USB_USBCMD, USB_USBCMD_RS, + USB_USBCMD_RS, 2000)) { + pr_err("%s: timeout waiting for USB_USBCMD_RS\n", __func__); + return -ETIMEDOUT; + } + } + return 0; +} + +static int utmi_phy_post_resume(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + unsigned int inst = phy->inst; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(pmc_base + PMC_SLEEP_CFG); + /* if PMC is not disabled by now then disable it */ + if (val & UTMIP_MASTER_ENABLE(inst)) { + utmip_phy_disable_pmc_bus_ctrl(phy); + } + + utmi_phy_disable_obs_bus(phy); + + return 0; +} + +static int utmi_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + void __iomem *base = phy->regs; + unsigned int inst = phy->inst; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + val = (readl(base + HOSTPC1_DEVLC) >> 25) & + HOSTPC1_DEVLC_PSPD_MASK; + if (val == USB_PHY_PORT_SPEED_HIGH) { + /* Disable interrupts */ + writel(0, base + USB_USBINTR); + /* Clear the run bit to stop SOFs - 2LS WAR */ + val = readl(base + USB_USBCMD); + val &= ~USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + } + + val = readl(pmc_base + PMC_SLEEP_CFG); + if (val & UTMIP_MASTER_ENABLE(inst)) { + if (!remote_wakeup) + utmip_phy_disable_pmc_bus_ctrl(phy); + } else { + utmi_phy_enable_obs_bus(phy); + } + + return 0; +} + +static int utmi_phy_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + PHY_DBG("%s(%d) inst:[%d] BEGIN\n", __func__, __LINE__, phy->inst); + if (!phy->phy_clk_on) { + PHY_DBG("%s(%d) inst:[%d] phy clk is already off\n", + __func__, __LINE__, phy->inst); + return 0; + } + + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + utmip_powerdown_pmc_wake_detect(phy); + + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0); + val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5); + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val |= UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + } else { + utmip_setup_pmc_wake_detect(phy); + } + + if (!phy->pdata->u_data.host.hot_plug) { + val = readl(base + UTMIP_XCVR_CFG0); + val |= (UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | + UTMIP_FORCE_PDZI_POWERDOWN); + writel(val, base + UTMIP_XCVR_CFG0); + } + + val = readl(base + UTMIP_XCVR_CFG1); + val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | + UTMIP_FORCE_PDDR_POWERDOWN; + writel(val, base + UTMIP_XCVR_CFG1); + + val = readl(base + UTMIP_BIAS_CFG1); + val |= UTMIP_BIAS_PDTRK_COUNT(0x5); + writel(val, base + UTMIP_BIAS_CFG1); + + utmi_phy_pad_power_off(phy); + + phy->port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) & + HOSTPC1_DEVLC_PSPD_MASK; + + if (phy->pdata->u_data.host.hot_plug) { + bool enable_hotplug = true; + /* if it is OTG port then make sure to enable hot-plug feature + only if host adaptor is connected, i.e id is low */ + if (phy->pdata->port_otg) { + val = readl(base + USB_PHY_VBUS_WAKEUP_ID); + enable_hotplug = (val & USB_ID_STATUS) ? false : true; + } + if (enable_hotplug) { + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_WKCN; + writel(val, base + USB_PORTSC); + + val = readl(base + USB_SUSP_CTRL); + val |= USB_PHY_CLK_VALID_INT_ENB; + writel(val, base + USB_SUSP_CTRL); + } else { + /* Disable PHY clock valid interrupts while going into suspend*/ + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_PHY_CLK_VALID_INT_ENB; + writel(val, base + USB_SUSP_CTRL); + } + } + + val = readl(base + HOSTPC1_DEVLC); + val |= HOSTPC1_DEVLC_PHCD; + writel(val, base + HOSTPC1_DEVLC); + + if (!phy->pdata->u_data.host.hot_plug) { + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + } + + phy->phy_clk_on = false; + phy->hw_accessible = false; + + PHY_DBG("%s(%d) inst:[%d] END\n", __func__, __LINE__, phy->inst); + + return 0; +} + + +static int utmi_phy_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + struct tegra_utmi_config *config = &phy->pdata->u_cfg.utmi; + + PHY_DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->phy_clk_on) { + PHY_DBG("%s(%d) inst:[%d] phy clk is already On\n", + __func__, __LINE__, phy->inst); + return 0; + } + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_TX_CFG0); + val |= UTMIP_FS_PREABMLE_J; + writel(val, base + UTMIP_TX_CFG0); + + val = readl(base + UTMIP_HSRX_CFG0); + val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0)); + val |= UTMIP_IDLE_WAIT(config->idle_wait_delay); + val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit); + writel(val, base + UTMIP_HSRX_CFG0); + + val = readl(base + UTMIP_HSRX_CFG1); + val &= ~UTMIP_HS_SYNC_START_DLY(~0); + val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay); + writel(val, base + UTMIP_HSRX_CFG1); + + val = readl(base + UTMIP_DEBOUNCE_CFG0); + val &= ~UTMIP_BIAS_DEBOUNCE_A(~0); + val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce); + writel(val, base + UTMIP_DEBOUNCE_CFG0); + + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE; + writel(val, base + UTMIP_MISC_CFG0); + + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + val = readl(base + USB_SUSP_CTRL); + val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV); + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val &= ~UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + } else { + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val |= UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + } + + utmi_phy_pad_power_on(phy); + + val = readl(base + UTMIP_XCVR_CFG0); + val &= ~(UTMIP_XCVR_LSBIAS_SEL | UTMIP_FORCE_PD_POWERDOWN | + UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN | + UTMIP_XCVR_SETUP(~0) | UTMIP_XCVR_LSFSLEW(~0) | + UTMIP_XCVR_LSRSLEW(~0) | UTMIP_XCVR_HSSLEW_MSB(~0)); + val |= UTMIP_XCVR_SETUP(phy->utmi_xcvr_setup); + val |= UTMIP_XCVR_SETUP_MSB(XCVR_SETUP_MSB_CALIB(phy->utmi_xcvr_setup)); + val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); + val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); + val |= UTMIP_XCVR_HSSLEW_MSB(0x8); + writel(val, base + UTMIP_XCVR_CFG0); + + val = readl(base + UTMIP_XCVR_CFG1); + val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | + UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0)); + val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj); + writel(val, base + UTMIP_XCVR_CFG1); + + val = readl(base + UTMIP_BIAS_CFG1); + val &= ~UTMIP_BIAS_PDTRK_COUNT(~0); + val |= UTMIP_BIAS_PDTRK_COUNT(phy->freq->pdtrk_count); + writel(val, base + UTMIP_BIAS_CFG1); + + val = readl(base + UTMIP_SPARE_CFG0); + val &= ~FUSE_SETUP_SEL; + val |= FUSE_ATERM_SEL; + writel(val, base + UTMIP_SPARE_CFG0); + + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + USB_SUSP_CTRL); + val &= ~UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + HOSTPC1_DEVLC); + val &= ~HOSTPC1_DEVLC_PHCD; + writel(val, base + HOSTPC1_DEVLC); + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, + USB_PHY_CLK_VALID, USB_PHY_CLK_VALID, 2500)) + pr_warn("%s: timeout waiting for phy to stabilize\n", __func__); + + utmi_phy_enable_trking_data(phy); + + if (phy->inst == 2) + writel(0, base + ICUSB_CTRL); + + val = readl(base + USB_USBMODE); + val &= ~USB_USBMODE_MASK; + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) + val |= USB_USBMODE_HOST; + else + val |= USB_USBMODE_DEVICE; + writel(val, base + USB_USBMODE); + + val = readl(base + HOSTPC1_DEVLC); + val &= ~HOSTPC1_DEVLC_PTS(~0); + val |= HOSTPC1_DEVLC_STS; + writel(val, base + HOSTPC1_DEVLC); + + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) + utmip_powerup_pmc_wake_detect(phy); + phy->phy_clk_on = true; + phy->hw_accessible = true; + PHY_DBG("%s(%d) End inst:[%d]\n", __func__, __LINE__, phy->inst); + return 0; +} + +static void utmi_phy_restore_start(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); + int inst = phy->inst; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(pmc_base + UTMIP_UHSIC_STATUS); + /* check whether we wake up from the remote resume */ + if (UTMIP_WALK_PTR_VAL(inst) & val) { + phy->remote_wakeup = true; + } else { + if (!((UTMIP_USBON_VAL(phy->inst) | + UTMIP_USBOP_VAL(phy->inst)) & val)) { + utmip_phy_disable_pmc_bus_ctrl(phy); + } + } + utmi_phy_enable_obs_bus(phy); +} + +static void utmi_phy_restore_end(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + int wait_time_us = 25000; /* FPR should be set by this time */ + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + /* check whether we wake up from the remote resume */ + if (phy->remote_wakeup) { + /* wait until SUSPEND and RESUME bit is cleared on remote resume */ + do { + val = readl(base + USB_PORTSC); + udelay(1); + if (wait_time_us == 0) { + PHY_DBG("%s PMC REMOTE WAKEUP FPR timeout val = 0x%x instance = %d\n", __func__, val, phy->inst); + utmip_phy_disable_pmc_bus_ctrl(phy); + utmi_phy_post_resume(phy); + return; + } + wait_time_us--; + } while (val & (USB_PORTSC_RESUME | USB_PORTSC_SUSP)); + + /* wait for 25 ms to port resume complete */ + msleep(25); + /* disable PMC master control */ + utmip_phy_disable_pmc_bus_ctrl(phy); + + /* Clear PCI and SRI bits to avoid an interrupt upon resume */ + val = readl(base + USB_USBSTS); + writel(val, base + USB_USBSTS); + /* wait to avoid SOF if there is any */ + if (usb_phy_reg_status_wait(base + USB_USBSTS, + USB_USBSTS_SRI, USB_USBSTS_SRI, 2500) < 0) { + pr_err("%s: timeout waiting for SOF\n", __func__); + } + utmi_phy_post_resume(phy); + } +} + +static int utmi_phy_resume(struct tegra_usb_phy *phy) +{ + int status = 0; + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) { + if (phy->port_speed < USB_PHY_PORT_SPEED_UNKNOWN) { + utmi_phy_restore_start(phy); + usb_phy_bringup_host_controller(phy); + utmi_phy_restore_end(phy); + } else { + /* device is plugged in when system is in LP0 */ + /* bring up the controller from LP0*/ + val = readl(base + USB_USBCMD); + val |= USB_CMD_RESET; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, + USB_CMD_RESET, 0, 2500) < 0) { + pr_err("%s: timeout waiting for reset\n", __func__); + } + + val = readl(base + USB_USBMODE); + val &= ~USB_USBMODE_MASK; + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE); + + val = readl(base + HOSTPC1_DEVLC); + val &= ~HOSTPC1_DEVLC_PTS(~0); + val |= HOSTPC1_DEVLC_STS; + writel(val, base + HOSTPC1_DEVLC); + + writel(USB_USBCMD_RS, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, + USB_USBCMD_RS, USB_USBCMD_RS, 2500) < 0) { + pr_err("%s: timeout waiting for run bit\n", __func__); + } + + /* Enable Port Power */ + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PP; + writel(val, base + USB_PORTSC); + udelay(10); + + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x]\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC)); + } + } + + return status; +} + +bool utmi_phy_charger_detect(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + bool status; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->pdata->op_mode != TEGRA_USB_OPMODE_DEVICE) { + /* Charger detection is not there for ULPI + * return Charger not available */ + return false; + } + + /* Enable charger detection logic */ + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val |= UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + + /* Source should be on for 100 ms as per USB charging spec */ + msleep(TDP_SRC_ON_MS); + + val = readl(base + USB_PHY_VBUS_WAKEUP_ID); + /* If charger is not connected disable the interrupt */ + val &= ~VDAT_DET_INT_EN; + val |= VDAT_DET_CHG_DET; + writel(val, base + USB_PHY_VBUS_WAKEUP_ID); + + val = readl(base + USB_PHY_VBUS_WAKEUP_ID); + if (val & VDAT_DET_STS) + status = true; + else + status = false; + + /* Disable charger detection logic */ + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val &= ~(UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN); + writel(val, base + UTMIP_BAT_CHRG_CFG0); + + /* Delay of 40 ms before we pull the D+ as per battery charger spec */ + msleep(TDPSRC_CON_MS); + + return status; +} + +static int uhsic_phy_open(struct tegra_usb_phy *phy) +{ + unsigned long parent_rate; + int i; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + parent_rate = clk_get_rate(clk_get_parent(phy->pllu_clk)); + for (i = 0; i < ARRAY_SIZE(uhsic_freq_table); i++) { + if (uhsic_freq_table[i].freq == parent_rate) { + phy->freq = &uhsic_freq_table[i]; + break; + } + } + if (!phy->freq) { + pr_err("invalid pll_u parent rate %ld\n", parent_rate); + return -EINVAL; + } + + utmip_powerup_pmc_wake_detect(phy); + + return 0; +} + +static int uhsic_phy_irq(struct tegra_usb_phy *phy) +{ + usb_phy_fence_read(phy); + return IRQ_HANDLED; +} + +static int uhsic_phy_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + struct tegra_hsic_config *config = &phy->pdata->u_cfg.hsic; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + utmip_powerup_pmc_wake_detect(phy); + + if (phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already On\n", + __func__, __LINE__, phy->inst); + return 0; + } + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~(UHSIC_PD_BG | UHSIC_PD_TX | UHSIC_PD_TRK | UHSIC_PD_RX | + UHSIC_PD_ZI | UHSIC_RPD_DATA | UHSIC_RPD_STROBE); + val |= UHSIC_RX_SEL; + writel(val, base + UHSIC_PADS_CFG1); + udelay(2); + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel(val, base + USB_SUSP_CTRL); + udelay(30); + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UHSIC_HSRX_CFG0); + val |= UHSIC_IDLE_WAIT(config->idle_wait_delay); + val |= UHSIC_ELASTIC_UNDERRUN_LIMIT(config->elastic_underrun_limit); + val |= UHSIC_ELASTIC_OVERRUN_LIMIT(config->elastic_overrun_limit); + writel(val, base + UHSIC_HSRX_CFG0); + + val = readl(base + UHSIC_HSRX_CFG1); + val |= UHSIC_HS_SYNC_START_DLY(config->sync_start_delay); + writel(val, base + UHSIC_HSRX_CFG1); + + /* WAR HSIC TX */ + val = readl(base + UHSIC_TX_CFG0); + val &= ~UHSIC_HS_READY_WAIT_FOR_VALID; + writel(val, base + UHSIC_TX_CFG0); + + val = readl(base + UHSIC_MISC_CFG0); + val |= UHSIC_SUSPEND_EXIT_ON_EDGE; + /* Disable generic bus reset, to allow AP30 specific bus reset*/ + val |= UHSIC_DISABLE_BUSRESET; + writel(val, base + UHSIC_MISC_CFG0); + + val = readl(base + UHSIC_MISC_CFG1); + val |= UHSIC_PLLU_STABLE_COUNT(phy->freq->stable_count); + writel(val, base + UHSIC_MISC_CFG1); + + val = readl(base + UHSIC_PLL_CFG1); + val |= UHSIC_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); + val |= UHSIC_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count); + writel(val, base + UHSIC_PLL_CFG1); + + val = readl(base + USB_SUSP_CTRL); + val &= ~(UHSIC_RESET); + writel(val, base + USB_SUSP_CTRL); + udelay(2); + + val = readl(base + USB_USBMODE); + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE); + + /* Change the USB controller PHY type to HSIC */ + val = readl(base + HOSTPC1_DEVLC); + val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK); + val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC); + val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK); + val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED); + writel(val, base + HOSTPC1_DEVLC); + + val = readl(base + USB_TXFILLTUNING); + if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) { + val = USB_FIFO_TXFILL_THRES(0x10); + writel(val, base + USB_TXFILLTUNING); + } + + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_WKOC | USB_PORTSC_WKDS | USB_PORTSC_WKCN); + writel(val, base + USB_PORTSC); + + val = readl(base + UHSIC_PADS_CFG0); + val &= ~(UHSIC_TX_RTUNEN); + /* set Rtune impedance to 50 ohm */ + val |= UHSIC_TX_RTUNE(8); + writel(val, base + UHSIC_PADS_CFG0); + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, + USB_PHY_CLK_VALID, USB_PHY_CLK_VALID, 2500)) { + pr_err("%s: timeout waiting for phy to stabilize\n", __func__); + return -ETIMEDOUT; + } + + phy->phy_clk_on = true; + phy->hw_accessible = true; + + return 0; +} + +static int uhsic_phy_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (!phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already off\n", + __func__, __LINE__, phy->inst); + return 0; + } + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPU_STROBE; + val |= UHSIC_RPD_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel(val, base + USB_SUSP_CTRL); + udelay(30); + + utmip_powerdown_pmc_wake_detect(phy); + + phy->phy_clk_on = false; + phy->hw_accessible = false; + + return 0; +} + +int uhsic_phy_bus_port_power(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + UHSIC_STAT_CFG0); + val &= ~UHSIC_CONNECT_DETECT; + writel(val, base + UHSIC_STAT_CFG0); + + val = readl(base + USB_USBMODE); + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE); + + /* Change the USB controller PHY type to HSIC */ + val = readl(base + HOSTPC1_DEVLC); + val &= ~(HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK)); + val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC); + val &= ~(HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK)); + val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED); + writel(val, base + HOSTPC1_DEVLC); + + val = readl(base + UHSIC_MISC_CFG0); + val |= UHSIC_DETECT_SHORT_CONNECT; + writel(val, base + UHSIC_MISC_CFG0); + udelay(1); + + val = readl(base + UHSIC_MISC_CFG0); + val |= UHSIC_FORCE_XCVR_MODE; + writel(val, base + UHSIC_MISC_CFG0); + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPD_STROBE; + /* safe to enable RPU on STROBE at all times during idle */ + val |= UHSIC_RPU_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + val = readl(base + USB_USBCMD); + val &= ~USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + UHSIC_STAT_CFG0, + UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT, 25000)) { + pr_err("%s: timeout waiting for UHSIC_CONNECT_DETECT\n", + __func__); + return -ETIMEDOUT; + } + + return 0; +} + +static int uhsic_phy_bus_reset(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + /* Change the USB controller PHY type to HSIC */ + val = readl(base + HOSTPC1_DEVLC); + val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK); + val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC); + val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK); + val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED); + writel(val, base + HOSTPC1_DEVLC); + /* wait here, otherwise HOSTPC1_DEVLC_PSPD will timeout */ + mdelay(5); + + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PTC(5); + writel(val, base + USB_PORTSC); + udelay(2); + + val = readl(base + USB_PORTSC); + val &= ~(USB_PORTSC_PTC(~0)); + writel(val, base + USB_PORTSC); + udelay(2); + + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_LS(0), + 0, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_LS\n", __func__); + return -ETIMEDOUT; + } + + /* Poll until CCS is enabled */ + if (usb_phy_reg_status_wait(base + USB_PORTSC, USB_PORTSC_CCS, + USB_PORTSC_CCS, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC_CCS\n", __func__); + return -ETIMEDOUT; + } + + if (usb_phy_reg_status_wait(base + HOSTPC1_DEVLC, + HOSTPC1_DEVLC_PSPD(2), + HOSTPC1_DEVLC_PSPD(2), 2000) < 0) { + pr_err("%s: timeout waiting hsic high speed configuration\n", + __func__); + return -ETIMEDOUT; + } + + val = readl(base + USB_USBCMD); + val &= ~USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_HCH, + USB_USBSTS_HCH, 2000)) { + pr_err("%s: timeout waiting for USB_USBSTS_HCH\n", __func__); + return -ETIMEDOUT; + } + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPU_STROBE; + val |= UHSIC_RPD_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + mdelay(50); + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPD_STROBE; + val |= UHSIC_RPU_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + val = readl(base + USB_USBCMD); + val |= USB_USBCMD_RS; + writel(val, base + USB_USBCMD); + + val = readl(base + UHSIC_PADS_CFG1); + val &= ~UHSIC_RPU_STROBE; + writel(val, base + UHSIC_PADS_CFG1); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, USB_USBCMD_RS, + USB_USBCMD_RS, 2000)) { + pr_err("%s: timeout waiting for USB_USBCMD_RS\n", __func__); + return -ETIMEDOUT; + } + + return 0; +} + + +int uhsic_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) +{ + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + usb_phy_wait_for_sof(phy); + + return 0; +} + +int uhsic_phy_resume(struct tegra_usb_phy *phy) +{ + void __iomem *base = phy->regs; + unsigned long val; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + /* Check if the phy resume from LP0. When the phy resume from LP0 + * USB register will be reset.to zero */ + if (!readl(base + USB_ASYNCLISTADDR)) { + + val = readl(base + USB_USBCMD); + val |= USB_CMD_RESET; + writel(val, base + USB_USBCMD); + + if (usb_phy_reg_status_wait(base + USB_USBCMD, + USB_CMD_RESET, 0, 2500) < 0) { + pr_err("%s: timeout waiting for reset\n", __func__); + } + + val = readl(base + USB_USBMODE); + val &= ~USB_USBMODE_MASK; + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE); + + /* Enable Port Power */ + val = readl(base + USB_PORTSC); + val |= USB_PORTSC_PP; + writel(val, base + USB_PORTSC); + udelay(10); + + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x]\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC)); + + uhsic_phy_bus_port_power(phy); + } + + return 0; +} + +static int uhsic_phy_post_resume(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + USB_TXFILLTUNING); + if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) { + val = USB_FIFO_TXFILL_THRES(0x10); + writel(val, base + USB_TXFILLTUNING); + } + + return 0; +} + +static void ulpi_set_trimmer(struct tegra_usb_phy *phy) +{ + struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi; + void __iomem *base = phy->regs; + unsigned long val; + + val = ULPI_DATA_TRIMMER_SEL(config->data_trimmer); + val |= ULPI_STPDIRNXT_TRIMMER_SEL(config->stpdirnxt_trimmer); + val |= ULPI_DIR_TRIMMER_SEL(config->dir_trimmer); + writel(val, base + ULPI_TIMING_CTRL_1); + udelay(10); + + val |= ULPI_DATA_TRIMMER_LOAD; + val |= ULPI_STPDIRNXT_TRIMMER_LOAD; + val |= ULPI_DIR_TRIMMER_LOAD; + writel(val, base + ULPI_TIMING_CTRL_1); +} + +static void reset_utmip_uhsic(void __iomem *base) +{ + unsigned long val; + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); +} + +static void ulpi_set_host(void __iomem *base) +{ + unsigned long val; + + val = readl(base + USB_USBMODE); + val |= USB_USBMODE_HOST; + writel(val, base + USB_USBMODE); + + val = readl(base + HOSTPC1_DEVLC); + val |= HOSTPC1_DEVLC_PTS(2); + writel(val, base + HOSTPC1_DEVLC); +} + + + +static inline void null_phy_set_tristate(bool enable) +{ +#ifndef CONFIG_ARCH_TEGRA_2x_SOC + int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL; + DBG("%s(%d) inst:[%s] FIXME enable pin group +++\n", __func__, + __LINE__, enable ? "TRISTATE" : "NORMAL"); + + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA0, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA1, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA2, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA3, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA4, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA5, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA6, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA7, tristate); + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_NXT, tristate); + + if (enable) + tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, tristate); +#endif + +} + + +static int ulpi_null_phy_power_off(struct tegra_usb_phy *phy) +{ + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + if (!phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already off\n", __func__, + __LINE__, phy->inst); + return 0; + } + + null_phy_set_tristate(true); + + phy->phy_clk_on = false; + phy->hw_accessible = false; + + return 0; +} + +static int ulpi_null_phy_init(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + val = readl(base + ULPIS2S_CTRL); + val |= ULPIS2S_SLV0_CLAMP_XMIT; + writel(val, base + ULPIS2S_CTRL); + + val = readl(base + USB_SUSP_CTRL); + val |= ULPIS2S_SLV0_RESET; + writel(val, base + USB_SUSP_CTRL); + udelay(10); + + return 0; +} + +static int ulpi_null_phy_irq(struct tegra_usb_phy *phy) +{ + usb_phy_fence_read(phy); + return IRQ_HANDLED; +} + +static int ulpi_null_phy_cmd_reset(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + ulpi_set_host(base); + + /* remove slave0 reset */ + val = readl(base + USB_SUSP_CTRL); + val &= ~ULPIS2S_SLV0_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + ULPIS2S_CTRL); + val &= ~ULPIS2S_SLV0_CLAMP_XMIT; + writel(val, base + ULPIS2S_CTRL); + udelay(10); + + return 0; +} + +static int ulpi_null_phy_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi; + static bool cold_boot = true; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->phy_clk_on) { + DBG("%s(%d) inst:[%d] phy clk is already On\n", __func__, + __LINE__, phy->inst); + return 0; + } + reset_utmip_uhsic(base); + + /* remove ULPI PADS CLKEN reset */ + val = readl(base + USB_SUSP_CTRL); + val &= ~ULPI_PADS_CLKEN_RESET; + writel(val, base + USB_SUSP_CTRL); + udelay(10); + + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP; + writel(val, base + ULPI_TIMING_CTRL_0); + + val = readl(base + USB_SUSP_CTRL); + val |= ULPI_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + udelay(10); + + /* set timming parameters */ + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_SHADOW_CLK_LOOPBACK_EN; + val &= ~ULPI_SHADOW_CLK_SEL; + val &= ~ULPI_LBK_PAD_EN; + val |= ULPI_SHADOW_CLK_DELAY(config->shadow_clk_delay); + val |= ULPI_CLOCK_OUT_DELAY(config->clock_out_delay); + val |= ULPI_LBK_PAD_E_INPUT_OR; + writel(val, base + ULPI_TIMING_CTRL_0); + + writel(0, base + ULPI_TIMING_CTRL_1); + udelay(10); + + /* start internal 60MHz clock */ + val = readl(base + ULPIS2S_CTRL); + val |= ULPIS2S_ENA; + val |= ULPIS2S_SUPPORT_DISCONNECT; + val |= ULPIS2S_SPARE((phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) ? 3 : 1); + val |= ULPIS2S_PLLU_MASTER_BLASTER60; + writel(val, base + ULPIS2S_CTRL); + + /* select ULPI_CORE_CLK_SEL to SHADOW_CLK */ + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_CORE_CLK_SEL; + writel(val, base + ULPI_TIMING_CTRL_0); + udelay(10); + + /* enable ULPI null phy clock - can't set the trimmers before this */ + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_CLK_OUT_ENA; + writel(val, base + ULPI_TIMING_CTRL_0); + udelay(10); + + if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID, 2500)) { + pr_err("%s: timeout waiting for phy to stabilize\n", __func__); + return -ETIMEDOUT; + } + + /* set ULPI trimmers */ + ulpi_set_trimmer(phy); + + ulpi_set_host(base); + + /* remove slave0 reset */ + val = readl(base + USB_SUSP_CTRL); + val &= ~ULPIS2S_SLV0_RESET; + writel(val, base + USB_SUSP_CTRL); + + /* remove slave1 and line reset */ + val = readl(base + USB_SUSP_CTRL); + val &= ~ULPIS2S_SLV1_RESET; + val &= ~ULPIS2S_LINE_RESET; + + /* remove ULPI PADS reset */ + val &= ~ULPI_PADS_RESET; + writel(val, base + USB_SUSP_CTRL); + + if (cold_boot) { + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_CLK_PADOUT_ENA; + writel(val, base + ULPI_TIMING_CTRL_0); + cold_boot = false; + } + udelay(10); + + phy->phy_clk_on = true; + phy->hw_accessible = true; + + return 0; +} + + +int ulpi_null_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) +{ + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + usb_phy_wait_for_sof(phy); + return 0; +} + +static struct tegra_usb_phy_ops utmi_phy_ops = { + .open = utmi_phy_open, + .close = utmi_phy_close, + .irq = utmi_phy_irq, + .power_on = utmi_phy_power_on, + .power_off = utmi_phy_power_off, + .pre_resume = utmi_phy_pre_resume, + .resume = utmi_phy_resume, + .post_resume = utmi_phy_post_resume, + .charger_detect = utmi_phy_charger_detect, +}; + +static struct tegra_usb_phy_ops uhsic_phy_ops = { + .open = uhsic_phy_open, + .irq = uhsic_phy_irq, + .power_on = uhsic_phy_power_on, + .power_off = uhsic_phy_power_off, + .pre_resume = uhsic_phy_pre_resume, + .resume = uhsic_phy_resume, + .post_resume = uhsic_phy_post_resume, + .port_power = uhsic_phy_bus_port_power, + .bus_reset = uhsic_phy_bus_reset, +}; + +static struct tegra_usb_phy_ops ulpi_null_phy_ops = { + .init = ulpi_null_phy_init, + .irq = ulpi_null_phy_irq, + .power_on = ulpi_null_phy_power_on, + .power_off = ulpi_null_phy_power_off, + .pre_resume = ulpi_null_phy_pre_resume, + .reset = ulpi_null_phy_cmd_reset, +}; + +static struct tegra_usb_phy_ops ulpi_link_phy_ops; +static struct tegra_usb_phy_ops icusb_phy_ops; + +static struct tegra_usb_phy_ops *phy_ops[] = { + [TEGRA_USB_PHY_INTF_UTMI] = &utmi_phy_ops, + [TEGRA_USB_PHY_INTF_ULPI_LINK] = &ulpi_link_phy_ops, + [TEGRA_USB_PHY_INTF_ULPI_NULL] = &ulpi_null_phy_ops, + [TEGRA_USB_PHY_INTF_HSIC] = &uhsic_phy_ops, + [TEGRA_USB_PHY_INTF_ICUSB] = &icusb_phy_ops, +}; + +int tegra3_usb_phy_init_ops(struct tegra_usb_phy *phy) +{ + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + phy->ops = phy_ops[phy->pdata->phy_intf]; + + /* FIXME: uncommenting below line to make USB host mode fail*/ + /* usb_phy_power_down_pmc(); */ + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra_usb_phy.h b/arch/arm/mach-tegra/tegra_usb_phy.h new file mode 100644 index 000000000000..36b88db94f52 --- /dev/null +++ b/arch/arm/mach-tegra/tegra_usb_phy.h @@ -0,0 +1,104 @@ +/* + * arch/arm/mach-tegra/include/mach/tegra_usb_phy.h + * + * Copyright (C) 2011 NVIDIA Corporation. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 __MACH_TEGRA_USB_PHY_H +#define __MACH_TEGRA_USB_PHY_H + +/** + * defines USB port speeds supported in USB2.0 + */ +enum usb_phy_port_speed { + USB_PHY_PORT_SPEED_FULL = 0, + USB_PHY_PORT_SPEED_LOW, + USB_PHY_PORT_SPEED_HIGH, + USB_PHY_PORT_SPEED_UNKNOWN, +}; + +/** + * defines structure for oscillator dependent parameters + */ +struct tegra_xtal_freq { + int freq; + u8 enable_delay; + u8 stable_count; + u8 active_delay; + u16 xtal_freq_count; + u16 debounce; + u8 pdtrk_count; +}; + +/** + * pre decleration of the usb phy data structure + */ +struct tegra_usb_phy; + +/** + * defines function pointers used for differnt phy interfaces + */ +struct tegra_usb_phy_ops { + int (*open)(struct tegra_usb_phy *phy); + void (*close)(struct tegra_usb_phy *phy); + int (*irq)(struct tegra_usb_phy *phy); + int (*init)(struct tegra_usb_phy *phy); + int (*reset)(struct tegra_usb_phy *phy); + int (*pre_suspend)(struct tegra_usb_phy *phy); + int (*suspend)(struct tegra_usb_phy *phy); + int (*post_suspend)(struct tegra_usb_phy *phy); + int (*pre_resume)(struct tegra_usb_phy *phy, bool remote_wakeup); + int (*resume)(struct tegra_usb_phy *phy); + int (*post_resume)(struct tegra_usb_phy *phy); + int (*port_power)(struct tegra_usb_phy *phy); + int (*bus_reset)(struct tegra_usb_phy *phy); + int (*power_off)(struct tegra_usb_phy *phy); + int (*power_on)(struct tegra_usb_phy *phy); + bool (*charger_detect)(struct tegra_usb_phy *phy); +}; + +/** + * defines usb phy data structure + */ +struct tegra_usb_phy { + struct platform_device *pdev; + struct tegra_usb_platform_data *pdata; + struct clk *pllu_clk; + struct clk *ctrlr_clk; + struct clk *ulpi_clk; + struct clk *utmi_pad_clk; + struct clk *emc_clk; + struct clk *sys_clk; + struct regulator *vdd_reg; + struct regulator *vbus_reg; + struct tegra_usb_phy_ops *ops; + struct tegra_xtal_freq *freq; + struct otg_transceiver *ulpi_vp; + enum usb_phy_port_speed port_speed; + signed char utmi_xcvr_setup; + void __iomem *regs; + int inst; + bool phy_clk_on; + bool phy_power_on; + bool remote_wakeup; + bool hw_accessible; +}; + +int usb_phy_reg_status_wait(void __iomem *reg, u32 mask, + u32 result, u32 timeout); + +int tegra3_usb_phy_init_ops(struct tegra_usb_phy *phy); +int tegra2_usb_phy_init_ops(struct tegra_usb_phy *phy); + + +#endif /* __MACH_TEGRA_USB_PHY_H */ diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c index 8c36159e085a..6f568fd2cd29 100644 --- a/arch/arm/mach-tegra/usb_phy.c +++ b/arch/arm/mach-tegra/usb_phy.c @@ -18,7 +18,6 @@ * GNU General Public License for more details. * */ - #include <linux/resource.h> #include <linux/delay.h> #include <linux/interrupt.h> @@ -27,581 +26,16 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/gpio.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> -#include <asm/mach-types.h> -#include <mach/usb_phy.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/regulator/consumer.h> +#include <linux/platform_data/tegra_usb.h> +#include "tegra_usb_phy.h" #include <mach/iomap.h> -#include <mach/pinmux.h> -#include "fuse.h" - - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC -#define USB_USBCMD 0x140 -#define USB_USBCMD_RS (1 << 0) - -#define USB_USBSTS 0x144 -#define USB_USBSTS_PCI (1 << 2) -#define USB_USBSTS_HCH (1 << 12) - -#define USB_TXFILLTUNING 0x164 -#define USB_FIFO_TXFILL_THRES(x) (((x) & 0x1f) << 16) -#define USB_FIFO_TXFILL_MASK 0x1f0000 - -#define ULPI_VIEWPORT 0x170 -#define ULPI_WAKEUP (1 << 31) -#define ULPI_RUN (1 << 30) -#define ULPI_RD_WR (1 << 29) - -#define USB_PORTSC1 0x184 -#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30) -#define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26) -#define USB_PORTSC1_PHCD (1 << 23) -#define USB_PORTSC1_WKOC (1 << 22) -#define USB_PORTSC1_WKDS (1 << 21) -#define USB_PORTSC1_WKCN (1 << 20) -#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16) -#define USB_PORTSC1_PP (1 << 12) -#define USB_PORTSC1_LS(x) (((x) & 0x3) << 10) -#define USB_PORTSC1_SUSP (1 << 7) -#define USB_PORTSC1_PE (1 << 2) -#define USB_PORTSC1_CCS (1 << 0) - -#define USB_SUSP_CTRL 0x400 -#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) -#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) -#define USB_SUSP_CLR (1 << 5) -#define USB_CLKEN (1 << 6) -#define USB_PHY_CLK_VALID (1 << 7) -#define USB_PHY_CLK_VALID_INT_ENB (1 << 9) -#define UTMIP_RESET (1 << 11) -#define UHSIC_RESET (1 << 11) -#define UTMIP_PHY_ENABLE (1 << 12) -#define UHSIC_PHY_ENABLE (1 << 12) -#define ULPI_PHY_ENABLE (1 << 13) -#define USB_SUSP_SET (1 << 14) -#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) - -#define USB_PHY_VBUS_WAKEUP_ID 0x408 -#define VDAT_DET_INT_EN (1 << 16) -#define VDAT_DET_CHG_DET (1 << 17) -#define VDAT_DET_STS (1 << 18) - -#define USB1_LEGACY_CTRL 0x410 -#define USB1_NO_LEGACY_MODE (1 << 0) -#define USB1_VBUS_SENSE_CTL_MASK (3 << 1) -#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \ - (1 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1) -#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1) - - -#define UTMIP_PLL_CFG1 0x804 -#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) -#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) - -#define UTMIP_XCVR_CFG0 0x808 -#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0) -#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8) -#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10) -#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) -#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) -#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) -#define UTMIP_XCVR_LSBIAS_SEL (1 << 21) -#define UTMIP_XCVR_SETUP_MSB(x) (((x) & 0x7) << 22) -#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) - -#define UTMIP_XCVR_MAX_OFFSET 2 -#define UTMIP_XCVR_SETUP_MAX_VALUE 0x7f -#define UTMIP_XCVR_SETUP_MIN_VALUE 0 -#define XCVR_SETUP_MSB_CALIB(x) ((x) >> 4) - -#define UTMIP_BIAS_CFG0 0x80c -#define UTMIP_OTGPD (1 << 11) -#define UTMIP_BIASPD (1 << 10) - -#define UTMIP_HSRX_CFG0 0x810 -#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) -#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15) - -#define UTMIP_HSRX_CFG1 0x814 -#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) - -#define UTMIP_TX_CFG0 0x820 -#define UTMIP_FS_PREABMLE_J (1 << 19) -#define UTMIP_HS_DISCON_DISABLE (1 << 8) - -#define UTMIP_MISC_CFG1 0x828 -#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18) -#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6) - -#define UTMIP_DEBOUNCE_CFG0 0x82c -#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0) - -#define UTMIP_BAT_CHRG_CFG0 0x830 -#define UTMIP_PD_CHRG (1 << 0) -#define UTMIP_ON_SINK_EN (1 << 2) -#define UTMIP_OP_SRC_EN (1 << 3) - -#define UTMIP_XCVR_CFG1 0x838 -#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) -#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) -#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) -#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18) - -#define UTMIP_BIAS_CFG1 0x83c -#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) - -#define UHSIC_PLL_CFG1 0x804 -#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) -#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14) - -#define UHSIC_HSRX_CFG0 0x808 -#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2) -#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8) -#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13) - -#define UHSIC_HSRX_CFG1 0x80c -#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) - -#define UHSIC_TX_CFG0 0x810 -#define UHSIC_HS_POSTAMBLE_OUTPUT_ENABLE (1 << 6) - -#define UHSIC_MISC_CFG0 0x814 -#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7) -#define UHSIC_DETECT_SHORT_CONNECT (1 << 8) -#define UHSIC_FORCE_XCVR_MODE (1 << 15) - -#define UHSIC_MISC_CFG1 0X818 -#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2) - -#define UHSIC_PADS_CFG0 0x81c -#define UHSIC_TX_RTUNEN 0xf000 -#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12) - -#define UHSIC_PADS_CFG1 0x820 -#define UHSIC_PD_BG (1 << 2) -#define UHSIC_PD_TX (1 << 3) -#define UHSIC_PD_TRK (1 << 4) -#define UHSIC_PD_RX (1 << 5) -#define UHSIC_PD_ZI (1 << 6) -#define UHSIC_RX_SEL (1 << 7) -#define UHSIC_RPD_DATA (1 << 9) -#define UHSIC_RPD_STROBE (1 << 10) -#define UHSIC_RPU_DATA (1 << 11) -#define UHSIC_RPU_STROBE (1 << 12) - -#define UHSIC_STAT_CFG0 0x828 -#define UHSIC_CONNECT_DETECT (1 << 0) - - -#else -#define USB_USBCMD 0x130 -#define USB_USBCMD_RS (1 << 0) - -#define USB_USBSTS 0x134 -#define USB_USBSTS_PCI (1 << 2) -#define USB_USBSTS_SRI (1 << 7) -#define USB_USBSTS_HCH (1 << 12) - -#define USB_TXFILLTUNING 0x154 -#define USB_FIFO_TXFILL_THRES(x) (((x) & 0x1f) << 16) -#define USB_FIFO_TXFILL_MASK 0x1f0000 - -#define ULPI_VIEWPORT 0x160 - -#define USB_PORTSC1 0x174 -#define USB_PORTSC1_WKOC (1 << 22) -#define USB_PORTSC1_WKDS (1 << 21) -#define USB_PORTSC1_WKCN (1 << 20) -#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16) -#define USB_PORTSC1_PP (1 << 12) -#define USB_PORTSC1_LS(x) (((x) & 0x3) << 10) -#define USB_PORTSC1_SUSP (1 << 7) -#define USB_PORTSC1_RESUME (1 << 6) -#define USB_PORTSC1_PE (1 << 2) -#define USB_PORTSC1_CCS (1 << 0) - -#define USB_SUSP_CTRL 0x400 -#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) -#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) -#define USB_SUSP_CLR (1 << 5) -#define USB_PHY_CLK_VALID (1 << 7) -#define USB_PHY_CLK_VALID_INT_ENB (1 << 9) - - -#define UTMIP_RESET (1 << 11) -#define UTMIP_PHY_ENABLE (1 << 12) -#define ULPI_PHY_ENABLE (1 << 13) -#define UHSIC_RESET (1 << 14) - -#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) -#define UHSIC_PHY_ENABLE (1 << 19) -#define ULPIS2S_SLV0_RESET (1 << 20) -#define ULPIS2S_SLV1_RESET (1 << 21) -#define ULPIS2S_LINE_RESET (1 << 22) -#define ULPI_PADS_RESET (1 << 23) -#define ULPI_PADS_CLKEN_RESET (1 << 24) - -#define USB_PHY_VBUS_WAKEUP_ID 0x408 -#define VDAT_DET_INT_EN (1 << 16) -#define VDAT_DET_CHG_DET (1 << 17) -#define VDAT_DET_STS (1 << 18) - -#define USB1_LEGACY_CTRL 0x410 -#define USB1_NO_LEGACY_MODE (1 << 0) -#define USB1_VBUS_SENSE_CTL_MASK (3 << 1) -#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \ - (1 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1) -#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1) - -#define UTMIP_PLL_CFG1 0x804 -#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) -#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) - -#define UTMIP_XCVR_CFG0 0x808 -#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0) -#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8) -#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10) -#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) -#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) -#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) -#define UTMIP_XCVR_LSBIAS_SEL (1 << 21) -#define UTMIP_XCVR_SETUP_MSB(x) (((x) & 0x7) << 22) -#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) - -#define UTMIP_XCVR_MAX_OFFSET 2 -#define UTMIP_XCVR_SETUP_MAX_VALUE 0x7f -#define UTMIP_XCVR_SETUP_MIN_VALUE 0 -#define XCVR_SETUP_MSB_CALIB(x) ((x) >> 4) - -#define UTMIP_BIAS_CFG0 0x80c -#define UTMIP_OTGPD (1 << 11) -#define UTMIP_BIASPD (1 << 10) -#define UTMIP_HSSQUELCH_LEVEL(x) (((x) & 0x3) << 0) -#define UTMIP_HSDISCON_LEVEL(x) (((x) & 0x3) << 2) -#define UTMIP_HSDISCON_LEVEL_MSB (1 << 24) - -#define UTMIP_HSRX_CFG0 0x810 -#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) -#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15) - -#define UTMIP_HSRX_CFG1 0x814 -#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) - -#define UTMIP_TX_CFG0 0x820 -#define UTMIP_FS_PREABMLE_J (1 << 19) -#define UTMIP_HS_DISCON_DISABLE (1 << 8) - -#define UTMIP_MISC_CFG1 0x828 -#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18) -#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6) - -#define UTMIP_DEBOUNCE_CFG0 0x82c -#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0) - -#define UTMIP_BAT_CHRG_CFG0 0x830 -#define UTMIP_PD_CHRG (1 << 0) -#define UTMIP_ON_SINK_EN (1 << 2) -#define UTMIP_OP_SRC_EN (1 << 3) - -#define UTMIP_XCVR_CFG1 0x838 -#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) -#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) -#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) -#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18) - -#define UTMIP_BIAS_CFG1 0x83c -#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) -#define UTMIP_BIAS_PDTRK_POWERDOWN (1 << 0) -#define UTMIP_BIAS_PDTRK_POWERUP (1 << 1) - -#define HOSTPC1_DEVLC 0x1b4 -#define HOSTPC1_DEVLC_PHCD (1 << 22) -#define HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29) -#define HOSTPC1_DEVLC_PTS_MASK 7 -#define HOSTPC1_DEVLC_PTS_HSIC 4 -#define HOSTPC1_DEVLC_STS (1 << 28) -#define HOSTPC1_DEVLC_PSPD(x) (((x) & 0x3) << 25) -#define HOSTPC1_DEVLC_PSPD_MASK 3 -#define HOSTPC1_DEVLC_PSPD_HIGH_SPEED 2 - -#define TEGRA_USB_USBMODE_REG_OFFSET 0x1f8 -#define TEGRA_USB_USBMODE_HOST (3 << 0) - -#define TEGRA_PMC_USB_AO 0xf0 -#define TEGRA_PMC_USB_AO_VBUS_WAKEUP_PD_P0 (1 << 2) -#define TEGRA_PMC_USB_AO_ID_PD_P0 (1 << 3) -#define TEGRA_PMC_USB_AO_PD_P2 (0xf << 8) - -#define ICUSB_CTRL 0x15c - -#define UHSIC_PLL_CFG1 0xc04 -#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) -#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14) - -#define UHSIC_HSRX_CFG0 0xc08 -#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2) -#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8) -#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13) - -#define UHSIC_HSRX_CFG1 0xc0c -#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) - -#define UHSIC_TX_CFG0 0xc10 -#define UHSIC_HS_READY_WAIT_FOR_VALID (1 << 9) - -#define UHSIC_MISC_CFG0 0xc14 -#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7) -#define UHSIC_DETECT_SHORT_CONNECT (1 << 8) -#define UHSIC_FORCE_XCVR_MODE (1 << 15) -#define UHSIC_DISABLE_BUSRESET (1 << 20) - -#define UHSIC_MISC_CFG1 0xc18 -#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2) - -#define UHSIC_PADS_CFG0 0xc1c -#define UHSIC_TX_RTUNEN 0xf000 -#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12) - -#define UHSIC_PADS_CFG1 0xc20 -#define UHSIC_PD_BG (1 << 2) -#define UHSIC_PD_TX (1 << 3) -#define UHSIC_PD_TRK (1 << 4) -#define UHSIC_PD_RX (1 << 5) -#define UHSIC_PD_ZI (1 << 6) -#define UHSIC_RX_SEL (1 << 7) -#define UHSIC_RPD_DATA (1 << 9) -#define UHSIC_RPD_STROBE (1 << 10) -#define UHSIC_RPU_DATA (1 << 11) -#define UHSIC_RPU_STROBE (1 << 12) - -#define UHSIC_STAT_CFG0 0xc28 -#define UHSIC_CONNECT_DETECT (1 << 0) - -#define PMC_UTMIP_MASTER_CONFIG 0x310 -#define UTMIP_PWR(inst) (1 << (inst)) - -#define PMC_USB_DEBOUNCE 0xec -#define UTMIP_LINE_DEB_CNT(x) (((x) & 0xf) << 16) - -#define PMC_UTMIP_UHSIC_FAKE 0x218 -#define USBON_VAL(inst) (1 << ((4*(inst))+1)) -#define USBON_VAL_P2 (1 << 9) -#define USBON_VAL_P1 (1 << 5) -#define USBON_VAL_P0 (1 << 1) -#define USBOP_VAL(inst) (1 << (4*(inst))) -#define USBOP_VAL_P2 (1 << 8) -#define USBOP_VAL_P1 (1 << 4) -#define USBOP_VAL_P0 (1 << 0) - -#define PMC_SLEEPWALK_CFG 0x200 -#define UTMIP_LINEVAL_WALK_EN(inst) (1 << ((8*(inst))+7)) -#define UTMIP_LINEVAL_WALK_EN_P2 (1 << 23) -#define UTMIP_LINEVAL_WALK_EN_P1 (1 << 15) -#define UTMIP_LINEVAL_WALK_EN_P0 (1 << 7) -#define UTMIP_WAKE_VAL(inst, x) (((x) & 0xf) << ((8*(inst))+4)) -#define UTMIP_WAKE_VAL_P2(x) (((x) & 0xf) << 20) -#define UTMIP_WAKE_VAL_P1(x) (((x) & 0xf) << 12) -#define UTMIP_WAKE_VAL_P0(x) (((x) & 0xf) << 4) -#define WAKE_VAL_NONE 0xc -#define WAKE_VAL_FSJ 0x2 -#define WAKE_VAL_FSK 0x1 -#define WAKE_VAL_SE0 0x0 -#define WAKE_VAL_ANY 0xf - -#define PMC_SLEEP_CFG 0x1fc -#define UTMIP_TCTRL_USE_PMC(inst) (1 << ((8*(inst))+3)) -#define UTMIP_TCTRL_USE_PMC_P2 (1 << 19) -#define UTMIP_TCTRL_USE_PMC_P1 (1 << 11) -#define UTMIP_TCTRL_USE_PMC_P0 (1 << 3) -#define UTMIP_RCTRL_USE_PMC(inst) (1 << ((8*(inst))+2)) -#define UTMIP_RCTRL_USE_PMC_P2 (1 << 18) -#define UTMIP_RCTRL_USE_PMC_P1 (1 << 10) -#define UTMIP_RCTRL_USE_PMC_P0 (1 << 2) -#define UTMIP_FSLS_USE_PMC(inst) (1 << ((8*(inst))+1)) -#define UTMIP_FSLS_USE_PMC_P2 (1 << 17) -#define UTMIP_FSLS_USE_PMC_P1 (1 << 9) -#define UTMIP_FSLS_USE_PMC_P0 (1 << 1) -#define UTMIP_MASTER_ENABLE(inst) (1 << (8*(inst))) -#define UTMIP_MASTER_ENABLE_P2 (1 << 16) -#define UTMIP_MASTER_ENABLE_P1 (1 << 8) -#define UTMIP_MASTER_ENABLE_P0 (1 << 0) -#define UHSIC_MASTER_ENABLE_P0 (1 << 24) -#define UHSIC_WAKE_VAL_P0(x) (((x) & 0xf) << 28) - -#define PMC_USB_AO 0xf0 -#define PMC_POWER_DOWN_MASK 0xffff -#define HSIC_RESERVED_P0 (3 << 14) -#define HSIC_STOBE_VAL_PD_P0 (1 << 13) -#define HSIC_DATA_VAL_PD_P0 (1 << 12) -#define USB_ID_PD(inst) (1 << ((4*(inst))+3)) -#define VBUS_WAKEUP_PD(inst) (1 << ((4*(inst))+2)) -#define USBON_VAL_PD(inst) (1 << ((4*(inst))+1)) -#define USBON_VAL_PD_P2 (1 << 9) -#define USBON_VAL_PD_P1 (1 << 5) -#define USBON_VAL_PD_P0 (1 << 1) -#define USBOP_VAL_PD(inst) (1 << (4*(inst))) -#define USBOP_VAL_PD_P2 (1 << 8) -#define USBOP_VAL_PD_P1 (1 << 4) -#define USBOP_VAL_PD_P0 (1 << 0) - -#define PMC_TRIGGERS 0x1ec -#define UTMIP_CLR_WALK_PTR(inst) (1 << (inst)) -#define UTMIP_CLR_WALK_PTR_P2 (1 << 2) -#define UTMIP_CLR_WALK_PTR_P1 (1 << 1) -#define UTMIP_CLR_WALK_PTR_P0 (1 << 0) -#define UTMIP_CAP_CFG(inst) (1 << ((inst)+4)) -#define UTMIP_CAP_CFG_P2 (1 << 6) -#define UTMIP_CAP_CFG_P1 (1 << 5) -#define UTMIP_CAP_CFG_P0 (1 << 4) -#define UTMIP_CLR_WAKE_ALARM(inst) (1 << ((inst)+12)) -#define UTMIP_CLR_WAKE_ALARM_P2 (1 << 14) - -#define PMC_PAD_CFG (0x1f4) - -#define PMC_UTMIP_BIAS_MASTER_CNTRL 0x30c -#define BIAS_MASTER_PROG_VAL (1 << 1) - -#define PMC_SLEEPWALK_REG(inst) (0x204 + (4*(inst))) -#define PMC_SLEEPWALK_P0 0x204 -#define PMC_SLEEPWALK_P1 0x208 -#define PMC_SLEEPWALK_P2 0x20c -#define UTMIP_USBOP_RPD_A (1 << 0) -#define UTMIP_USBON_RPD_A (1 << 1) -#define UTMIP_AP_A (1 << 4) -#define UTMIP_AN_A (1 << 5) -#define UTMIP_HIGHZ_A (1 << 6) -#define UTMIP_USBOP_RPD_B (1 << 8) -#define UTMIP_USBON_RPD_B (1 << 9) -#define UTMIP_AP_B (1 << 12) -#define UTMIP_AN_B (1 << 13) -#define UTMIP_HIGHZ_B (1 << 14) -#define UTMIP_USBOP_RPD_C (1 << 16) -#define UTMIP_USBON_RPD_C (1 << 17) -#define UTMIP_AP_C (1 << 20) -#define UTMIP_AN_C (1 << 21) -#define UTMIP_HIGHZ_C (1 << 22) -#define UTMIP_USBOP_RPD_D (1 << 24) -#define UTMIP_USBON_RPD_D (1 << 25) -#define UTMIP_AP_D (1 << 28) -#define UTMIP_AN_D (1 << 29) -#define UTMIP_HIGHZ_D (1 << 30) - -#define UTMIP_PMC_WAKEUP0 0x84c -#define EVENT_INT_ENB (1 << 0) - -#define UTMIP_UHSIC_STATUS 0x214 -#define UTMIP_WALK_PTR_VAL(inst) (0x3 << ((inst)*2)) -#define UTMIP_USBOP_VAL(inst) (1 << ((2*(inst)) + 8)) -#define UTMIP_USBOP_VAL_P2 (1 << 12) -#define UTMIP_USBOP_VAL_P1 (1 << 10) -#define UTMIP_USBOP_VAL_P0 (1 << 8) -#define UTMIP_USBON_VAL(inst) (1 << ((2*(inst)) + 9)) -#define UTMIP_USBON_VAL_P2 (1 << 13) -#define UTMIP_USBON_VAL_P1 (1 << 11) -#define UTMIP_USBON_VAL_P0 (1 << 9) -#define UTMIP_WAKE_ALARM(inst) (1 << ((inst) + 16)) -#define UTMIP_WAKE_ALARM_P2 (1 << 18) -#define UTMIP_WAKE_ALARM_P1 (1 << 17) -#define UTMIP_WAKE_ALARM_P0 (1 << 16) -#define UTMIP_WALK_PTR(inst) (1 << ((inst)*2)) -#define UTMIP_WALK_PTR_P2 (1 << 4) -#define UTMIP_WALK_PTR_P1 (1 << 2) -#define UTMIP_WALK_PTR_P0 (1 << 0) - -#define UTMIP_BIAS_STS0 0x840 -#define UTMIP_RCTRL_VAL(x) (((x) & 0xffff) << 0) -#define UTMIP_TCTRL_VAL(x) (((x) & (0xffff << 16)) >> 16) - -#define PMC_UTMIP_TERM_PAD_CFG 0x1f8 -#define PMC_TCTRL_VAL(x) (((x) & 0x1f) << 5) -#define PMC_RCTRL_VAL(x) (((x) & 0x1f) << 0) - -#define UHSIC_SLEEPWALK_REG 0x210 -#define UHSIC_DATA_RPD_D (1 << 25) -#define UHSIC_STRB_RPD_D (1 << 24) -#define UHSIC_DATA_RPD_C (1 << 17) -#define UHSIC_STRB_RPD_C (1 << 16) -#define UHSIC_DATA_RPD_B (1 << 9) -#define UHSIC_STRB_RPD_B (1 << 8) -#define UHSIC_DATA_RPD_A (1 << 1) -#define UHSIC_STRB_RPD_A (1 << 0) - -static u32 utmip_rctrl_val, utmip_tctrl_val; - -#endif - -/* Common registers */ -#define UTMIP_MISC_CFG0 0x824 -#define UTMIP_DPDM_OBSERVE (1 << 26) -#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27) -#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf) -#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe) -#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd) -#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc) -#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) -#define FORCE_PULLDN_DM (1 << 8) -#define FORCE_PULLDN_DP (1 << 9) -#define COMB_TERMS (1 << 0) -#define ALWAYS_FREE_RUNNING_TERMS (1 << 1) - -#define ULPIS2S_CTRL 0x418 -#define ULPIS2S_ENA (1 << 0) -#define ULPIS2S_SUPPORT_DISCONNECT (1 << 2) -#define ULPIS2S_PLLU_MASTER_BLASTER60 (1 << 3) -#define ULPIS2S_SPARE(x) (((x) & 0xF) << 8) -#define ULPIS2S_FORCE_ULPI_CLK_OUT (1 << 12) -#define ULPIS2S_DISCON_DONT_CHECK_SE0 (1 << 13) -#define ULPIS2S_SUPPORT_HS_KEEP_ALIVE (1 << 14) -#define ULPIS2S_DISABLE_STP_PU (1 << 15) -#define ULPIS2S_SLV0_CLAMP_XMIT (1 << 16) - - -#define ULPI_TIMING_CTRL_0 0x424 -#define ULPI_CLOCK_OUT_DELAY(x) ((x) & 0x1F) -#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) -#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) -#define ULPI_SHADOW_CLK_LOOPBACK_EN (1 << 12) -#define ULPI_SHADOW_CLK_SEL (1 << 13) -#define ULPI_CORE_CLK_SEL (1 << 14) -#define ULPI_SHADOW_CLK_DELAY(x) (((x) & 0x1F) << 16) -#define ULPI_LBK_PAD_EN (1 << 26) -#define ULPI_LBK_PAD_E_INPUT_OR (1 << 27) -#define ULPI_CLK_OUT_ENA (1 << 28) -#define ULPI_CLK_PADOUT_ENA (1 << 29) - -#define ULPI_TIMING_CTRL_1 0x428 -#define ULPI_DATA_TRIMMER_LOAD (1 << 0) -#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) -#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) -#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) -#define ULPI_DIR_TRIMMER_LOAD (1 << 24) -#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) - -#define UTMIP_SPARE_CFG0 0x834 -#define FUSE_SETUP_SEL (1 << 3) -#define FUSE_ATERM_SEL (1 << 4) - -#define FUSE_USB_CALIB_0 0x1F0 -#define FUSE_USB_CALIB_XCVR_SETUP(x) (((x) & 0x7F) << 0) - -#define UHSIC_PLL_CFG0 0x800 - -#define UHSIC_CMD_CFG0 0x824 -#define UHSIC_PRETEND_CONNECT_DETECT (1 << 5) - -#define UHSIC_SPARE_CFG0 0x82c - -/* These values (in milli second) are taken from the battery charging spec */ -#define TDP_SRC_ON_MS 100 -#define TDPSRC_CON_MS 40 - -#define CONNECT_DETECT_TIMEOUT 25000 +#define ERR(stuff...) pr_err("usb_phy: " stuff) +#define WARNING(stuff...) pr_warning("usb_phy: " stuff) +#define INFO(stuff...) pr_info("usb_phy: " stuff) #define AHB_MEM_PREFETCH_CFG3 0xe0 #define AHB_MEM_PREFETCH_CFG4 0xe4 @@ -609,2587 +43,599 @@ static u32 utmip_rctrl_val, utmip_tctrl_val; #define AHB_MEM_PREFETCH_CFG2 0xf0 #define PREFETCH_ENB (1 << 31) -static DEFINE_SPINLOCK(utmip_pad_lock); -static int utmip_pad_count; - -struct tegra_xtal_freq { - int freq; - u8 enable_delay; - u8 stable_count; - u8 active_delay; - u16 xtal_freq_count; - u16 debounce; - u8 pdtrk_count; -}; - -static const struct tegra_xtal_freq tegra_freq_table[] = { - { - .freq = 12000000, - .enable_delay = 0x02, - .stable_count = 0x2F, - .active_delay = 0x04, - .xtal_freq_count = 0x76, - .debounce = 0x7530, - .pdtrk_count = 5, - }, - { - .freq = 13000000, - .enable_delay = 0x02, - .stable_count = 0x33, - .active_delay = 0x05, - .xtal_freq_count = 0x7F, - .debounce = 0x7EF4, - .pdtrk_count = 5, - }, - { - .freq = 19200000, - .enable_delay = 0x03, - .stable_count = 0x4B, - .active_delay = 0x06, - .xtal_freq_count = 0xBB, - .debounce = 0xBB80, - .pdtrk_count = 7, - }, - { - .freq = 26000000, - .enable_delay = 0x04, - .stable_count = 0x66, - .active_delay = 0x09, - .xtal_freq_count = 0xFE, - .debounce = 0xFDE8, - .pdtrk_count = 9, - }, -}; - -static const struct tegra_xtal_freq tegra_uhsic_freq_table[] = { - { - .freq = 12000000, - .enable_delay = 0x02, - .stable_count = 0x2F, - .active_delay = 0x0, - .xtal_freq_count = 0x1CA, - }, - { - .freq = 13000000, - .enable_delay = 0x02, - .stable_count = 0x33, - .active_delay = 0x0, - .xtal_freq_count = 0x1F0, - }, - { - .freq = 19200000, - .enable_delay = 0x03, - .stable_count = 0x4B, - .active_delay = 0x0, - .xtal_freq_count = 0x2DD, - }, - { - .freq = 26000000, - .enable_delay = 0x04, - .stable_count = 0x66, - .active_delay = 0x0, - .xtal_freq_count = 0x3E0, - }, -}; - -static struct tegra_utmip_config utmip_default[] = { - [0] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 9, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [2] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup_offset = 0, - .xcvr_use_fuses = 1, - .xcvr_setup = 9, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - -struct usb_phy_plat_data usb_phy_data[] = { - { 0, 0, -1, NULL}, - { 0, 0, -1, NULL}, - { 0, 0, -1, NULL}, -}; - -static int utmip_pad_open(struct tegra_usb_phy *phy) +#ifdef DEBUG +#define DBG(stuff...) pr_info("usb_phy: " stuff) +#else +#define DBG(stuff...) do {} while (0) +#endif + +static void print_usb_plat_data_info(struct tegra_usb_phy *phy) { - phy->pad_clk = clk_get_sys("utmip-pad", NULL); - if (IS_ERR(phy->pad_clk)) { - pr_err("%s: can't get utmip pad clock\n", __func__); - return PTR_ERR(phy->pad_clk); - } + struct tegra_usb_platform_data *pdata = phy->pdata; + char op_mode[][50] = { + "TEGRA_USB_OPMODE_DEVICE", + "TEGRA_USB_OPMODE_HOST" + }; + char phy_intf[][50] = { + "USB_PHY_INTF_UTMI", + "USB_PHY_INTF_ULPI_LINK", + "USB_PHY_INTF_ULPI_NULL", + "USB_PHY_INTF_HSIC", + "USB_PHY_INTF_ICUSB" + }; - if (phy->instance == 0) { - phy->pad_regs = phy->regs; + pr_info("tegra USB phy - inst[%d] platform info:\n", phy->inst); + pr_info("port_otg: %s\n", pdata->port_otg ? "yes" : "no"); + pr_info("has_hostpc: %s\n", pdata->has_hostpc ? "yes" : "no"); + pr_info("phy_interface: %s\n", phy_intf[pdata->phy_intf]); + pr_info("op_mode: %s\n", op_mode[pdata->op_mode]); + if (pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + pr_info("vbus_pmu_irq: %d\n", pdata->u_data.dev.vbus_pmu_irq); + pr_info("vbus_gpio: %d\n", pdata->u_data.dev.vbus_gpio); + pr_info("charging: %s\n", pdata->u_data.dev.charging_supported ? + "enabled" : "disabled"); + pr_info("remote_wakeup: %s\n", pdata->u_data.dev.remote_wakeup_supported + ? "enabled" : "disabled"); } else { - phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); - if (!phy->pad_regs) { - pr_err("%s: can't remap usb registers\n", __func__); - clk_put(phy->pad_clk); - return -ENOMEM; - } + pr_info("vbus_gpio: %d\n", pdata->u_data.host.vbus_gpio); + pr_info("vbus_reg: %s\n", pdata->u_data.host.vbus_reg ? + pdata->u_data.host.vbus_reg : "NULL"); + pr_info("hot_plug: %s\n", pdata->u_data.host.hot_plug ? + "enabled" : "disabled"); + pr_info("remote_wakeup: %s\n", pdata->u_data.host.remote_wakeup_supported + ? "enabled" : "disabled"); } - return 0; } -static void utmip_pad_close(struct tegra_usb_phy *phy) +static void usb_host_vbus_enable(struct tegra_usb_phy *phy, bool enable) { - if (phy->instance != 0) - iounmap(phy->pad_regs); - clk_put(phy->pad_clk); -} - -static int utmip_pad_power_on(struct tegra_usb_phy *phy) -{ - unsigned long val, flags; - void __iomem *base = phy->pad_regs; - - clk_enable(phy->pad_clk); - - spin_lock_irqsave(&utmip_pad_lock, flags); - - utmip_pad_count++; - val = readl(base + UTMIP_BIAS_CFG0); - val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val |= UTMIP_HSSQUELCH_LEVEL(0x2) | UTMIP_HSDISCON_LEVEL(0x1) | - UTMIP_HSDISCON_LEVEL_MSB; -#endif - writel(val, base + UTMIP_BIAS_CFG0); - - spin_unlock_irqrestore(&utmip_pad_lock, flags); - - clk_disable(phy->pad_clk); - - return 0; -} - -static int utmip_pad_power_off(struct tegra_usb_phy *phy, bool is_dpd) -{ - unsigned long val, flags; - void __iomem *base = phy->pad_regs; - - if (!utmip_pad_count) { - pr_err("%s: utmip pad already powered off\n", __func__); - return -EINVAL; - } - - clk_enable(phy->pad_clk); - - spin_lock_irqsave(&utmip_pad_lock, flags); - - if (--utmip_pad_count == 0 && is_dpd) { - val = readl(base + UTMIP_BIAS_CFG0); - val |= UTMIP_OTGPD | UTMIP_BIASPD; -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val &= ~(UTMIP_HSSQUELCH_LEVEL(~0) | UTMIP_HSDISCON_LEVEL(~0) | - UTMIP_HSDISCON_LEVEL_MSB); -#endif - writel(val, base + UTMIP_BIAS_CFG0); + if (phy->vbus_reg) { + if (enable) + regulator_enable(phy->vbus_reg); + else + regulator_disable(phy->vbus_reg); + } else { + int gpio = phy->pdata->u_data.host.vbus_gpio; + if (gpio == -1) + return; + gpio_set_value_cansleep(gpio, enable ? 1 : 0); } - - spin_unlock_irqrestore(&utmip_pad_lock, flags); - - clk_disable(phy->pad_clk); - - return 0; } -static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result) +int usb_phy_reg_status_wait(void __iomem *reg, u32 mask, + u32 result, u32 timeout) { - unsigned long timeout = 2500; do { if ((readl(reg) & mask) == result) return 0; udelay(1); timeout--; } while (timeout); - return -1; -} -static int utmi_wait_register_timeout(void __iomem *reg, u32 mask, u32 result, - unsigned long timeout) -{ - do { - if ((readl(reg) & mask) == result) - return 0; - udelay(1); - timeout--; - } while (timeout); return -1; } -static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (phy->instance == 0) { - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - - udelay(10); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - } - - if (phy->instance == 2) { - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_PHCD; - writel(val, base + USB_PORTSC1); - } -#else - val = readl(base + HOSTPC1_DEVLC); - val |= HOSTPC1_DEVLC_PHCD; - writel(val, base + HOSTPC1_DEVLC); -#endif - if (phy->hotplug) { - val = readl(base + USB_SUSP_CTRL); - val |= USB_PHY_CLK_VALID_INT_ENB; - writel(val, base + USB_SUSP_CTRL); - } else { - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - } - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); -} - -static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - if (phy->instance == 0) { - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - - udelay(10); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - } - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (phy->instance == 2) { - val = readl(base + USB_PORTSC1); - val &= ~USB_PORTSC1_PHCD; - writel(val, base + USB_PORTSC1); - } -#endif - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, - USB_PHY_CLK_VALID) < 0) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); -} - -static void vbus_enable(struct tegra_usb_phy *phy) +int tegra_usb_phy_init_ops(struct tegra_usb_phy *phy) { -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - int gpio_status; - int gpio = usb_phy_data[phy->instance].vbus_gpio; - - if (gpio == -1) - return; - - gpio_status = gpio_request(gpio,"VBUS_USB"); - if (gpio_status < 0) { - printk("VBUS_USB request GPIO FAILED\n"); - WARN_ON(1); - return; - } - if (gpio < TEGRA_NR_GPIOS) tegra_gpio_enable(gpio); - gpio_status = gpio_direction_output(gpio, 1); - if (gpio_status < 0) { - printk("VBUS_USB request GPIO DIRECTION FAILED \n"); - WARN_ON(1); - return; - } - gpio_set_value_cansleep(gpio, 1); -#else - if (phy->reg_vbus) - regulator_enable(phy->reg_vbus); -#endif -} + int err = 0; -static void vbus_disable(struct tegra_usb_phy *phy) -{ -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - int gpio = usb_phy_data[phy->instance].vbus_gpio; - - if (gpio == -1) - return; + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - gpio_set_value_cansleep(gpio, 0); - gpio_free(gpio); -#else - if (phy->reg_vbus) - regulator_disable(phy->reg_vbus); -#endif -} - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC -static void utmip_phy_enable_trking_data(struct tegra_usb_phy *phy) -{ - void __iomem *base = phy->pad_regs; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - static bool init_done = false; - u32 val; - - /* Should be done only once after system boot */ - if (init_done) - return; - - clk_enable(phy->pad_clk); - /* Bias pad MASTER_ENABLE=1 */ - val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - val |= BIAS_MASTER_PROG_VAL; - writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - - /* Setting the tracking length time */ - val = readl(base + UTMIP_BIAS_CFG1); - val &= ~UTMIP_BIAS_PDTRK_COUNT(~0); - val |= UTMIP_BIAS_PDTRK_COUNT(5); - writel(val, base + UTMIP_BIAS_CFG1); - - /* Bias PDTRK is Shared and MUST be done from USB1 ONLY, PD_TRK=0 */ - val = readl(base + UTMIP_BIAS_CFG1); - val &= ~ UTMIP_BIAS_PDTRK_POWERDOWN; - writel(val, base + UTMIP_BIAS_CFG1); - - val = readl(base + UTMIP_BIAS_CFG1); - val |= UTMIP_BIAS_PDTRK_POWERUP; - writel(val, base + UTMIP_BIAS_CFG1); - - /* Wait for 25usec */ - udelay(25); - - /* Bias pad MASTER_ENABLE=0 */ - val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - val &= ~BIAS_MASTER_PROG_VAL; - writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - - /* Wait for 1usec */ - udelay(1); - - /* Bias pad MASTER_ENABLE=1 */ - val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - val |= BIAS_MASTER_PROG_VAL; - writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - - /* Read RCTRL and TCTRL from UTMIP space */ - val = readl(base + UTMIP_BIAS_STS0); - utmip_rctrl_val = ffz(UTMIP_RCTRL_VAL(val)); - utmip_tctrl_val = ffz(UTMIP_TCTRL_VAL(val)); - - /* PD_TRK=1 */ - val = readl(base + UTMIP_BIAS_CFG1); - val |= UTMIP_BIAS_PDTRK_POWERDOWN; - writel(val, base + UTMIP_BIAS_CFG1); - - /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ - val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); - val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); - writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); - clk_disable(phy->pad_clk); - init_done = true; -} - -static void utmip_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->instance; - - /* power down UTMIP interfaces */ - val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); - val |= UTMIP_PWR(inst); - writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); - - /* setup sleep walk usb controller */ - val = UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_HIGHZ_A | - UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_HIGHZ_B | - UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_HIGHZ_C | - UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_HIGHZ_D; - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - - /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ - val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); - val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); - writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); - - /* Turn over pad configuration to PMC */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, ~0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE) | - UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | - UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst); - writel(val, pmc_base + PMC_SLEEP_CFG); -} + if (phy->pdata->has_hostpc) + err = tegra3_usb_phy_init_ops(phy); + else + err = tegra2_usb_phy_init_ops(phy); -static void utmip_powerup_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->instance; - - /* Disable PMC master mode by clearing MASTER_EN */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~(UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | - UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst)); - writel(val, pmc_base + PMC_SLEEP_CFG); - mdelay(1); + return err; } -static void uhsic_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy) +static irqreturn_t usb_phy_dev_vbus_pmu_irq_thr(int irq, void *pdata) { - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - - /* turn on pad detectors for HSIC*/ - val = readl(pmc_base + PMC_USB_AO); - val |= (HSIC_RESERVED_P0 | HSIC_STOBE_VAL_PD_P0 | HSIC_DATA_VAL_PD_P0); - writel(val, pmc_base + PMC_USB_AO); - - /* enable pull downs on HSIC PMC */ - val = UHSIC_STRB_RPD_A | UHSIC_DATA_RPD_A | UHSIC_STRB_RPD_B | - UHSIC_DATA_RPD_B | UHSIC_STRB_RPD_C | UHSIC_DATA_RPD_C | - UHSIC_STRB_RPD_D | UHSIC_DATA_RPD_D; - writel(val, pmc_base + UHSIC_SLEEPWALK_REG); - - /* Turn over pad configuration to PMC */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UHSIC_WAKE_VAL_P0(~0); - val |= UHSIC_WAKE_VAL_P0(WAKE_VAL_NONE) | UHSIC_MASTER_ENABLE_P0; - writel(val, pmc_base + PMC_SLEEP_CFG); -} + /* FIXME : Need to enable pmu vbus handling */ -static void uhsic_powerup_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - - /* turn on pad detectors for HSIC*/ - val = readl(pmc_base + PMC_USB_AO); - val &= ~(HSIC_RESERVED_P0 | HSIC_STOBE_VAL_PD_P0 | HSIC_DATA_VAL_PD_P0); - writel(val, pmc_base + PMC_USB_AO); - - /* Disable PMC master mode by clearing MASTER_EN */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~(UHSIC_MASTER_ENABLE_P0); - writel(val, pmc_base + PMC_SLEEP_CFG); - mdelay(1); + return IRQ_NONE; } -#endif -static unsigned int tegra_phy_xcvr_setup_value(struct tegra_utmip_config *cfg) +static void tegra_usb_phy_release_clocks(struct tegra_usb_phy *phy) { - signed long val; - - if (cfg->xcvr_use_fuses) { - val = FUSE_USB_CALIB_XCVR_SETUP( - tegra_fuse_readl(FUSE_USB_CALIB_0)); - if (cfg->xcvr_setup_offset <= UTMIP_XCVR_MAX_OFFSET) - val = val + cfg->xcvr_setup_offset; - - if (val > UTMIP_XCVR_SETUP_MAX_VALUE) { - val = UTMIP_XCVR_SETUP_MAX_VALUE; - pr_info("%s: reset XCVR_SETUP to max value\n", - __func__); - } else if (val < UTMIP_XCVR_SETUP_MIN_VALUE) { - val = UTMIP_XCVR_SETUP_MIN_VALUE; - pr_info("%s: reset XCVR_SETUP to min value\n", - __func__); - } - } else { - val = cfg->xcvr_setup; - } - - return (unsigned int)val; + clk_put(phy->emc_clk); + clk_put(phy->sys_clk); + clk_put(phy->ctrlr_clk); + clk_disable(phy->pllu_clk); + clk_put(phy->pllu_clk); } -static int utmi_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) +static int tegra_usb_phy_get_clocks(struct tegra_usb_phy *phy) { - unsigned long val; - void __iomem *base = phy->regs; - unsigned int xcvr_setup_value; - struct tegra_utmip_config *config = phy->config; - - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (phy->instance == 0) { - val = readl(base + USB1_LEGACY_CTRL); - val |= USB1_NO_LEGACY_MODE; - writel(val, base + USB1_LEGACY_CTRL); - } -#endif - - val = readl(base + UTMIP_TX_CFG0); - val |= UTMIP_FS_PREABMLE_J; - writel(val, base + UTMIP_TX_CFG0); - - val = readl(base + UTMIP_HSRX_CFG0); - val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0)); - val |= UTMIP_IDLE_WAIT(config->idle_wait_delay); - val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit); - writel(val, base + UTMIP_HSRX_CFG0); - - val = readl(base + UTMIP_HSRX_CFG1); - val &= ~UTMIP_HS_SYNC_START_DLY(~0); - val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay); - writel(val, base + UTMIP_HSRX_CFG1); - - val = readl(base + UTMIP_DEBOUNCE_CFG0); - val &= ~UTMIP_BIAS_DEBOUNCE_A(~0); - val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce); - writel(val, base + UTMIP_DEBOUNCE_CFG0); - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE; - writel(val, base + UTMIP_MISC_CFG0); - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + UTMIP_MISC_CFG1); - val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0)); - val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) | - UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count); - writel(val, base + UTMIP_MISC_CFG1); - - val = readl(base + UTMIP_PLL_CFG1); - val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0)); - val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) | - UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); - writel(val, base + UTMIP_PLL_CFG1); -#endif + int err = 0; - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { - val = readl(base + USB_SUSP_CTRL); - val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV); - writel(val, base + USB_SUSP_CTRL); + phy->pllu_clk = clk_get_sys(NULL, "pll_u"); + if (IS_ERR(phy->pllu_clk)) { + ERR("inst:[%d] Can't get pllu_clk clock\n", phy->inst); + err = PTR_ERR(phy->pllu_clk); + goto fail_pll; } + clk_enable(phy->pllu_clk); - utmip_pad_power_on(phy); - - xcvr_setup_value = phy->xcvr_setup_value; - - val = readl(base + UTMIP_XCVR_CFG0); - val &= ~(UTMIP_XCVR_LSBIAS_SEL | UTMIP_FORCE_PD_POWERDOWN | - UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN | - UTMIP_XCVR_SETUP(~0) | UTMIP_XCVR_LSFSLEW(~0) | - UTMIP_XCVR_LSRSLEW(~0) | UTMIP_XCVR_HSSLEW_MSB(~0)); - val |= UTMIP_XCVR_SETUP(xcvr_setup_value); - val |= UTMIP_XCVR_SETUP_MSB(XCVR_SETUP_MSB_CALIB(xcvr_setup_value)); - val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); - val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val |= UTMIP_XCVR_HSSLEW_MSB(0x8); -#endif - writel(val, base + UTMIP_XCVR_CFG0); - - val = readl(base + UTMIP_XCVR_CFG1); - val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | - UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0)); - val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj); - writel(val, base + UTMIP_XCVR_CFG1); - - val = readl(base + UTMIP_BAT_CHRG_CFG0); - if (phy->mode == TEGRA_USB_PHY_MODE_HOST) - val |= UTMIP_PD_CHRG; - else - val &= ~UTMIP_PD_CHRG; - writel(val, base + UTMIP_BAT_CHRG_CFG0); - - val = readl(base + UTMIP_BIAS_CFG1); - val &= ~UTMIP_BIAS_PDTRK_COUNT(~0); - val |= UTMIP_BIAS_PDTRK_COUNT(phy->freq->pdtrk_count); - writel(val, base + UTMIP_BIAS_CFG1); - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + UTMIP_SPARE_CFG0); - val &= ~FUSE_SETUP_SEL; - writel(val, base + UTMIP_SPARE_CFG0); - - if (phy->instance == 2) { - val = readl(base + UTMIP_SPARE_CFG0); - val |= FUSE_SETUP_SEL; - writel(val, base + UTMIP_SPARE_CFG0); - - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); + phy->ctrlr_clk = clk_get(&phy->pdev->dev, NULL); + if (IS_ERR(phy->ctrlr_clk)) { + dev_err(&phy->pdev->dev, "Can't get controller clock\n"); + err = PTR_ERR(phy->ctrlr_clk); + goto fail_ctrlr_clk; } -#else - val = readl(base + UTMIP_SPARE_CFG0); - val &= ~FUSE_SETUP_SEL; - val |= FUSE_ATERM_SEL; - writel(val, base + UTMIP_SPARE_CFG0); - - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); -#endif - - val = readl(base + USB_SUSP_CTRL); - val &= ~UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - - if (phy->instance == 0) { - val = readl(base + USB1_LEGACY_CTRL); - val &= ~USB1_VBUS_SENSE_CTL_MASK; - val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; - writel(val, base + USB1_LEGACY_CTRL); -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); -#endif - } - - utmi_phy_clk_enable(phy); -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (phy->instance == 2) { - val = readl(base + USB_PORTSC1); - val &= ~USB_PORTSC1_PTS(~0); - writel(val, base + USB_PORTSC1); - } -#else - if (phy->instance == 0) - utmip_phy_enable_trking_data(phy); - - if(phy->instance == 2) { - writel(0, base + ICUSB_CTRL); + phy->sys_clk = clk_get(&phy->pdev->dev, "sclk"); + if (IS_ERR(phy->sys_clk)) { + dev_err(&phy->pdev->dev, "Can't get sclk clock\n"); + err = PTR_ERR(phy->sys_clk); + goto fail_sclk; } + clk_set_rate(phy->sys_clk, 80000000); - if (phy->mode == TEGRA_USB_PHY_MODE_HOST) { - val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET); - writel((val | TEGRA_USB_USBMODE_HOST), - (base + TEGRA_USB_USBMODE_REG_OFFSET)); + phy->emc_clk = clk_get(&phy->pdev->dev, "emc"); + if (IS_ERR(phy->emc_clk)) { + dev_err(&phy->pdev->dev, "Can't get emc clock\n"); + err = PTR_ERR(phy->emc_clk); + goto fail_emc; } - val = readl(base + HOSTPC1_DEVLC); - val &= ~HOSTPC1_DEVLC_PTS(~0); - val |= HOSTPC1_DEVLC_STS; - writel(val, base + HOSTPC1_DEVLC); - - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) - utmip_powerup_pmc_wake_detect(phy); -#endif - return 0; -} - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC -static void utmip_setup_pmc_wake_detect(struct tegra_usb_phy *phy) -{ - unsigned long val, pmc_pad_cfg_val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->instance; - void __iomem *base = phy->regs; - bool port_connected; - enum tegra_usb_phy_port_speed port_speed; - - /* check for port connect status */ - val = readl(base + USB_PORTSC1); - port_connected = val & USB_PORTSC1_CCS; - - if (!port_connected) - return; - - port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) & - HOSTPC1_DEVLC_PSPD_MASK; - /*Set PMC MASTER bits to do the following - * a. Take over the UTMI drivers - * b. set up such that it will take over resume - * if remote wakeup is detected - * Prepare PMC to take over suspend-wake detect-drive resume until USB - * controller ready - */ - - /* disable master enable in PMC */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_MASTER_ENABLE(inst); - writel(val, pmc_base + PMC_SLEEP_CFG); - - /* UTMIP_PWR_PX=1 for power savings mode */ - val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); - val |= UTMIP_PWR(inst); - writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); - - /* config debouncer */ - val = readl(pmc_base + PMC_USB_DEBOUNCE); - val &= ~UTMIP_LINE_DEB_CNT(~0); - val |= UTMIP_LINE_DEB_CNT(1); - writel(val, pmc_base + PMC_USB_DEBOUNCE); - - /* Make sure nothing is happening on the line with respect to PMC */ - val = readl(pmc_base + PMC_UTMIP_UHSIC_FAKE); - val &= ~USBOP_VAL(inst); - val &= ~USBON_VAL(inst); - writel(val, pmc_base + PMC_UTMIP_UHSIC_FAKE); - - /* Make sure wake value for line is none */ - val = readl(pmc_base + PMC_SLEEPWALK_CFG); - val &= ~UTMIP_LINEVAL_WALK_EN(inst); - writel(val, pmc_base + PMC_SLEEPWALK_CFG); - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, ~0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); - writel(val, pmc_base + PMC_SLEEP_CFG); - - /* turn off pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - /* Remove fake values and make synchronizers work a bit */ - val = readl(pmc_base + PMC_UTMIP_UHSIC_FAKE); - val &= ~USBOP_VAL(inst); - val &= ~USBON_VAL(inst); - writel(val, pmc_base + PMC_UTMIP_UHSIC_FAKE); - - /* Enable which type of event can trigger a walk, - in this case usb_line_wake */ - val = readl(pmc_base + PMC_SLEEPWALK_CFG); - val |= UTMIP_LINEVAL_WALK_EN(inst); - writel(val, pmc_base + PMC_SLEEPWALK_CFG); - - /* Enable which type of event can trigger a walk, - * in this case usb_line_wake */ - val = readl(pmc_base + PMC_SLEEPWALK_CFG); - val |= UTMIP_LINEVAL_WALK_EN(inst); - writel(val, pmc_base + PMC_SLEEPWALK_CFG); - - /* Clear the walk pointers and wake alarm */ - val = readl(pmc_base + PMC_TRIGGERS); - val |= UTMIP_CLR_WAKE_ALARM(inst) | UTMIP_CLR_WALK_PTR(inst); - writel(val, pmc_base + PMC_TRIGGERS); - - - /* Capture FS/LS pad configurations */ - pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG); - val = readl(pmc_base + PMC_TRIGGERS); - val |= UTMIP_CAP_CFG(inst); - writel(val, pmc_base + PMC_TRIGGERS); - udelay(1); - pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG); - - /* BIAS MASTER_ENABLE=0 */ - val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - val &= ~BIAS_MASTER_PROG_VAL; - writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL); - - /* program walk sequence, maintain a J, followed by a driven K - * to signal a resume once an wake event is detected */ - val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); - val &= ~UTMIP_AP_A; - val |= UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A| UTMIP_AN_A | UTMIP_HIGHZ_A | - UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_AP_B | UTMIP_AN_B | - UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_AP_C | UTMIP_AN_C | - UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_AP_D | UTMIP_AN_D; - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - - if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) { - val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); - val &= ~(UTMIP_AN_B | UTMIP_HIGHZ_B | UTMIP_AN_C | - UTMIP_HIGHZ_C | UTMIP_AN_D | UTMIP_HIGHZ_D); - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - } else { - val = readl(pmc_base + PMC_SLEEPWALK_REG(inst)); - val &= ~(UTMIP_AP_B | UTMIP_HIGHZ_B | UTMIP_AP_C | - UTMIP_HIGHZ_C | UTMIP_AP_D | UTMIP_HIGHZ_D); - writel(val, pmc_base + PMC_SLEEPWALK_REG(inst)); - } + if(phy->pdata->has_hostpc) + clk_set_rate(phy->emc_clk, 100000000); + else + clk_set_rate(phy->emc_clk, 300000000); - /* turn on pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val &= ~(USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); + return err; - /* Add small delay before usb detectors provide stable line values */ - mdelay(1); +fail_emc: + clk_put(phy->sys_clk); - /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */ - val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG); - val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val); - writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG); +fail_sclk: + clk_put(phy->ctrlr_clk); - phy->remote_wakeup = false; +fail_ctrlr_clk: + clk_disable(phy->pllu_clk); + clk_put(phy->pllu_clk); - /* Turn over pad configuration to PMC for line wake events*/ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, ~0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_ANY); - val |= UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst); - val |= UTMIP_MASTER_ENABLE(inst) | UTMIP_FSLS_USE_PMC(inst); - writel(val, pmc_base + PMC_SLEEP_CFG); +fail_pll: - val = readl(base + UTMIP_PMC_WAKEUP0); - val |= EVENT_INT_ENB; - writel(val, base + UTMIP_PMC_WAKEUP0); + return err; } -#endif -static int utmi_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) +struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev) { - unsigned long val; - void __iomem *base = phy->regs; - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - if (phy->mode == TEGRA_USB_PHY_MODE_HOST) - utmip_setup_pmc_wake_detect(phy); - else - utmip_powerdown_pmc_wake_detect(phy); -#endif - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0); - val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5); - writel(val, base + USB_SUSP_CTRL); - } + struct tegra_usb_phy *phy; + struct tegra_usb_platform_data *pdata; + struct resource *res; + int err; - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { - val = readl(base + UTMIP_BAT_CHRG_CFG0); - val |= UTMIP_PD_CHRG; - writel(val, base + UTMIP_BAT_CHRG_CFG0); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, pdev->id); + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + dev_err(&pdev->dev, "inst:[%d] Platform data missing\n", + pdev->id); + return ERR_PTR(-EINVAL); } - if (phy->instance != 2) { - val = readl(base + UTMIP_XCVR_CFG0); - val |= (UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | - UTMIP_FORCE_PDZI_POWERDOWN); - writel(val, base + UTMIP_XCVR_CFG0); + phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); + if (!phy) { + ERR("inst:[%d] malloc usb phy failed\n", pdev->id); + return ERR_PTR(-ENOMEM); } - val = readl(base + UTMIP_XCVR_CFG1); - val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | - UTMIP_FORCE_PDDR_POWERDOWN; - writel(val, base + UTMIP_XCVR_CFG1); - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + UTMIP_BIAS_CFG1); - val |= UTMIP_BIAS_PDTRK_COUNT(0x5); - writel(val, base + UTMIP_BIAS_CFG1); -#endif - if (phy->hotplug) { - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_WKCN; - writel(val, base + USB_PORTSC1); - } - if (phy->instance != 0) { - val = readl(base + UTMIP_BIAS_CFG0); - val |= UTMIP_OTGPD; - writel(val, base + UTMIP_BIAS_CFG0); + phy->pdata = kzalloc(sizeof(struct tegra_usb_platform_data), GFP_KERNEL); + if (!phy->pdata) { + ERR("inst:[%d] malloc usb phy pdata failed\n", pdev->id); + kfree(phy); + return ERR_PTR(-ENOMEM); } - utmi_phy_clk_disable(phy); - - utmip_pad_power_off(phy, true); - return 0; -} + memcpy(phy->pdata, pdata, sizeof(struct tegra_usb_platform_data)); + phy->pdev = pdev; + phy->inst = pdev->id; -static void utmip_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy) -{ -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->instance; - void __iomem *base = phy->regs; - - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, 0x0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); - writel(val, pmc_base + PMC_SLEEP_CFG); - - val = readl(pmc_base + PMC_TRIGGERS); - val |= UTMIP_CLR_WAKE_ALARM(inst) | UTMIP_CLR_WALK_PTR(inst); - writel(val, pmc_base + PMC_TRIGGERS); - - val = readl(base + UTMIP_PMC_WAKEUP0); - val &= ~EVENT_INT_ENB; - writel(val, base + UTMIP_PMC_WAKEUP0); - - /* Disable PMC master mode by clearing MASTER_EN */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~(UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) | - UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst)); - writel(val, pmc_base + PMC_SLEEP_CFG); - - val = readl(pmc_base + PMC_TRIGGERS); - val &= ~UTMIP_CAP_CFG(inst); - writel(val, pmc_base + PMC_TRIGGERS); - - /* turn off pad detectors */ - val = readl(pmc_base + PMC_USB_AO); - val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst)); - writel(val, pmc_base + PMC_USB_AO); - - phy->remote_wakeup = false; -#endif -} + print_usb_plat_data_info(phy); -static void utmi_phy_enable_obs_bus(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ - unsigned long val; - void __iomem *base = phy->regs; - - /* (2LS WAR)is not required for LS and FS devices and is only for HS */ - if (port_speed != TEGRA_USB_PHY_PORT_SPEED_HIGH) { - /* do not enable the OBS bus */ - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); - writel(val, base + UTMIP_MISC_CFG0); - return; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ERR("inst:[%d] failed to get I/O memory\n", phy->inst); + err = -ENXIO; + goto fail_io; } -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* Force DP/DM pulldown active for Host mode */ - val = readl(base + UTMIP_MISC_CFG0); - val |= FORCE_PULLDN_DM | FORCE_PULLDN_DP | - COMB_TERMS | ALWAYS_FREE_RUNNING_TERMS; - writel(val, base + UTMIP_MISC_CFG0); -#endif - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); - if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; - else - val |= UTMIP_DPDM_OBSERVE_SEL_FS_K; - writel(val, base + UTMIP_MISC_CFG0); - udelay(1); - - val = readl(base + UTMIP_MISC_CFG0); - val |= UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - udelay(10); -} -static void utmi_phy_disable_obs_bus(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - /* check if OBS bus is already enabled */ - val = readl(base + UTMIP_MISC_CFG0); - if (val & UTMIP_DPDM_OBSERVE) { - /* Change the UTMIP OBS bus to drive SE0 */ - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); - val |= UTMIP_DPDM_OBSERVE_SEL_FS_SE0; - writel(val, base + UTMIP_MISC_CFG0); - - /* Wait for 3us(2 LS bit times) */ - udelay (3); - - /* Release UTMIP OBS bus */ - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* Release DP/DM pulldown for Host mode */ - val = readl(base + UTMIP_MISC_CFG0); - val &= ~(FORCE_PULLDN_DM | FORCE_PULLDN_DP | - COMB_TERMS | ALWAYS_FREE_RUNNING_TERMS); - writel(val, base + UTMIP_MISC_CFG0); -#endif + phy->regs = ioremap(res->start, resource_size(res)); + if (!phy->regs) { + ERR("inst:[%d] Failed to remap I/O memory\n", phy->inst); + err = -ENOMEM; + goto fail_io; } -} - -static int utmi_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup) -{ -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; - enum tegra_usb_phy_port_speed port_speed; - - val = readl(base + UTMIP_TX_CFG0); - val |= UTMIP_HS_DISCON_DISABLE; - writel(val, base + UTMIP_TX_CFG0); - - port_speed = (readl(base + USB_PORTSC1) >> 26) & 0x3; - if (remote_wakeup && (port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH)) { - val = readl(base + USB_USBCMD); - val &= ~USB_USBCMD_RS; - writel(val, base + USB_USBCMD); - if (utmi_wait_register(base + USB_USBSTS, - USB_USBSTS_HCH, USB_USBSTS_HCH) < 0) { - pr_err("%s: timeout waiting for stopping controller\n", __func__); - return -ETIMEDOUT; - } + phy->vdd_reg = regulator_get(NULL, "avdd_usb"); + if (IS_ERR_OR_NULL(phy->vdd_reg)) { + ERR("inst:[%d] couldn't get regulator avdd_usb: %ld\n", + phy->inst, PTR_ERR(phy->vdd_reg)); + phy->vdd_reg = NULL; } - utmi_phy_enable_obs_bus(phy, port_speed); -#else - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - unsigned int inst = phy->instance; - void __iomem *base = phy->regs; - enum tegra_usb_phy_port_speed port_speed; - - val = readl(pmc_base + PMC_SLEEP_CFG); - if (val & UTMIP_MASTER_ENABLE(inst)) { - if (!remote_wakeup) - utmip_phy_disable_pmc_bus_ctrl(phy); - } else { - port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) & - HOSTPC1_DEVLC_PSPD_MASK; - utmi_phy_enable_obs_bus(phy, port_speed); + err = tegra_usb_phy_get_clocks(phy); + if (err) { + ERR("inst:[%d] Failed to init clocks\n", phy->inst); + goto fail_clk; } -#endif - - return 0; -} -static int utmi_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd) -{ - unsigned long val; -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) - void __iomem *base = phy->regs; -#else - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); -#endif - unsigned int inst = phy->instance; - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(pmc_base + PMC_SLEEP_CFG); - /* if PMC is not disabled by now then disable it */ - if (val & UTMIP_MASTER_ENABLE(inst)) { - utmip_phy_disable_pmc_bus_ctrl(phy); - } - utmi_phy_disable_obs_bus(phy); -#else - val = readl(base + USB_USBCMD); - if (val & USB_USBCMD_RS) { - val &= ~USB_USBCMD_RS; - writel(val, base + USB_USBCMD); - if (utmi_wait_register(base + USB_USBSTS, - USB_USBSTS_HCH, USB_USBSTS_HCH) < 0) { - pr_err("%s: timeout waiting for stopping controller\n", __func__); - return -ETIMEDOUT; + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + if (phy->pdata->u_data.dev.vbus_pmu_irq) { + err = request_threaded_irq( + phy->pdata->u_data.dev.vbus_pmu_irq, + NULL, usb_phy_dev_vbus_pmu_irq_thr, + IRQF_SHARED, "usb_pmu_vbus_irq", phy); + if (err) { + ERR("inst:[%d] Failed to register IRQ\n", + phy->inst); + goto fail_init; + } + } + } else { + if (phy->pdata->u_data.host.vbus_reg) { + phy->vbus_reg = regulator_get(NULL, + phy->pdata->u_data.host.vbus_reg); + if (WARN_ON(IS_ERR_OR_NULL(phy->vbus_reg))) { + ERR("failed to get regulator vdd_vbus_usb: %ld,\ + instance : %d\n", PTR_ERR(phy->vbus_reg), + phy->inst); + err = PTR_ERR(phy->vbus_reg); + goto fail_init; + } + } else { + int gpio = phy->pdata->u_data.host.vbus_gpio; + if (gpio != -1) { + if (gpio_request(gpio, "usb_host_vbus") < 0) { + ERR("inst:[%d] host vbus gpio \ + req failed\n", phy->inst); + goto fail_init; + } + if (gpio < TEGRA_NR_GPIOS) + tegra_gpio_enable(gpio); + if (gpio_direction_output(gpio, 1) < 0) { + ERR("inst:[%d] host vbus gpio \ + dir failed\n", phy->inst); + goto fail_init; + } + } } + usb_host_vbus_enable(phy, true); } - writel(val, base + USB_USBCMD); - utmi_phy_disable_obs_bus(phy); - val = readl(base + USB_USBCMD); - val |= USB_USBCMD_RS; - writel(val, base + USB_USBCMD); - val = readl(base + UTMIP_TX_CFG0); - val &= ~UTMIP_HS_DISCON_DISABLE; - writel(val, base + UTMIP_TX_CFG0); -#endif + err = tegra_usb_phy_init_ops(phy); + if (err) { + ERR("inst:[%d] Failed to init ops\n", phy->inst); + goto fail_init; + } - return 0; -} - -static int uhsic_phy_postsuspend(struct tegra_usb_phy *phy, bool is_dpd) -{ - struct tegra_uhsic_config *uhsic_config = phy->config; - - if (uhsic_config->postsuspend) - uhsic_config->postsuspend(); - - return 0; -} - -static int uhsic_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup) -{ - struct tegra_uhsic_config *uhsic_config = phy->config; - - if (uhsic_config->preresume) - uhsic_config->preresume(); - - return 0; -} - -static int usb_phy_set_tx_fill_tuning(struct tegra_usb_phy *phy, bool is_dpd) -{ - unsigned long val; - void __iomem *base = phy->regs; + if (phy->pdata->ops && phy->pdata->ops->open) + phy->pdata->ops->open(); - val = readl(base + USB_TXFILLTUNING); - if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) { - val = USB_FIFO_TXFILL_THRES(0x10); - writel(val, base + USB_TXFILLTUNING); + if (phy->ops && phy->ops->open) { + err = phy->ops->open(phy); + if (err) { + ERR("inst:[%d] Failed to open hw ops\n", phy->inst); + goto fail_init; + } } - return 0; -} + if (phy->vdd_reg) + regulator_enable(phy->vdd_reg); -static void utmi_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; + return phy; - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); - if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= UTMIP_DPDM_OBSERVE_SEL_FS_K; - else - val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; - writel(val, base + UTMIP_MISC_CFG0); - udelay(1); - - val = readl(base + UTMIP_MISC_CFG0); - val |= UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - udelay(10); -#else - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - int inst = phy->instance; +fail_init: + tegra_usb_phy_release_clocks(phy); - val = readl(pmc_base + UTMIP_UHSIC_STATUS); - /* check whether we wake up from the remote resume */ - if (UTMIP_WALK_PTR_VAL(inst) & val) { - phy->remote_wakeup = true; + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + if (phy->pdata->u_data.dev.vbus_pmu_irq) + free_irq(phy->pdata->u_data.dev.vbus_pmu_irq, phy); } else { - if (!((UTMIP_USBON_VAL(phy->instance) | - UTMIP_USBOP_VAL(phy->instance)) & val)) { - utmip_phy_disable_pmc_bus_ctrl(phy); - } - } - utmi_phy_enable_obs_bus(phy, port_speed); -#endif -} - -static void utmi_phy_restore_end(struct tegra_usb_phy *phy) -{ -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - udelay(10); -#else - unsigned long val; - void __iomem *base = phy->regs; - int wait_time_us = 3000; /* FPR should be set by this time */ - - /* check whether we wake up from the remote resume */ - if (phy->remote_wakeup) { - /* wait until FPR bit is set automatically on remote resume */ - do { - val = readl(base + USB_PORTSC1); - udelay(1); - if (wait_time_us == 0) { - utmip_phy_disable_pmc_bus_ctrl(phy); - tegra_usb_phy_postresume(phy, false); - return; + usb_host_vbus_enable(phy, false); + + if (phy->vbus_reg) + regulator_put(phy->vbus_reg); + else { + int gpio = phy->pdata->u_data.host.vbus_gpio; + if (gpio != -1) { + gpio_set_value_cansleep(gpio, 0); + gpio_free(gpio); } - wait_time_us--; - } while (!(val & USB_PORTSC1_RESUME)); - /* wait for 25 ms to port resume complete */ - msleep(25); - /* disable PMC master control */ - utmip_phy_disable_pmc_bus_ctrl(phy); - - /* Clear PCI and SRI bits to avoid an interrupt upon resume */ - val = readl(base + USB_USBSTS); - writel(val, base + USB_USBSTS); - /* wait to avoid SOF if there is any */ - if (utmi_wait_register(base + USB_USBSTS, - USB_USBSTS_SRI, USB_USBSTS_SRI) < 0) { - pr_err("%s: timeout waiting for SOF\n", __func__); } - tegra_usb_phy_postresume(phy, false); } -#endif -} - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC -static void ulpi_set_tristate(bool enable) -{ - int tristate = (enable)? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL; - - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate); -} -#endif -static void ulpi_phy_reset(void __iomem *base) -{ - unsigned long val; - - val = readl(base + USB_SUSP_CTRL); - val |= UHSIC_RESET; - writel(val, base + USB_SUSP_CTRL); - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); -#endif -} - -static void ulpi_set_host(void __iomem *base) -{ -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - - val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET); - val |= TEGRA_USB_USBMODE_HOST; - writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET); - - val = readl(base + HOSTPC1_DEVLC); - val |= HOSTPC1_DEVLC_PTS(2); - writel(val, base + HOSTPC1_DEVLC); -#endif -} - -static void ulpi_set_trimmer(void __iomem *base, u8 data, u8 sdn, u8 dir) -{ - unsigned long val; - - val = ULPI_DATA_TRIMMER_SEL(data); - val |= ULPI_STPDIRNXT_TRIMMER_SEL(sdn); - val |= ULPI_DIR_TRIMMER_SEL(dir); - writel(val, base + ULPI_TIMING_CTRL_1); - udelay(10); - - val |= ULPI_DATA_TRIMMER_LOAD; - val |= ULPI_STPDIRNXT_TRIMMER_LOAD; - val |= ULPI_DIR_TRIMMER_LOAD; - writel(val, base + ULPI_TIMING_CTRL_1); -} - -static inline void ulpi_pinmux_bypass(struct tegra_usb_phy *phy, bool enable) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + ULPI_TIMING_CTRL_0); - - if (enable) - val |= ULPI_OUTPUT_PINMUX_BYP; - else - val &= ~ULPI_OUTPUT_PINMUX_BYP; - - writel(val, base + ULPI_TIMING_CTRL_0); -} - -static void ulpi_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; - - /*Tristate ulpi interface before USB controller resume*/ - ulpi_set_tristate(true); +fail_clk: + regulator_put(phy->vdd_reg); + iounmap(phy->regs); +fail_io: + kfree(phy); - val = readl(base + ULPI_TIMING_CTRL_0); - val &= ~ULPI_OUTPUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); -#endif + return ERR_PTR(err); } -static void ulpi_phy_restore_end(struct tegra_usb_phy *phy) -{ -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_OUTPUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); - ulpi_set_tristate(false); -#endif -} -static int ulpi_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) +void tegra_usb_phy_close(struct tegra_usb_phy *phy) { - int ret; - unsigned long val; - void __iomem *base = phy->regs; -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - struct tegra_ulpi_config *config = phy->config; -#endif - - if (phy->clk) - clk_enable(phy->clk); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - msleep(1); - - if (!phy->initialized) { - phy->initialized = 1; -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - gpio_direction_output(config->reset_gpio, 0); - msleep(5); - gpio_direction_output(config->reset_gpio, 1); -#endif + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { + if (phy->pdata->u_data.dev.vbus_pmu_irq) + free_irq(phy->pdata->u_data.dev.vbus_pmu_irq, phy); + } else { + usb_host_vbus_enable(phy, false); + + if (phy->vbus_reg) + regulator_put(phy->vbus_reg); + else { + int gpio = phy->pdata->u_data.host.vbus_gpio; + if (gpio != -1) { + gpio_set_value_cansleep(gpio, 0); + gpio_free(gpio); + } + } } - ulpi_phy_reset(base); - ulpi_set_host(base); - - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); - - val = readl(base + USB_SUSP_CTRL); - val |= ULPI_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, - USB_PHY_CLK_VALID) < 0) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_CLKEN, USB_CLKEN) < 0) - pr_err("%s: timeout waiting for AHB clock\n", __func__); -#else - udelay(100); -#endif - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - - val = 0; - writel(val, base + ULPI_TIMING_CTRL_1); + tegra_usb_phy_release_clocks(phy); - ulpi_set_trimmer(base, 4, 4, 4); - - /* Fix VbusInvalid due to floating VBUS */ - ret = otg_io_write(phy->ulpi, 0x40, 0x08); - if (ret) { - pr_err("%s: ulpi write failed\n", __func__); - return ret; - } - - ret = otg_io_write(phy->ulpi, 0x80, 0x0B); - if (ret) { - pr_err("%s: ulpi write failed\n", __func__); - return ret; + if (phy->vdd_reg) { + regulator_disable(phy->vdd_reg); + regulator_put(phy->vdd_reg); } - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN; - writel(val, base + USB_PORTSC1); - - return 0; -} - -static int ulpi_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) -{ - unsigned long val; - void __iomem *base = phy->regs; -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - int ret; - - /* Disable VbusValid, SessEnd comparators */ - ret = otg_io_write(phy->ulpi, 0x00, 0x0D); - if (ret) - pr_err("%s: ulpi write 0x0D failed\n", __func__); - - ret = otg_io_write(phy->ulpi, 0x00, 0x10); - if (ret) - pr_err("%s: ulpi write 0x10 failed\n", __func__); - - /* Disable IdFloat comparator */ - ret = otg_io_write(phy->ulpi, 0x00, 0x19); - if (ret) - pr_err("%s: ulpi write 0x19 failed\n", __func__); - - ret = otg_io_write(phy->ulpi, 0x00, 0x1D); - if (ret) - pr_err("%s: ulpi write 0x1D failed\n", __func__); - - /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB - * Controller to immediately bring the ULPI PHY out of low power - */ - val = readl(base + USB_PORTSC1); - val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN); - writel(val, base + USB_PORTSC1); - - /* Put the PHY in the low power mode */ - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_PHCD; - writel(val, base + USB_PORTSC1); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) - pr_err("%s: timeout waiting for phy to stop\n", __func__); -#else - val = readl(base + HOSTPC1_DEVLC); - val &= ~(HOSTPC1_DEVLC_PHCD); - writel(val, base + HOSTPC1_DEVLC); -#endif + if (phy->ops && phy->ops->close) + phy->ops->close(phy); - if(phy->clk) - clk_disable(phy->clk); + if (phy->pdata->ops && phy->pdata->ops->close) + phy->pdata->ops->close(); - return 0; + kfree(phy->pdata); + kfree(phy); } -static inline void null_phy_set_tristate(bool enable) +irqreturn_t tegra_usb_phy_irq(struct tegra_usb_phy *phy) { - int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL; - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate); -#else - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA0, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA1, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA2, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA3, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA4, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA5, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA6, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA7, tristate); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_NXT, tristate); - - if (enable) - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, tristate); -#endif -} + irqreturn_t status = IRQ_HANDLED; -static void null_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ - struct tegra_ulpi_config *config = phy->config; + if (phy->ops && phy->ops->irq) + status = phy->ops->irq(phy); - if (config->phy_restore_start) - config->phy_restore_start(); + return status; } - -static void null_phy_restore_end(struct tegra_usb_phy *phy) +int tegra_usb_phy_init(struct tegra_usb_phy *phy) { - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_ulpi_config *config = phy->config; + int status = 0; - /* disable ULPI pinmux bypass */ - ulpi_pinmux_bypass(phy, false); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - /* driving linestate using GPIO */ - gpio_set_value(config->ulpi_d0_gpio, 0); - gpio_set_value(config->ulpi_d1_gpio, 0); - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* driving DIR high */ - gpio_set_value(config->ulpi_dir_gpio, 1); -#endif + if (phy->pdata->ops && phy->pdata->ops->init) + phy->pdata->ops->init(); - /* remove ULPI tristate */ - null_phy_set_tristate(false); - - if (config->phy_restore_end) - config->phy_restore_end(); - - if (gpio_is_valid(config->phy_restore_gpio)) { - int phy_restore_gpio = config->phy_restore_gpio; - int retry = 20000; - - while (retry) { - /* poll phy_restore_gpio high */ - if (gpio_get_value(phy_restore_gpio)) - break; - retry--; - } + if (phy->ops && phy->ops->init) + status = phy->ops->init(phy); - if (retry == 0) - pr_info("phy_restore_gpio timeout\n"); - } - - /* enable ULPI CLK output pad */ - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_CLK_PADOUT_ENA; - writel(val, base + ULPI_TIMING_CTRL_0); - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - udelay(5); /* wait for CLK stabilize */ - - /* enable ULPI pinmux bypass */ - ulpi_pinmux_bypass(phy, true); -#else - /* enable ULPI pinmux bypass */ - ulpi_pinmux_bypass(phy, true); - udelay(5); - - /* remove DIR tristate */ - tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, TEGRA_TRI_NORMAL); -#endif + return status; } -static int null_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) +int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) { - const struct tegra_ulpi_trimmer default_trimmer = {0, 0, 4, 4}; - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_ulpi_config *config = phy->config; - static bool cold_boot = true; - - if (!config->trimmer) - config->trimmer = &default_trimmer; - - ulpi_phy_reset(base); - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* remove ULPI PADS CLKEN reset */ - val = readl(base + USB_SUSP_CTRL); - val &= ~ULPI_PADS_CLKEN_RESET; - writel(val, base + USB_SUSP_CTRL); - udelay(10); -#endif - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); - - if (config->pre_phy_on && config->pre_phy_on()) - return -EAGAIN; - - val = readl(base + USB_SUSP_CTRL); - val |= ULPI_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); - udelay(10); - - /* set timming parameters */ - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_SHADOW_CLK_LOOPBACK_EN; -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val &= ~ULPI_SHADOW_CLK_SEL; - val &= ~ULPI_LBK_PAD_EN; -#else - val |= ULPI_SHADOW_CLK_SEL; - val |= ULPI_LBK_PAD_EN; -#endif - val |= ULPI_SHADOW_CLK_DELAY(config->trimmer->shadow_clk_delay); - val |= ULPI_CLOCK_OUT_DELAY(config->trimmer->clock_out_delay); - val |= ULPI_LBK_PAD_E_INPUT_OR; - writel(val, base + ULPI_TIMING_CTRL_0); - - writel(0, base + ULPI_TIMING_CTRL_1); - udelay(10); - - /* start internal 60MHz clock */ - val = readl(base + ULPIS2S_CTRL); - val |= ULPIS2S_ENA; - val |= ULPIS2S_SUPPORT_DISCONNECT; - val |= ULPIS2S_SPARE((phy->mode == TEGRA_USB_PHY_MODE_HOST) ? 3 : 1); - val |= ULPIS2S_PLLU_MASTER_BLASTER60; - writel(val, base + ULPIS2S_CTRL); - - /* select ULPI_CORE_CLK_SEL to SHADOW_CLK */ - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_CORE_CLK_SEL; - writel(val, base + ULPI_TIMING_CTRL_0); - udelay(10); - - /* enable ULPI null phy clock - can't set the trimmers before this */ - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_CLK_OUT_ENA; - writel(val, base + ULPI_TIMING_CTRL_0); - udelay(10); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, - USB_PHY_CLK_VALID)) { - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); - return -ETIMEDOUT; - } + int err = 0; - /* set ULPI trimmers */ - ulpi_set_trimmer(base, config->trimmer->data_trimmer, - config->trimmer->stpdirnxt_trimmer, 1); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - ulpi_set_host(base); + if (!phy->phy_power_on) + return err; -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* remove slave0 reset */ - val = readl(base + USB_SUSP_CTRL); - val &= ~ULPIS2S_SLV0_RESET; - writel(val, base + USB_SUSP_CTRL); - - /* remove slave1 and line reset */ - val = readl(base + USB_SUSP_CTRL); - val &= ~ULPIS2S_SLV1_RESET; - val &= ~ULPIS2S_LINE_RESET; - - /* remove ULPI PADS reset */ - val &= ~ULPI_PADS_RESET; - writel(val, base + USB_SUSP_CTRL); -#endif - if (cold_boot) { - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_CLK_PADOUT_ENA; - writel(val, base + ULPI_TIMING_CTRL_0); - cold_boot = false; + if (phy->ops && phy->ops->power_off) { + if (phy->pdata->ops && phy->pdata->ops->pre_phy_off) + phy->pdata->ops->pre_phy_off(); + err = phy->ops->power_off(phy); + if (phy->pdata->ops && phy->pdata->ops->post_phy_off) + phy->pdata->ops->post_phy_off(); } - udelay(10); - - if (config->post_phy_on && config->post_phy_on()) - return -EAGAIN; - - return 0; -} - -static int null_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) -{ - struct tegra_ulpi_config *config = phy->config; - - if (config->pre_phy_off && config->pre_phy_off()) - return -EAGAIN; - - null_phy_set_tristate(true); + clk_disable(phy->emc_clk); + clk_disable(phy->sys_clk); + clk_disable(phy->ctrlr_clk); - if (config->post_phy_off && config->post_phy_off()) - return -EAGAIN; + phy->phy_power_on = false; - return 0; -} - -static int null_phy_pre_usbcmd_reset(struct tegra_usb_phy *phy, bool is_dpd) -{ -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + ULPIS2S_CTRL); - val |= ULPIS2S_SLV0_CLAMP_XMIT; - writel(val, base + ULPIS2S_CTRL); - - val = readl(base + USB_SUSP_CTRL); - val |= ULPIS2S_SLV0_RESET; - writel(val, base + USB_SUSP_CTRL); - udelay(10); -#endif - return 0; -} - -static int null_phy_post_usbcmd_reset(struct tegra_usb_phy *phy, bool is_dpd) -{ -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; - - ulpi_set_host(base); - - /* remove slave0 reset */ - val = readl(base + USB_SUSP_CTRL); - val &= ~ULPIS2S_SLV0_RESET; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + ULPIS2S_CTRL); - val &= ~ULPIS2S_SLV0_CLAMP_XMIT; - writel(val, base + ULPIS2S_CTRL); - udelay(10); -#endif - return 0; + return err; } -static int uhsic_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) +int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) { - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_uhsic_config *uhsic_config = phy->config; - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - uhsic_powerup_pmc_wake_detect(phy); -#endif - - if (uhsic_config->enable_gpio != -1) { - gpio_set_value_cansleep(uhsic_config->enable_gpio, 1); - /* keep hsic reset asserted for 1 ms */ - udelay(1000); - } - - val = readl(base + UHSIC_PADS_CFG1); - val &= ~(UHSIC_PD_BG | UHSIC_PD_TX | UHSIC_PD_TRK | UHSIC_PD_RX | - UHSIC_PD_ZI | UHSIC_RPD_DATA | UHSIC_RPD_STROBE); - val |= UHSIC_RX_SEL; - writel(val, base + UHSIC_PADS_CFG1); - udelay(2); - - val = readl(base + USB_SUSP_CTRL); - val |= UHSIC_RESET; - writel(val, base + USB_SUSP_CTRL); - udelay(30); - - val = readl(base + USB_SUSP_CTRL); - val |= UHSIC_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + UHSIC_HSRX_CFG0); - val |= UHSIC_IDLE_WAIT(uhsic_config->idle_wait_delay); - val |= UHSIC_ELASTIC_UNDERRUN_LIMIT(uhsic_config->elastic_underrun_limit); - val |= UHSIC_ELASTIC_OVERRUN_LIMIT(uhsic_config->elastic_overrun_limit); - writel(val, base + UHSIC_HSRX_CFG0); - - val = readl(base + UHSIC_HSRX_CFG1); - val |= UHSIC_HS_SYNC_START_DLY(uhsic_config->sync_start_delay); - writel(val, base + UHSIC_HSRX_CFG1); - -#ifdef CONFIG_ARCH_TEGRA_3x_SOC - /* WAR HSIC TX */ - val = readl(base + UHSIC_TX_CFG0); - val &= ~UHSIC_HS_READY_WAIT_FOR_VALID; - writel(val, base + UHSIC_TX_CFG0); -#endif - - val = readl(base + UHSIC_MISC_CFG0); - val |= UHSIC_SUSPEND_EXIT_ON_EDGE; -#ifdef CONFIG_ARCH_TEGRA_3x_SOC - /* Disable generic bus reset, to allow AP30 specific bus reset*/ - val |= UHSIC_DISABLE_BUSRESET; -#endif - writel(val, base + UHSIC_MISC_CFG0); - - val = readl(base + UHSIC_MISC_CFG1); - val |= UHSIC_PLLU_STABLE_COUNT(phy->freq->stable_count); - writel(val, base + UHSIC_MISC_CFG1); - - val = readl(base + UHSIC_PLL_CFG1); - val |= UHSIC_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); - val |= UHSIC_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count); - writel(val, base + UHSIC_PLL_CFG1); - - val = readl(base + USB_SUSP_CTRL); - val &= ~(UHSIC_RESET); - writel(val, base + USB_SUSP_CTRL); - udelay(2); - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + USB_PORTSC1); - val &= ~USB_PORTSC1_PTS(~0); - writel(val, base + USB_PORTSC1); - -#endif -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET); - val |= TEGRA_USB_USBMODE_HOST; - writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET); - - /* Change the USB controller PHY type to HSIC */ - val = readl(base + HOSTPC1_DEVLC); - val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK); - val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC); - val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK); - val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED); - writel(val, base + HOSTPC1_DEVLC); -#endif - usb_phy_set_tx_fill_tuning(phy, is_dpd); + int status = 0; - val = readl(base + USB_PORTSC1); - val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN); - writel(val, base + USB_PORTSC1); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - val = readl(base + UHSIC_PADS_CFG0); - val &= ~(UHSIC_TX_RTUNEN); -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* set Rtune impedance to 40 ohm */ - val |= UHSIC_TX_RTUNE(0); -#else - /* set Rtune impedance to 50 ohm */ - val |= UHSIC_TX_RTUNE(8); -#endif - writel(val, base + UHSIC_PADS_CFG0); + if (phy->phy_power_on) + return status; - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, - USB_PHY_CLK_VALID)) { - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); - return -ETIMEDOUT; - } - - return 0; -} + clk_enable(phy->ctrlr_clk); + clk_enable(phy->sys_clk); + clk_enable(phy->emc_clk); -static int uhsic_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) -{ - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_uhsic_config *uhsic_config = phy->config; - - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPU_STROBE; - val |= UHSIC_RPD_STROBE; - writel(val, base + UHSIC_PADS_CFG1); - - val = readl(base + USB_SUSP_CTRL); - val |= UHSIC_RESET; - writel(val, base + USB_SUSP_CTRL); - udelay(30); - - if (uhsic_config->enable_gpio != -1) { - gpio_set_value_cansleep(uhsic_config->enable_gpio, 0); - /* keep hsic reset de-asserted for 1 ms */ - udelay(1000); + if (phy->ops && phy->ops->power_on) { + if (phy->pdata->ops && phy->pdata->ops->pre_phy_on) + phy->pdata->ops->pre_phy_on(); + status = phy->ops->power_on(phy); + if (phy->pdata->ops && phy->pdata->ops->post_phy_on) + phy->pdata->ops->post_phy_on(); } - if (uhsic_config->post_phy_off && uhsic_config->post_phy_off()) - return -EAGAIN; -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - uhsic_powerdown_pmc_wake_detect(phy); -#endif + phy->phy_power_on = true; - return 0; + return status; } -#ifdef CONFIG_USB_TEGRA_OTG -extern void tegra_otg_check_vbus_detection(void); -#endif - -static irqreturn_t usb_phy_vbus_irq_thr(int irq, void *pdata) +int tegra_usb_phy_reset(struct tegra_usb_phy *phy) { - struct tegra_usb_phy *phy = pdata; - - if (phy->reg_vdd && !phy->regulator_on) { - regulator_enable(phy->reg_vdd); - phy->regulator_on = 1; - /* - * Optimal time to get the regulator turned on - * before detecting vbus interrupt. - */ - mdelay(15); - } + int status = 0; -#ifdef CONFIG_USB_TEGRA_OTG - tegra_otg_check_vbus_detection(); -#endif + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->ops && phy->ops->reset) + status = phy->ops->reset(phy); - return IRQ_HANDLED; + return status; } - -struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, - void *config, enum tegra_usb_phy_mode phy_mode, - enum tegra_usb_phy_type usb_phy_type) +int tegra_usb_phy_pre_suspend(struct tegra_usb_phy *phy) { - struct tegra_usb_phy *phy; - struct tegra_ulpi_config *ulpi_config; - unsigned long parent_rate; - int i; - int err; -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - struct tegra_uhsic_config *uhsic_config; - int reset_gpio, enable_gpio; -#endif + int status = 0; - phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); - if (!phy) - return ERR_PTR(-ENOMEM); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - phy->instance = instance; - phy->regs = regs; - phy->config = config; - phy->mode = phy_mode; - phy->usb_phy_type = usb_phy_type; - phy->initialized = 0; - phy->regulator_on = 0; - phy->power_on = 0; - phy->remote_wakeup = false; - phy->hotplug = 0; - phy->xcvr_setup_value = 0; - - if (!phy->config) { - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_LINK_ULPI || - phy->usb_phy_type == TEGRA_USB_PHY_TYPE_NULL_ULPI) { - pr_err("%s: ulpi phy configuration missing", __func__); - err = -EINVAL; - goto err0; - } else { - phy->config = &utmip_default[instance]; - } - } + if (phy->pdata->ops && phy->pdata->ops->pre_suspend) + phy->pdata->ops->pre_suspend(); - phy->pll_u = clk_get_sys(NULL, "pll_u"); - if (IS_ERR(phy->pll_u)) { - pr_err("Can't get pll_u clock\n"); - err = PTR_ERR(phy->pll_u); - goto err0; - } - clk_enable(phy->pll_u); - - parent_rate = clk_get_rate(clk_get_parent(phy->pll_u)); - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { - for (i = 0; i < ARRAY_SIZE(tegra_uhsic_freq_table); i++) { - if (tegra_uhsic_freq_table[i].freq == parent_rate) { - phy->freq = &tegra_uhsic_freq_table[i]; - break; - } - } - } else { - for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) { - if (tegra_freq_table[i].freq == parent_rate) { - phy->freq = &tegra_freq_table[i]; - break; - } - } - } - if (!phy->freq) { - pr_err("invalid pll_u parent rate %ld\n", parent_rate); - err = -EINVAL; - goto err1; - } + if (phy->ops && phy->ops->pre_suspend) + status = phy->ops->pre_suspend(phy); - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - err = utmip_pad_open(phy); - phy->xcvr_setup_value = tegra_phy_xcvr_setup_value(phy->config); - if (err < 0) - goto err1; - } else if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_LINK_ULPI) { - ulpi_config = config; - - if (ulpi_config->clk) { - phy->clk = clk_get_sys(NULL, ulpi_config->clk); - if (IS_ERR(phy->clk)) { - pr_err("%s: can't get ulpi clock\n", __func__); - err = -ENXIO; - goto err1; - } - } else { - /* Some USB ULPI chips are not driven by Tegra clocks or PLL */ - phy->clk = NULL; - } - tegra_gpio_enable(ulpi_config->reset_gpio); - gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b"); - gpio_direction_output(ulpi_config->reset_gpio, 0); - phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); - phy->ulpi->io_priv = regs + ULPI_VIEWPORT; - } -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - else if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { - uhsic_config = config; - enable_gpio = gpio_request(uhsic_config->enable_gpio, - "uhsic_enable"); - reset_gpio = gpio_request(uhsic_config->reset_gpio, - "uhsic_reset"); - /* hsic enable signal deasserted, hsic reset asserted */ - if (!enable_gpio) - gpio_direction_output(uhsic_config->enable_gpio, - 0 /* deasserted */); - if (!reset_gpio) - gpio_direction_output(uhsic_config->reset_gpio, - 0 /* asserted */); - if (!enable_gpio) - tegra_gpio_enable(uhsic_config->enable_gpio); - if (!reset_gpio) - tegra_gpio_enable(uhsic_config->reset_gpio); - /* keep hsic reset asserted for 1 ms */ - udelay(1000); - /* enable (power on) hsic */ - if (!enable_gpio) - gpio_set_value_cansleep(uhsic_config->enable_gpio, 1); - udelay(1000); - /* deassert reset */ - if (!reset_gpio) - gpio_set_value_cansleep(uhsic_config->reset_gpio, 1); - } -#endif - - phy->reg_vdd = regulator_get(NULL, "avdd_usb"); - if (IS_ERR_OR_NULL(phy->reg_vdd)) { - pr_err("couldn't get regulator avdd_usb: %ld \n", - PTR_ERR(phy->reg_vdd)); - phy->reg_vdd = NULL; - } - - if (instance == 0 && usb_phy_data[0].vbus_irq) { - err = request_threaded_irq(usb_phy_data[0].vbus_irq, NULL, usb_phy_vbus_irq_thr, IRQF_SHARED, - "usb_phy_vbus", phy); - if (err) { - pr_err("Failed to register IRQ\n"); - goto err1; - } - } - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* Power-up the VBUS detector for UTMIP PHY */ - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - - /* turn on pad detectors for HSIC*/ - val = readl(pmc_base + PMC_USB_AO); - val &= ~(TEGRA_PMC_USB_AO_VBUS_WAKEUP_PD_P0 | TEGRA_PMC_USB_AO_ID_PD_P0); - writel(val, pmc_base + PMC_USB_AO); - - utmip_powerup_pmc_wake_detect(phy); - - if (usb_phy_data[phy->instance].vbus_reg_supply) { - phy->reg_vbus = regulator_get(NULL, usb_phy_data[phy->instance].vbus_reg_supply); - if (WARN_ON(IS_ERR_OR_NULL(phy->reg_vbus))) { - pr_err("couldn't get regulator vdd_vbus_usb: %ld, instance : %d\n", - PTR_ERR(phy->reg_vbus), phy->instance); - err = PTR_ERR(phy->reg_vbus); - goto err1; - } - } - } - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { - uhsic_powerup_pmc_wake_detect(phy); - } - -#endif - if (((instance == 2) || (instance == 0)) && - (phy->mode == TEGRA_USB_PHY_MODE_HOST)) { - vbus_enable(phy); - } - return phy; - -err1: - clk_disable(phy->pll_u); - clk_put(phy->pll_u); -err0: - kfree(phy); - return ERR_PTR(err); + return status; } - -int tegra_usb_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) +int tegra_usb_phy_suspend(struct tegra_usb_phy *phy) { - int ret = 0; - - const tegra_phy_fp power_on[] = { - utmi_phy_power_on, - ulpi_phy_power_on, - null_phy_power_on, - uhsic_phy_power_on, - }; + int err = 0; - if (phy->power_on) - return ret; + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - if ((phy->instance == 0) && usb_phy_data[0].vbus_irq && - (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)) - is_dpd = true; + if (phy->ops && phy->ops->suspend) + err = phy->ops->suspend(phy); - if (phy->reg_vdd && !phy->regulator_on) { - regulator_enable(phy->reg_vdd); - phy->regulator_on = 1; + if (!err && phy->pdata->u_data.host.power_off_on_suspend) { + if (phy->pdata->ops && phy->pdata->ops->pre_phy_off) + phy->pdata->ops->pre_phy_off(); + err = phy->ops->power_off(phy); + if (phy->pdata->ops && phy->pdata->ops->post_phy_off) + phy->pdata->ops->post_phy_off(); } - if (power_on[phy->usb_phy_type]) - ret = power_on[phy->usb_phy_type](phy, is_dpd); - - phy->power_on = true; - return ret; + return err; } - -void tegra_usb_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) +int tegra_usb_phy_post_suspend(struct tegra_usb_phy *phy) { - const tegra_phy_fp power_off[] = { - utmi_phy_power_off, - ulpi_phy_power_off, - null_phy_power_off, - uhsic_phy_power_off, - }; + int status = 0; - if (!phy->power_on) - return; + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - if ((phy->instance == 0) && usb_phy_data[0].vbus_irq && - (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)) - is_dpd = true; + if (phy->ops && phy->ops->post_suspend) + status = phy->ops->post_suspend(phy); - if (power_off[phy->usb_phy_type]) - power_off[phy->usb_phy_type](phy, is_dpd); + if (phy->pdata->ops && phy->pdata->ops->post_suspend) + phy->pdata->ops->post_suspend(); - if (phy->reg_vdd && phy->regulator_on && is_dpd) { -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (tegra_get_revision() >= TEGRA_REVISION_A03) -#endif - regulator_disable(phy->reg_vdd); - phy->regulator_on = 0; - } - phy->power_on = false; + return status; } - -void tegra_usb_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup) +int tegra_usb_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) { - const tegra_phy_fp preresume[] = { - utmi_phy_preresume, - NULL, - NULL, - uhsic_phy_preresume, - }; + int status = 0; - if (preresume[phy->usb_phy_type]) - preresume[phy->usb_phy_type](phy, remote_wakeup); -} + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); -void tegra_usb_phy_postsuspend(struct tegra_usb_phy *phy, bool is_dpd) + if (phy->pdata->ops && phy->pdata->ops->pre_resume) + phy->pdata->ops->pre_resume(); -{ - const tegra_phy_fp postsuspend[] = { - NULL, - NULL, - NULL, - uhsic_phy_postsuspend, - }; + if (phy->ops && phy->ops->pre_resume) + status = phy->ops->pre_resume(phy, remote_wakeup); - if (postsuspend[phy->usb_phy_type]) - postsuspend[phy->usb_phy_type](phy, is_dpd); + return status; } - -void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd) +int tegra_usb_phy_resume(struct tegra_usb_phy *phy) { - const tegra_phy_fp postresume[] = { - utmi_phy_postresume, - NULL, - NULL, - NULL, - }; + int err = 0; - usb_phy_set_tx_fill_tuning(phy, is_dpd); - - // If Phy type is utmi, call its post resume - if (phy->usb_phy_type == 0) - utmi_phy_postresume(phy, is_dpd); -} + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); -void tegra_ehci_pre_reset(struct tegra_usb_phy *phy, bool is_dpd) -{ - const tegra_phy_fp pre_reset[] = { - NULL, - NULL, - null_phy_pre_usbcmd_reset, - NULL, - }; + if (phy->pdata->u_data.host.power_off_on_suspend) { + if (phy->pdata->ops && phy->pdata->ops->pre_phy_on) + phy->pdata->ops->pre_phy_on(); + err = phy->ops->power_on(phy); + if (phy->pdata->ops && phy->pdata->ops->post_phy_on) + phy->pdata->ops->post_phy_on(); + } - if (pre_reset[phy->usb_phy_type]) - pre_reset[phy->usb_phy_type](phy, is_dpd); -} + if (!err && phy->ops && phy->ops->resume) + err = phy->ops->resume(phy); -void tegra_ehci_post_reset(struct tegra_usb_phy *phy, bool is_dpd) -{ - const tegra_phy_fp post_reset[] = { - NULL, - NULL, - null_phy_post_usbcmd_reset, - NULL, - }; + return err; - if (post_reset[phy->usb_phy_type]) - post_reset[phy->usb_phy_type](phy, is_dpd); } - -void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) +int tegra_usb_phy_post_resume(struct tegra_usb_phy *phy) { - const tegra_phy_restore_start_fp phy_restore_start[] = { - utmi_phy_restore_start, - ulpi_phy_restore_start, - null_phy_restore_start, - NULL, - }; + int status = 0; - if (phy_restore_start[phy->usb_phy_type]) - phy_restore_start[phy->usb_phy_type](phy, port_speed); -} + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); -void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) -{ - const tegra_phy_restore_end_fp phy_restore_end[] = { - utmi_phy_restore_end, - ulpi_phy_restore_end, - null_phy_restore_end, - NULL, - }; + if (phy->ops && phy->ops->post_resume) + status = phy->ops->post_resume(phy); - if (phy_restore_end[phy->usb_phy_type]) - phy_restore_end[phy->usb_phy_type](phy); -} + if (phy->pdata->ops && phy->pdata->ops->post_resume) + phy->pdata->ops->post_resume(); -void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy) -{ - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) - utmi_phy_clk_disable(phy); + return status; } - -void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy) +int tegra_usb_phy_port_power(struct tegra_usb_phy *phy) { - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) - utmi_phy_clk_enable(phy); -} + int status = 0; -void tegra_usb_phy_close(struct tegra_usb_phy *phy) -{ - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - utmip_pad_close(phy); - utmip_phy_disable_pmc_bus_ctrl(phy); - } - else if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_LINK_ULPI && phy->clk) - clk_put(phy->clk); - if (phy->mode == TEGRA_USB_PHY_MODE_HOST) { - vbus_disable(phy); - } - clk_disable(phy->pll_u); - clk_put(phy->pll_u); - if (phy->reg_vbus) - regulator_put(phy->reg_vbus); - if (phy->reg_vdd) - regulator_put(phy->reg_vdd); - if (phy->instance == 0 && usb_phy_data[0].vbus_irq) - free_irq(usb_phy_data[0].vbus_irq, phy); - kfree(phy); -} + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); -int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_uhsic_config *uhsic_config = phy->config; - - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET); - val |= TEGRA_USB_USBMODE_HOST; - writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET); - - /* Change the USB controller PHY type to HSIC */ - val = readl(base + HOSTPC1_DEVLC); - val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK); - val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC); - val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK); - val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED); - writel(val, base + HOSTPC1_DEVLC); -#endif - val = readl(base + UHSIC_MISC_CFG0); - val |= UHSIC_DETECT_SHORT_CONNECT; - writel(val, base + UHSIC_MISC_CFG0); - udelay(1); - - val = readl(base + UHSIC_MISC_CFG0); - val |= UHSIC_FORCE_XCVR_MODE; - writel(val, base + UHSIC_MISC_CFG0); + if (phy->ops && phy->ops->port_power) + status = phy->ops->port_power(phy); - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPD_STROBE; -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - val |= UHSIC_RPU_STROBE; -#endif - writel(val, base + UHSIC_PADS_CFG1); - - if (uhsic_config->usb_phy_ready && - uhsic_config->usb_phy_ready()) - return -EAGAIN; - - /* connect detect on T30 requires extra wait */ - if (utmi_wait_register_timeout(base + UHSIC_STAT_CFG0, - UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT, - CONNECT_DETECT_TIMEOUT) < 0) { - pr_err("%s: timeout waiting for hsic connect detect\n", __func__); - return -ETIMEDOUT; - } - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(2), USB_PORTSC1_LS(2)) < 0) { - pr_err("%s: timeout waiting for dplus state\n", __func__); - return -ETIMEDOUT; - } -#endif - } + if (phy->pdata->ops && phy->pdata->ops->port_power) + phy->pdata->ops->port_power(); - return 0; + return status; } - int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy) { - unsigned long val; - void __iomem *base = phy->regs; - - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* Change the USB controller PHY type to HSIC */ - val = readl(base + HOSTPC1_DEVLC); - val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK); - val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC); - val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK); - val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED); - writel(val, base + HOSTPC1_DEVLC); - /* wait here, otherwise HOSTPC1_DEVLC_PSPD will timeout */ - mdelay(5); -#endif - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_PTC(5); - writel(val, base + USB_PORTSC1); - udelay(2); - - val = readl(base + USB_PORTSC1); - val &= ~USB_PORTSC1_PTC(~0); - writel(val, base + USB_PORTSC1); - udelay(2); - - if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(0), 0) < 0) { - pr_err("%s: timeout waiting for SE0\n", __func__); - return -ETIMEDOUT; - } + int status = 0; - if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_CCS, USB_PORTSC1_CCS) < 0) { - pr_err("%s: timeout waiting for connection status\n", __func__); - return -ETIMEDOUT; - } + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) - if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_PSPD(2), USB_PORTSC1_PSPD(2)) < 0) { - pr_err("%s: timeout waiting hsic high speed configuration\n", __func__); - return -ETIMEDOUT; - } -#elif defined(CONFIG_ARCH_TEGRA_3x_SOC) - if (utmi_wait_register(base + HOSTPC1_DEVLC, - HOSTPC1_DEVLC_PSPD(2), - HOSTPC1_DEVLC_PSPD(2)) < 0) { - pr_err("%s: timeout waiting hsic high speed configuration\n", __func__); - return -ETIMEDOUT; - } -#endif - val = readl(base + USB_USBCMD); - val &= ~USB_USBCMD_RS; - writel(val, base + USB_USBCMD); - - if (utmi_wait_register(base + USB_USBSTS, USB_USBSTS_HCH, USB_USBSTS_HCH) < 0) { - pr_err("%s: timeout waiting for stopping the controller\n", __func__); - return -ETIMEDOUT; - } - - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPU_STROBE; - val |= UHSIC_RPD_STROBE; - writel(val, base + UHSIC_PADS_CFG1); - - mdelay(50); - - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPD_STROBE; - val |= UHSIC_RPU_STROBE; - writel(val, base + UHSIC_PADS_CFG1); - - val = readl(base + USB_USBCMD); - val |= USB_USBCMD_RS; - writel(val, base + USB_USBCMD); - - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPU_STROBE; - writel(val, base + UHSIC_PADS_CFG1); + if (phy->ops && phy->ops->bus_reset) + status = phy->ops->bus_reset(phy); - if (utmi_wait_register(base + USB_USBCMD, USB_USBCMD_RS, USB_USBCMD_RS) < 0) { - pr_err("%s: timeout waiting for starting the controller\n", __func__); - return -ETIMEDOUT; - } - } - - return 0; + return status; } -int tegra_usb_phy_bus_idle(struct tegra_usb_phy *phy) +bool tegra_usb_phy_charger_detected(struct tegra_usb_phy *phy) { - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_uhsic_config *uhsic_config = phy->config; - - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET); - val |= TEGRA_USB_USBMODE_HOST; - writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET); - - /* Change the USB controller PHY type to HSIC */ - val = readl(base + HOSTPC1_DEVLC); - val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK); - val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC); - val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK); - val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED); - writel(val, base + HOSTPC1_DEVLC); -#endif - val = readl(base + UHSIC_MISC_CFG0); - val |= UHSIC_DETECT_SHORT_CONNECT; - writel(val, base + UHSIC_MISC_CFG0); - udelay(1); + bool status = 0; - val = readl(base + UHSIC_MISC_CFG0); - val |= UHSIC_FORCE_XCVR_MODE; - writel(val, base + UHSIC_MISC_CFG0); - - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPD_STROBE; - /* safe to enable RPU on STROBE at all times during idle */ - val |= UHSIC_RPU_STROBE; - writel(val, base + UHSIC_PADS_CFG1); - - val = readl(base + USB_USBCMD); - val &= ~USB_USBCMD_RS; - writel(val, base + USB_USBCMD); - - if (uhsic_config->usb_phy_ready && - uhsic_config->usb_phy_ready()) - return -EAGAIN; - - /* connect detect on T30 requires extra wait */ - if (utmi_wait_register_timeout(base + UHSIC_STAT_CFG0, - UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT, - CONNECT_DETECT_TIMEOUT) < 0) { - pr_err("%s: timeout waiting for hsic connect detect\n", - __func__); - return -ETIMEDOUT; - } - } - return 0; + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + if (phy->ops && phy->ops->charger_detect) + status = phy->ops->charger_detect(phy); + + return status; } -bool tegra_usb_phy_is_device_connected(struct tegra_usb_phy *phy) +bool tegra_usb_phy_hw_accessible(struct tegra_usb_phy *phy) { - void __iomem *base = phy->regs; + if (!phy->hw_accessible) + DBG("%s(%d) inst:[%d] Not Accessible\n", __func__, + __LINE__, phy->inst); - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { - if (utmi_wait_register(base + UHSIC_STAT_CFG0, - UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT) < 0) { - pr_err("%s: no hsic connection\n", __func__); - return false; - } -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(2), USB_PORTSC1_LS(2)) < 0) { - pr_err("%s: timeout waiting for dplus state\n", __func__); - return false; - } -#endif - } - return true; + return phy->hw_accessible; } -bool tegra_usb_phy_charger_detect(struct tegra_usb_phy *phy) +bool tegra_usb_phy_remote_wakeup(struct tegra_usb_phy *phy) { - unsigned long val; - void __iomem *base = phy->regs; - bool status; - - if (phy->usb_phy_type != TEGRA_USB_PHY_TYPE_UTMIP) - { - /* Charger detection is not there for ULPI - * return Charger not available */ - return false; - } - - /* Enable charger detection logic */ - val = readl(base + UTMIP_BAT_CHRG_CFG0); - val |= UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN; - writel(val, base + UTMIP_BAT_CHRG_CFG0); - - /* Source should be on for 100 ms as per USB charging spec */ - msleep(TDP_SRC_ON_MS); - - val = readl(base + USB_PHY_VBUS_WAKEUP_ID); - /* If charger is not connected disable the interrupt */ - val &= ~VDAT_DET_INT_EN; - val |= VDAT_DET_CHG_DET; - writel(val,base + USB_PHY_VBUS_WAKEUP_ID); - - val = readl(base + USB_PHY_VBUS_WAKEUP_ID); - if (val & VDAT_DET_STS) - status = true; - else - status = false; - - /* Disable charger detection logic */ - val = readl(base + UTMIP_BAT_CHRG_CFG0); - val &= ~(UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN); - writel(val, base + UTMIP_BAT_CHRG_CFG0); - - /* Delay of 40 ms before we pull the D+ as per battery charger spec */ - msleep(TDPSRC_CON_MS); - - return status; + return phy->remote_wakeup; } -#ifndef CONFIG_ARCH_TEGRA_2x_SOC -void tegra_usb_phy_power_down_pmc(void) +bool tegra_usb_phy_has_hostpc(struct tegra_usb_phy *phy) { - unsigned long val; - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - - /* power down all 3 UTMIP interfaces */ - val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG); - val |= UTMIP_PWR(0) | UTMIP_PWR(1) | UTMIP_PWR(2); - writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG); - - /* turn on pad detectors */ - writel(PMC_POWER_DOWN_MASK, pmc_base + PMC_USB_AO); - - /* setup sleep walk fl all 3 usb controllers */ - val = UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_HIGHZ_A | - UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_HIGHZ_B | - UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_HIGHZ_C | - UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_HIGHZ_D; - writel(val, pmc_base + PMC_SLEEPWALK_REG(0)); - writel(val, pmc_base + PMC_SLEEPWALK_REG(1)); - writel(val, pmc_base + PMC_SLEEPWALK_REG(2)); - - /* enable pull downs on HSIC PMC */ - val = UHSIC_STRB_RPD_A | UHSIC_DATA_RPD_A | UHSIC_STRB_RPD_B | - UHSIC_DATA_RPD_B | UHSIC_STRB_RPD_C | UHSIC_DATA_RPD_C | - UHSIC_STRB_RPD_D | UHSIC_DATA_RPD_D; - writel(val, pmc_base + UHSIC_SLEEPWALK_REG); - - /* Turn over pad configuration to PMC */ - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(0, ~0); - val &= ~UTMIP_WAKE_VAL(1, ~0); - val &= ~UTMIP_WAKE_VAL(2, ~0); - val &= ~UHSIC_WAKE_VAL_P0(~0); - val |= UTMIP_WAKE_VAL(0, WAKE_VAL_NONE) | UHSIC_WAKE_VAL_P0(WAKE_VAL_NONE) | - UTMIP_WAKE_VAL(1, WAKE_VAL_NONE) | UTMIP_WAKE_VAL(2, WAKE_VAL_NONE) | - UTMIP_RCTRL_USE_PMC(0) | UTMIP_RCTRL_USE_PMC(1) | UTMIP_RCTRL_USE_PMC(2) | - UTMIP_TCTRL_USE_PMC(0) | UTMIP_TCTRL_USE_PMC(1) | UTMIP_TCTRL_USE_PMC(2) | - UTMIP_FSLS_USE_PMC(0) | UTMIP_FSLS_USE_PMC(1) | UTMIP_FSLS_USE_PMC(2) | - UTMIP_MASTER_ENABLE(0) | UTMIP_MASTER_ENABLE(1) | UTMIP_MASTER_ENABLE(2) | - UHSIC_MASTER_ENABLE_P0; - writel(val, pmc_base + PMC_SLEEP_CFG); + return phy->pdata->has_hostpc; } -#endif -int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size) +bool tegra_usb_phy_otg_supported(struct tegra_usb_phy *phy) { - if (pdata) { - int i; - - for (i = 0; i < size; i++, pdata++) { - usb_phy_data[pdata->instance].instance = pdata->instance; - usb_phy_data[pdata->instance].vbus_irq = pdata->vbus_irq; - usb_phy_data[pdata->instance].vbus_gpio = pdata->vbus_gpio; - usb_phy_data[pdata->instance].vbus_reg_supply = pdata->vbus_reg_supply; - } - } - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - tegra_usb_phy_power_down_pmc(); -#endif - - return 0; + return phy->pdata->port_otg; } void tegra_usb_phy_memory_prefetch_on(struct tegra_usb_phy *phy) @@ -3197,7 +643,7 @@ void tegra_usb_phy_memory_prefetch_on(struct tegra_usb_phy *phy) void __iomem *ahb_gizmo = IO_ADDRESS(TEGRA_AHB_GIZMO_BASE); unsigned long val; - if (phy->instance == 0 && phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { + if (phy->inst == 0 && phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG1); val |= PREFETCH_ENB; writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG1); @@ -3212,7 +658,7 @@ void tegra_usb_phy_memory_prefetch_off(struct tegra_usb_phy *phy) void __iomem *ahb_gizmo = IO_ADDRESS(TEGRA_AHB_GIZMO_BASE); unsigned long val; - if (phy->instance == 0 && phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { + if (phy->inst == 0 && phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) { val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG1); val &= ~(PREFETCH_ENB); writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG1); @@ -3221,38 +667,3 @@ void tegra_usb_phy_memory_prefetch_off(struct tegra_usb_phy *phy) writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG2); } } - -/* disable walk and wake events after resume from LP0 */ -bool tegra_usb_phy_is_remotewake_detected(struct tegra_usb_phy *phy) -{ -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - void __iomem *base = phy->regs; - unsigned int inst = phy->instance; - u32 val; - - val = readl(base + UTMIP_PMC_WAKEUP0); - if (val & EVENT_INT_ENB) { - val = readl(pmc_base + UTMIP_UHSIC_STATUS); - if (UTMIP_WAKE_ALARM(inst) & val) { - val = readl(pmc_base + PMC_SLEEP_CFG); - val &= ~UTMIP_WAKE_VAL(inst, 0x0); - val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE); - writel(val, pmc_base + PMC_SLEEP_CFG); - - val = readl(pmc_base + PMC_TRIGGERS); - val |= UTMIP_CLR_WAKE_ALARM(inst) | - UTMIP_CLR_WALK_PTR(inst); - writel(val, pmc_base + PMC_TRIGGERS); - - val = readl(base + UTMIP_PMC_WAKEUP0); - val &= ~EVENT_INT_ENB; - writel(val, base + UTMIP_PMC_WAKEUP0); - phy->remote_wakeup = true; - return true; - } - } -#endif - return false; -} - diff --git a/chromeos/config/armel/config.common.armel b/chromeos/config/armel/config.common.armel new file mode 100644 index 000000000000..efc5f4e20ae0 --- /dev/null +++ b/chromeos/config/armel/config.common.armel @@ -0,0 +1,528 @@ +# +# Config options generated by splitconfig +# +CONFIG_AEABI=y +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_APM_EMULATION is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_EXYNOS4 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_HAS_CPUFREQ=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_NOMADIK is not set +CONFIG_ARCH_NR_GPIO=512 +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PRIMA2 is not set +CONFIG_ARCH_PROVIDES_UDELAY=y +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_REALVIEW is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_TCC_926 is not set +CONFIG_ARCH_TEGRA=y +CONFIG_ARCH_TEGRA_HAS_PCIE=y +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VT8500 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_ZYNQ is not set +CONFIG_ARM=y +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_720791 is not set +CONFIG_ARM_ERRATA_742230=y +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_ARM_ERRATA_753970 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_L1_CACHE_SHIFT=5 +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_ARM_SAVE_DEBUG_CONTEXT=y +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +# CONFIG_ATA is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH5K_PCI is not set +# CONFIG_ATH6K_LEGACY is not set +# CONFIG_ATH9K is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1C is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +# CONFIG_AUTO_ZRELADDR is not set +# CONFIG_AX88796 is not set +# CONFIG_B44 is not set +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_TEGRA_PWM is not set +CONFIG_BATTERY_BQ20Z75=y +# CONFIG_BCM4329 is not set +# CONFIG_BCMDHD is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BRCMDBG is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMUTIL=m +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BT_ATH3K is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +# CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_BCSP is not set +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_CACHE_L2X0=y +CONFIG_CACHE_PL310=y +CONFIG_CHARGER_GPIO=y +# CONFIG_CHARGER_ISP1704 is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CMDLINE="mem=448M@0M console=ttyS0,115200n8 earlyprintk init=/bin/ash" +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +CONFIG_CMDLINE_FROM_BOOTLOADER=y +CONFIG_COMPAT_BRK=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_CPA=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_HAS_PMU=y +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +# CONFIG_CRASH_DUMP is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DEV_TEGRA_AES is not set +# CONFIG_DCC_TTY is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +# CONFIG_DM9000 is not set +# CONFIG_DRM is not set +CONFIG_DTC=y +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_TEGRA=y +# CONFIG_FCOE is not set +CONFIG_FIQ=y +# CONFIG_FIQ_DEBUGGER is not set +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_FRAME_WARN=1024 +# CONFIG_FTGMAC100 is not set +# CONFIG_FTMAC100 is not set +CONFIG_FUNCTION_GRAPH_TRACER=y +CONFIG_HARDIRQS_SW_RESEND=y +# CONFIG_HARDLOCKUP_DETECTOR is not set +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARM_SCU=y +CONFIG_HAVE_ARM_TWD=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_PWM=y +CONFIG_HAVE_SCHED_CLOCK=y +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_PID is not set +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +# CONFIG_HOSTAP_PCI is not set +# CONFIG_HOSTAP_PLX is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HVC_DCC is not set +CONFIG_HW_PERF_EVENTS=y +CONFIG_HZ=100 +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_TEGRA=y +# CONFIG_IGBVF is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_IRQ_DOMAIN=y +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_ISCSI_TCP is not set +# CONFIG_IWL3945 is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWLAGN is not set +# CONFIG_IWM is not set +# CONFIG_IWMC3200TOP is not set +# CONFIG_JME is not set +CONFIG_KEYBOARD_TEGRA=y +CONFIG_KTIME_SCALAR=y +CONFIG_LBDAF=y +CONFIG_LEDS_PWM=y +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LIBERTAS_THINFIRM_USB is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +CONFIG_LOCAL_TIMERS=y +# CONFIG_LPC_SCH is not set +CONFIG_LZO_DECOMPRESS=y +CONFIG_MACH_HAS_SND_SOC_TEGRA_WM8903=y +# CONFIG_MACH_TEGRA_DT is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_MFD_ASIC3 is not set +CONFIG_MFD_CORE=y +# CONFIG_MFD_NVEC is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MG_DISK is not set +CONFIG_MMC=y +# CONFIG_MMC_BKOPS is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +CONFIG_MMC_BLOCK_MINORS=16 +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_CLKGATE is not set +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +# CONFIG_MMC_PARANOID_SD_INIT is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +CONFIG_MMC_SDHCI_TEGRA=y +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_UNSAFE_RESUME=y +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_PS2 is not set +CONFIG_NEED_DMA_MAP_STATE=y +# CONFIG_NET_PCI is not set +CONFIG_NVMAP_ALLOW_SYSMEM=y +CONFIG_NVMAP_CARVEOUT_COMPACTOR=y +# CONFIG_NVMAP_CARVEOUT_KILLER is not set +# CONFIG_NVMAP_HIGHMEM_ONLY is not set +CONFIG_NVMAP_PAGE_POOLS=y +CONFIG_NVMAP_PAGE_POOL_SIZE=0x0 +CONFIG_NVMAP_RECLAIM_UNPINNED_VM=y +# CONFIG_NVMAP_VPR is not set +# CONFIG_OABI_COMPAT is not set +# CONFIG_OC_ETM is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_DEVICE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_I2C=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_OF_SPI=y +CONFIG_OLD_MCOUNT=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PCI_SYSCALL=y +CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_769419 is not set +# CONFIG_PLAT_SPEAR is not set +CONFIG_PM_CLK=y +CONFIG_PROC_DEVICETREE=y +# CONFIG_R8169 is not set +# CONFIG_RC_CORE is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set +# CONFIG_REGULATOR_FAN53555 is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_GPIO is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_TPS6238X0 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +CONFIG_RFKILL_GPIO=m +# CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RT2500USB is not set +# CONFIG_RT2800USB is not set +# CONFIG_RT73USB is not set +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_TEGRA is not set +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTL8192CE is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_BNX2X_FCOE is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SD8797 is not set +# CONFIG_SDIO_UART is not set +CONFIG_SENSORS_ISL29018=m +# CONFIG_SENSORS_LIS3_SPI is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_TEGRA is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SKY2 is not set +# CONFIG_SMC911X is not set +CONFIG_SMC91X=m +CONFIG_SMP_ON_UP=y +# CONFIG_SMSC911X is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_PCM=y +CONFIG_SND_SOC=y +# CONFIG_SND_SOC_ALL_CODECS is not set +# CONFIG_SND_SOC_CACHE_LZO is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +CONFIG_SND_SOC_SPDIF=y +CONFIG_SND_SOC_TEGRA=y +CONFIG_SND_SOC_TEGRA_WM8903=y +# CONFIG_SND_SOC_TLV320AIC326X is not set +CONFIG_SND_SOC_WM8903=y +CONFIG_SND_TIMER=y +CONFIG_SOC_CAMERA=m +# CONFIG_SOC_CAMERA_IMX074 is not set +# CONFIG_SOC_CAMERA_MT9M001 is not set +# CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set +# CONFIG_SOC_CAMERA_MT9V022 is not set +CONFIG_SOC_CAMERA_OV2640=m +# CONFIG_SOC_CAMERA_OV5642 is not set +# CONFIG_SOC_CAMERA_OV6650 is not set +# CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV9640 is not set +CONFIG_SOC_CAMERA_OV9740=m +# CONFIG_SOC_CAMERA_PLATFORM is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set +# CONFIG_SOC_CAMERA_TW9910 is not set +# CONFIG_SPARSE_IRQ is not set +# CONFIG_SPI_SLAVE_TEGRA is not set +# CONFIG_SPI_TEGRA is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SQUASHFS_LZO=y +# CONFIG_SQUASHFS_XATTR is not set +# CONFIG_SQUASHFS_XZ is not set +CONFIG_SQUASHFS_ZLIB=y +# CONFIG_SSB is not set +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_TCG_TIS is not set +# CONFIG_TEGRA_AVP is not set +# CONFIG_TEGRA_BB_SUPPORT is not set +# CONFIG_TEGRA_BB_XMM_POWER is not set +# CONFIG_TEGRA_BB_XMM_POWER2 is not set +# CONFIG_TEGRA_BPC_MGMT is not set +CONFIG_TEGRA_CAMERA=y +CONFIG_TEGRA_CLOCK_DEBUG_WRITE=y +CONFIG_TEGRA_CORE_DVFS=y +CONFIG_TEGRA_CPU_DVFS=y +CONFIG_TEGRA_DC=y +CONFIG_TEGRA_DC_EXTENSIONS=y +# CONFIG_TEGRA_DEBUG_UARTC is not set +# CONFIG_TEGRA_DEBUG_UARTD is not set +# CONFIG_TEGRA_DEBUG_UARTE is not set +# CONFIG_TEGRA_DEBUG_UART_NONE is not set +# CONFIG_TEGRA_DSI is not set +CONFIG_TEGRA_DTV=y +CONFIG_TEGRA_EMC_SCALING_ENABLE=y +# CONFIG_TEGRA_FIQ_DEBUGGER is not set +# CONFIG_TEGRA_FPGA_PLATFORM is not set +CONFIG_TEGRA_GRHOST=y +# CONFIG_TEGRA_HDMI_74MHZ_LIMIT is not set +# CONFIG_TEGRA_IOMMU_SMMU is not set +CONFIG_TEGRA_IOVMM=y +# CONFIG_TEGRA_MC_PROFILE is not set +# CONFIG_TEGRA_MEDIASERVER is not set +CONFIG_TEGRA_NVAVP=y +# CONFIG_TEGRA_NVHDCP is not set +CONFIG_TEGRA_NVMAP=y +CONFIG_TEGRA_PWM=y +CONFIG_TEGRA_RPC=y +CONFIG_TEGRA_SILICON_PLATFORM=y +# CONFIG_TEGRA_SIMULATION_PLATFORM is not set +CONFIG_TEGRA_SYSTEM_DMA=y +CONFIG_TEGRA_THERMAL_THROTTLE=y +# CONFIG_TEGRA_USB_MODEM_POWER is not set +# CONFIG_TEGRA_WDT_RECOVERY is not set +# CONFIG_THUMB2_KERNEL is not set +# CONFIG_TIGON3 is not set +# CONFIG_TORCH_SSL3250A is not set +# CONFIG_TORCH_TPS61050 is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_UACCESS_WITH_MEMCPY is not set +CONFIG_USB_EHCI_TEGRA=y +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_OHCI_HCD is not set +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_TEGRA_OTG is not set +# CONFIG_USB_UHCI_HCD is not set +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USE_OF=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF_GEN=m +# CONFIG_VIDEO_AD5820 is not set +# CONFIG_VIDEO_AR0832 is not set +# CONFIG_VIDEO_OV14810 is not set +# CONFIG_VIDEO_OV2710 is not set +# CONFIG_VIDEO_OV5640 is not set +# CONFIG_VIDEO_OV5650 is not set +# CONFIG_VIDEO_OV9726 is not set +# CONFIG_VIDEO_SH532U is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set +# CONFIG_VIDEO_SOC380 is not set +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_XFRM_USER=m +# CONFIG_XIP_KERNEL is not set +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ZBOOT_ROM_TEXT=0x0 +# CONFIG_ZD1211RW is not set +CONFIG_ZONE_DMA_FLAG=0 diff --git a/chromeos/config/armel/config.flavour.chromeos-tegra3 b/chromeos/config/armel/config.flavour.chromeos-tegra3 new file mode 100644 index 000000000000..3d2488ffab63 --- /dev/null +++ b/chromeos/config/armel/config.flavour.chromeos-tegra3 @@ -0,0 +1,125 @@ +# +# Config options generated by splitconfig +# +# CONFIG_AFS_FS is not set +# CONFIG_ANDROID_PARANOID_NETWORK is not set +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_TEGRA_3x_SOC=y +CONFIG_ARCH_TEGRA_HAS_DUAL_3D=y +CONFIG_ARCH_TEGRA_HAS_DUAL_CPU_CLUSTERS=y +CONFIG_ARCH_TEGRA_HAS_SATA=y +# CONFIG_ARM_ERRATA_716044 is not set +CONFIG_ARM_ERRATA_743622=y +CONFIG_ARM_ERRATA_751472=y +CONFIG_ARM_ERRATA_752520=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_BATTERY_BQ27X00_I2C=y +CONFIG_BATTERY_BQ27X00_PLATFORM=y +CONFIG_BATTERY_BQ27x00=y +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_CODA_FS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CRYPTO_CTS=y +# CONFIG_CRYPTO_DEV_TEGRA_SE is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DNOTIFY=y +CONFIG_DNS_RESOLVER=y +CONFIG_EXPORTFS=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set +CONFIG_GIC_SET_MULTIPLE_CPUS=y +CONFIG_IPV6=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_RARP=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_LZO_COMPRESS=y +# CONFIG_MACH_ARUBA is not set +CONFIG_MACH_CARDHU=y +CONFIG_MACH_HAS_SND_SOC_TEGRA_MAX98095=y +CONFIG_MACH_HAS_SND_SOC_TEGRA_TLV320AIC326X=y +# CONFIG_MACH_KAI is not set +# CONFIG_MACH_P1852 is not set +# CONFIG_MACH_TEGRA_ENTERPRISE is not set +# CONFIG_MFD_TPS6586X is not set +CONFIG_MFD_TPS6591X=y +# CONFIG_NCP_FS is not set +CONFIG_NEON=y +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=y +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +# CONFIG_NFS_USE_NEW_IDMAPPER is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_NR_CPUS=4 +CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_PCI_MSI=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGULATOR_TPS62360=y +CONFIG_REGULATOR_TPS6591X=y +CONFIG_REPORT_PRESENT_CPUS=y +CONFIG_ROOT_NFS=y +CONFIG_RPCSEC_GSS_KRB5=y +CONFIG_RTC_DRV_TPS6591x=y +CONFIG_SENSORS_ISL29028=m +CONFIG_SENSORS_NCT1008=y +# CONFIG_SENSORS_TEGRA_TSENSOR is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +CONFIG_SND_SOC_MAX98095=y +CONFIG_SND_SOC_TEGRA30_AHUB=y +CONFIG_SND_SOC_TEGRA30_DAM=y +CONFIG_SND_SOC_TEGRA30_I2S=y +CONFIG_SND_SOC_TEGRA30_SPDIF=y +CONFIG_SND_SOC_TEGRA_MAX98095=y +# CONFIG_SND_SOC_TEGRA_TLV320AIC326X is not set +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SWAP=y +CONFIG_TASK_SIZE=0x7F000000 +CONFIG_TASK_SIZE_2G_LESS_16M=y +# CONFIG_TASK_SIZE_2G_LESS_24M is not set +CONFIG_TEGRA_AUTO_HOTPLUG=y +CONFIG_TEGRA_AVP_KERNEL_ON_SMMU=y +# CONFIG_TEGRA_CARDHU_DSI is not set +CONFIG_TEGRA_CLUSTER_CONTROL=y +CONFIG_TEGRA_DEBUG_UARTA=y +# CONFIG_TEGRA_DEBUG_UARTB is not set +CONFIG_TEGRA_DYNAMIC_PWRDET=y +CONFIG_TEGRA_EDP_EXACT_FREQ=y +CONFIG_TEGRA_EDP_LIMITS=y +CONFIG_TEGRA_EMC_TO_DDR_CLOCK=1 +CONFIG_TEGRA_IOVMM_SMMU=y +# CONFIG_TEGRA_IOVMM_SMMU_SYSFS is not set +CONFIG_TEGRA_LP2_ARM_TWD=y +# CONFIG_TEGRA_MC_EARLY_ACK is not set +CONFIG_TEGRA_PCI=y +CONFIG_TEGRA_PLLM_RESTRICTED=y +CONFIG_TEGRA_PREINIT_CLOCKS=y +CONFIG_TEGRA_PREPOWER_WIFI=y +CONFIG_TEGRA_SLOW_CSITE=y +CONFIG_TEGRA_THERMAL_SYSFS=y +CONFIG_USB_HOTPLUG=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_CDCETHER=y +CONFIG_USB_NET_CDC_NCM=y +CONFIG_USB_NET_MCS7830=y +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_USBNET=y +CONFIG_VMSPLIT_2G=y +# CONFIG_VMSPLIT_3G is not set +# CONFIG_VT_HW_CONSOLE_BINDING is not set diff --git a/chromeos/config/armel/config.flavour.chromiumos-arm b/chromeos/config/armel/config.flavour.chromiumos-arm new file mode 100644 index 000000000000..3c5ee02c17c1 --- /dev/null +++ b/chromeos/config/armel/config.flavour.chromiumos-arm @@ -0,0 +1,86 @@ +# +# Config options generated by splitconfig +# +CONFIG_ANDROID_PARANOID_NETWORK=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_TEGRA_2x_SOC=y +# CONFIG_ARCH_TEGRA_3x_SOC is not set +CONFIG_ARM_ERRATA_716044=y +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_ARM_ERRATA_752520 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_BATTERY_BQ27x00 is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_GIC_SET_MULTIPLE_CPUS is not set +CONFIG_IPV6=m +# CONFIG_IP_PNP is not set +CONFIG_MACH_HARMONY=y +CONFIG_MACH_KAEN=y +# CONFIG_MACH_P852 is not set +# CONFIG_MACH_PAZ00 is not set +CONFIG_MACH_SEABOARD=y +# CONFIG_MACH_TRIMSLICE is not set +# CONFIG_MACH_VENTANA is not set +CONFIG_MACH_WARIO=y +# CONFIG_MACH_WHISTLER is not set +CONFIG_MFD_TPS6586X=y +# CONFIG_MFD_TPS6591X is not set +# CONFIG_NEON is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NR_CPUS=2 +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_REGULATOR_TPS62360 is not set +CONFIG_REGULATOR_TPS6586X=y +# CONFIG_REPORT_PRESENT_CPUS is not set +CONFIG_RTC_DRV_TPS6586X=y +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_NCT1008 is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SND_SOC_TEGRA20_DAS=y +CONFIG_SND_SOC_TEGRA20_I2S=y +CONFIG_SND_SOC_TEGRA20_SPDIF=y +# CONFIG_SWAP is not set +CONFIG_TASK_SIZE=0xBF000000 +CONFIG_TASK_SIZE_3G_LESS_16M=y +# CONFIG_TASK_SIZE_3G_LESS_24M is not set +CONFIG_TEGRA_AVP_KERNEL_ON_MMU=y +# CONFIG_TEGRA_DEBUG_UARTA is not set +CONFIG_TEGRA_DEBUG_UARTB=y +# CONFIG_TEGRA_DYNAMIC_PWRDET is not set +# CONFIG_TEGRA_EDP_LIMITS is not set +CONFIG_TEGRA_EMC_TO_DDR_CLOCK=2 +# CONFIG_TEGRA_IOMMU_GART is not set +CONFIG_TEGRA_IOVMM_GART=y +# CONFIG_TEGRA_PCI is not set +# CONFIG_TEGRA_PREINIT_CLOCKS is not set +# CONFIG_TEGRA_PREPOWER_WIFI is not set +# CONFIG_TEGRA_SLOW_CSITE is not set +# CONFIG_TEGRA_STAT_MON is not set +# CONFIG_TEGRA_THERMAL_SYSFS is not set +# CONFIG_USB_HOTPLUG is not set +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_USBNET=m +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VMSPLIT_2G is not set +CONFIG_VMSPLIT_3G=y +CONFIG_VT_HW_CONSOLE_BINDING=y diff --git a/chromeos/config/config.common.chromeos b/chromeos/config/config.common.chromeos new file mode 100644 index 000000000000..eaea95f28fe6 --- /dev/null +++ b/chromeos/config/config.common.chromeos @@ -0,0 +1,2039 @@ +# +# Config options generated by splitconfig +# +# CONFIG_ABX500_CORE is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_ACENIC is not set +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AD2S120X is not set +# CONFIG_AD2S1210 is not set +# CONFIG_AD2S90 is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5686 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD5930 is not set +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7314 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7606 is not set +# CONFIG_AD7745 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD799X is not set +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# CONFIG_AD9850 is not set +# CONFIG_AD9852 is not set +# CONFIG_AD9910 is not set +# CONFIG_AD9951 is not set +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADIS16060 is not set +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADIS16400 is not set +# CONFIG_ADM8211 is not set +# CONFIG_ADT7310 is not set +# CONFIG_ADT7316 is not set +# CONFIG_ADT7410 is not set +# CONFIG_ADT75 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_AFFS_FS is not set +# CONFIG_AF_RXRPC is not set +CONFIG_AIO=y +# CONFIG_ALTERA_STAPL is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ANDROID is not set +CONFIG_ANON_INODES=y +# CONFIG_APANIC is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_APPLICOM is not set +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ARCNET is not set +# CONFIG_ARPD is not set +# CONFIG_ASHMEM is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_ATALK is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATH9K_HTC is not set +CONFIG_ATH_COMMON=m +CONFIG_ATH_DEBUG=y +# CONFIG_ATM is not set +# CONFIG_ATMEL is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_AUDIT is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_AVERAGE=y +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +# CONFIG_BATMAN_ADV is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_MAX17048 is not set +# CONFIG_BCM4329_RFKILL is not set +# CONFIG_BCMA is not set +CONFIG_BCMA_POSSIBLE=y +# CONFIG_BCM_WIMAX is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_BINARY_PRINTF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_BITREVERSE=y +# CONFIG_BLK_CGROUP is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_BLK_DEV_DRBD is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_RBD is not set +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLOCK=y +# CONFIG_BMP085 is not set +# CONFIG_BNX2 is not set +# CONFIG_BONDING is not set +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOUNCE=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_BRIDGE is not set +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BT=m +# CONFIG_BTRFS_FS is not set +# CONFIG_BT_BLUESLEEP is not set +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIVHCI=m +# CONFIG_BT_L2CAP is not set +# CONFIG_BT_MRVL is not set +# CONFIG_BT_SCO is not set +# CONFIG_BT_TIBLUESLEEP is not set +CONFIG_BUG=y +# CONFIG_C2PORT is not set +# CONFIG_CAIF is not set +# CONFIG_CAN is not set +CONFIG_CAN_PM_TRACE=y +# CONFIG_CARL9170 is not set +# CONFIG_CASSINI is not set +# CONFIG_CB710_CORE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_CEPH_LIB is not set +CONFIG_CFG80211=m +# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_CFG80211_DEBUGFS=y +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_WEXT=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_SCHED=y +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_SMB349 is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_CLEANCACHE is not set +# CONFIG_CNIC is not set +# CONFIG_COMPACTION is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_CONNECTOR=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_CORDIC is not set +# CONFIG_CPUSETS is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set +CONFIG_CPU_RMAP=y +# CONFIG_CRAMFS is not set +CONFIG_CRC16=y +CONFIG_CRC32=y +CONFIG_CRC7=m +# CONFIG_CRC8 is not set +CONFIG_CRC_CCITT=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=m +CONFIG_CROSS_COMPILE="" +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CCM is not set +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CTR is not set +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCBC is not set +CONFIG_CRYPTO_PCOMP2=y +# CONFIG_CRYPTO_PCRYPT is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_RNG2=y +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +# CONFIG_CRYPTO_VMAC is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYSTALHD is not set +# CONFIG_CUSE is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DCB is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_DEBUG_DEVRES=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_GPIO=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DECNET is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=5 +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_DEFAULT_NOOP is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_SECURITY="" +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_DEVKMEM is not set +CONFIG_DEVMEM=y +CONFIG_DEVPORT=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_DL2K is not set +# CONFIG_DMADEVICES is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DNET is not set +# CONFIG_DS1682 is not set +# CONFIG_DUMMY is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_DVB_CORE is not set +# CONFIG_DX_SEP is not set +# CONFIG_DYNAMIC_DEBUG is not set +CONFIG_DYNAMIC_FTRACE=y +CONFIG_EARLY_PRINTK=y +# CONFIG_EASYCAP is not set +# CONFIG_ECHO is not set +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EFI_PARTITION=y +# CONFIG_EFS_FS is not set +CONFIG_ELF_CORE=y +CONFIG_EMBEDDED=y +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENC28J60 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_EPOLL=y +# CONFIG_EQUALIZER is not set +# CONFIG_ET131X is not set +# CONFIG_ETHOC is not set +CONFIG_EVENTFD=y +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y +CONFIG_EVENT_TRACING=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPERT=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EZX_PCAP is not set +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FANOTIFY is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_METRONOME is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_SM7XX is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_TMIO is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_XGI is not set +# CONFIG_FDDI is not set +# CONFIG_FHANDLE is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FIRMWARE_IN_KERNEL=y +# CONFIG_FIXED_PHY is not set +CONFIG_FRAME_POINTER=y +CONFIG_FREEZER=y +# CONFIG_FSCACHE is not set +CONFIG_FSNOTIFY=y +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +# CONFIG_FT1000 is not set +CONFIG_FTRACE=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FUNCTION_TRACER=y +CONFIG_FUSE_FS=m +# CONFIG_FUSION is not set +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +# CONFIG_GAMEPORT is not set +# CONFIG_GCOV_KERNEL is not set +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_TRACER=y +# CONFIG_GFS2_FS is not set +CONFIG_GPIOLIB=y +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_RDC321X is not set +# CONFIG_GPIO_SX150X is not set +CONFIG_GPIO_SYSFS=y +# CONFIG_GPIO_VX855 is not set +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +# CONFIG_HAPPYMEAL is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SPARSE_IRQ=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_HERMES is not set +CONFIG_HFSPLUS_FS=m +# CONFIG_HFS_FS is not set +CONFIG_HID=y +CONFIG_HIDRAW=y +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=m +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=m +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_SUNPLUS is not set +CONFIG_HID_SUPPORT=y +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +# CONFIG_HMC6352 is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOTPLUG=y +CONFIG_HOTPLUG_CPU=y +# CONFIG_HP100 is not set +# CONFIG_HPFS_FS is not set +# CONFIG_HP_ILO is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON_VID is not set +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_I2C=y +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_COMPAT=y +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_EG20T is not set +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_HELPER_AUTO=y +# CONFIG_I2C_INTEL_MID is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_MUX is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_SLAVE is not set +CONFIG_I2C_STUB=m +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_XILINX is not set +# CONFIG_I2O is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_ICS932S401 is not set +# CONFIG_IDE is not set +# CONFIG_IEEE802154 is not set +# CONFIG_IGB is not set +CONFIG_IIO=m +# CONFIG_IIO_RING_BUFFER is not set +# CONFIG_IIO_TRIGGER is not set +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +# CONFIG_IMA is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +# CONFIG_INET6_XFRM_TUNNEL is not set +CONFIG_INET_AH=m +# CONFIG_INET_DIAG is not set +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +# CONFIG_INFINIBAND is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL is not set +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_CAPELLA_CM3217 is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_EVBUG is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_GPIO is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_KEYBOARD=y +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYRESET is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_MMA8450 is not set +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_PCF8574 is not set +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INTEL_MID_PTI is not set +CONFIG_INV_SENSORS=y +CONFIG_INV_SENSORS_ACCELEROMETERS=y +CONFIG_INV_SENSORS_COMPASS=y +CONFIG_INV_SENSORS_PRESSURE=y +CONFIG_IOMMU_SUPPORT=y +# CONFIG_ION is not set +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IP1000 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_REJECT_SKERR is not set +CONFIG_IPC_NS=y +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IPX is not set +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_DCCP is not set +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MROUTE=y +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +CONFIG_IP_MULTICAST=y +# CONFIG_IP_MULTIPLE_TABLES is not set +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_LOG=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_REJECT_SKERR is not set +CONFIG_IP_NF_TARGET_ULOG=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_SCTP is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set +# CONFIG_IRDA is not set +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_IRQ_WORK=y +# CONFIG_ISDN is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +CONFIG_ISO9660_FS=m +CONFIG_JBD=y +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFS_FS is not set +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KEXEC is not set +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_KGDB is not set +# CONFIG_KPROBES is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSM is not set +# CONFIG_KXSD9 is not set +# CONFIG_L2TP is not set +# CONFIG_LAPB is not set +# CONFIG_LCD_CLASS_DEVICE is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_LEDS_BD2802 is not set +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +CONFIG_LIB80211_CRYPT_WEP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_LIBCRC32C=m +# CONFIG_LIBERTAS is not set +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +# CONFIG_LINE6_USB is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_LKDTM is not set +# CONFIG_LLC2 is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGFS is not set +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=18 +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_LXT_PHY is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_HWSIM=m +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +# CONFIG_MAC80211_RC_PID is not set +# CONFIG_MACVLAN is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MARVELL_PHY is not set +# CONFIG_MAX1363 is not set +# CONFIG_MAX517 is not set +CONFIG_MD=y +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MEDIA_ATTACH is not set +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_XC5000=m +# CONFIG_MEMSTICK is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_MAX77663 is not set +# CONFIG_MFD_MAX8907C is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RICOH583 is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SUPPORT=y +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MICREL_PHY is not set +CONFIG_MII=y +# CONFIG_MINIX_FS is not set +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_MISC_DEVICES=y +CONFIG_MISC_FILESYSTEMS=y +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MPU_SENSORS_AK8963 is not set +# CONFIG_MPU_SENSORS_AK8972 is not set +# CONFIG_MPU_SENSORS_AK8975 is not set +# CONFIG_MPU_SENSORS_AMI306 is not set +# CONFIG_MPU_SENSORS_AMI30X is not set +# CONFIG_MPU_SENSORS_BMA085 is not set +# CONFIG_MPU_SENSORS_HMC5883 is not set +# CONFIG_MPU_SENSORS_HSCDTD002B is not set +# CONFIG_MPU_SENSORS_HSCDTD004A is not set +# CONFIG_MPU_SENSORS_LSM303DLX_M is not set +# CONFIG_MPU_SENSORS_MMC314X is not set +# CONFIG_MPU_SENSORS_MMC314XMS is not set +# CONFIG_MPU_SENSORS_MPU3050 is not set +# CONFIG_MPU_SENSORS_MPU6050A2 is not set +# CONFIG_MPU_SENSORS_MPU6050B1 is not set +# CONFIG_MPU_SENSORS_TIMERIRQ is not set +# CONFIG_MPU_SENSORS_YAS530 is not set +# CONFIG_MPU_USERSPACE_DEBUG is not set +# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_MTD is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +# CONFIG_MWIFIEX is not set +# CONFIG_MWL8K is not set +CONFIG_NAMESPACES=y +# CONFIG_NATIONAL_PHY is not set +CONFIG_NET=y +# CONFIG_NETCONSOLE is not set +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +# CONFIG_NETDEV_10000 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_ADVANCED is not set +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETLABEL is not set +# CONFIG_NETPOLL is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETWORK_SECMARK=y +# CONFIG_NET_9P is not set +CONFIG_NET_ACTIVITY_STATS=y +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_CGROUP is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_NET_DSA is not set +# CONFIG_NET_EMATCH is not set +CONFIG_NET_ETHERNET=y +# CONFIG_NET_FC is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_NET_IPIP is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +# CONFIG_NET_NS is not set +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_NET_SCHED=y +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_DSMARK is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_TULIP is not set +# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NEW_LEDS=y +# CONFIG_NFC is not set +CONFIG_NF_CONNTRACK=y +# CONFIG_NF_CONNTRACK_FTP is not set +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_IPV6=m +# CONFIG_NF_CONNTRACK_IRC is not set +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SECMARK is not set +# CONFIG_NF_CONNTRACK_SIP is not set +CONFIG_NF_CT_NETLINK=y +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_DEFRAG_IPV6=m +# CONFIG_NF_NAT is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NL80211_TESTMODE=y +CONFIG_NLATTR=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +CONFIG_NOP_TRACER=y +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_NOZOMI is not set +CONFIG_NO_HZ=y +# CONFIG_NS83820 is not set +# CONFIG_NTFS_FS is not set +# CONFIG_N_GSM is not set +# CONFIG_OMFS_FS is not set +# CONFIG_OPROFILE is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_P54_COMMON is not set +CONFIG_PACKET=y +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_PARPORT is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PCCARD is not set +# CONFIG_PCH_GBE is not set +# CONFIG_PCH_PHUB is not set +CONFIG_PCI=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_IOV is not set +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_STUB is not set +# CONFIG_PDA_POWER is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_PERF_EVENTS=y +# CONFIG_PHANTOM is not set +# CONFIG_PHONE is not set +# CONFIG_PHONET is not set +CONFIG_PHYLIB=y +CONFIG_PID_NS=y +CONFIG_PM=y +# CONFIG_PMBUS is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PM_ADVANCED_DEBUG is not set +CONFIG_PM_DEBUG=y +CONFIG_PM_RUNTIME=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_TEST_SUSPEND is not set +# CONFIG_POHMELFS is not set +# CONFIG_POSIX_MQUEUE is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPP=m +# CONFIG_PPPOE is not set +# CONFIG_PPPOLAC is not set +# CONFIG_PPPOPNS is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPS is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_RCU is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +# CONFIG_PRISM2_USB is not set +# CONFIG_PRISM54 is not set +CONFIG_PROC_EVENTS=y +CONFIG_PROC_FS=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_SYSCTL=y +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_PSTORE is not set +# CONFIG_QLA3XXX is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_R3964 is not set +# CONFIG_R8187SE is not set +# CONFIG_R8712U is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_RAID_ATTRS is not set +# CONFIG_RAMOOPS is not set +# CONFIG_RAW_DRIVER is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_RDS is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_GZIP=y +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_XZ is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_REISERFS_FS is not set +CONFIG_RELAY=y +# CONFIG_RESOURCE_COUNTERS is not set +CONFIG_RFKILL=y +# CONFIG_RFKILL_INPUT is not set +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_PM=y +CONFIG_RFS_ACCEL=y +CONFIG_RING_BUFFER=y +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_ROMFS_FS is not set +CONFIG_RPS=y +# CONFIG_RT2400PCI is not set +# CONFIG_RT2500PCI is not set +# CONFIG_RT2800PCI is not set +CONFIG_RT2X00=m +# CONFIG_RT61PCI is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_INTF_ALARM=y +CONFIG_RTC_INTF_ALARM_DEV=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +# CONFIG_RTL8180 is not set +# CONFIG_RTL8187 is not set +# CONFIG_RTL8192CU is not set +# CONFIG_RTL8192DE is not set +# CONFIG_RTL8192E is not set +# CONFIG_RTL8192SE is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTS_PSTOR is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_SAMPLES is not set +CONFIG_SCHEDSTATS=y +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHED_TRACER is not set +CONFIG_SCSI=y +# CONFIG_SCSI_DH is not set +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_MOD=y +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_WAIT_SCAN=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +# CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7461 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HMC5843 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_INA219 is not set +# CONFIG_SENSORS_INA230 is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LTR558 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_TSL2550 is not set +CONFIG_SENSORS_TSL2563=m +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +# CONFIG_SERIAL_MFD_HSU is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_SERIAL_PCH_UART is not set +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +CONFIG_SERIO=y +# CONFIG_SERIO_ALTERA_PS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_PS2MULT is not set +CONFIG_SERIO_RAW=y +CONFIG_SERIO_SERPORT=m +# CONFIG_SGI_IOC4 is not set +# CONFIG_SGI_PARTITION is not set +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +# CONFIG_SLIP is not set +# CONFIG_SLOB is not set +CONFIG_SMP=y +# CONFIG_SMSC_PHY is not set +CONFIG_SND=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_HWDEP=m +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +CONFIG_SND_JACK=y +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_MIXART is not set +CONFIG_SND_MIXER_OSS=m +# CONFIG_SND_MONA is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +CONFIG_SND_OSSEMUL=y +# CONFIG_SND_OXYGEN is not set +CONFIG_SND_PCI=y +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_PCXHR is not set +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SBAWE_SEQ is not set +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_6FIRE is not set +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_SOLO6X10 is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +# CONFIG_SOUND_PRIME is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_SPEAKUP is not set +CONFIG_SPI=y +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=m +# CONFIG_SPI_DEBUG is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_MASTER=y +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_SPIDEV=m +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_TOPCLIFF_PCH is not set +# CONFIG_SPI_XILINX is not set +CONFIG_SPLIT_PTLOCK_CPUS=999999 +CONFIG_SSB_POSSIBLE=y +CONFIG_STACKTRACE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +CONFIG_STAGING=y +CONFIG_STANDALONE=y +# CONFIG_STE10XP is not set +# CONFIG_STMMAC_ETH is not set +CONFIG_STOP_MACHINE=y +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_STUB_POULSBO is not set +# CONFIG_ST_GPS is not set +# CONFIG_SUNGEM is not set +# CONFIG_SUN_PARTITION is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_TIME is not set +# CONFIG_SWITCH is not set +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_NSC is not set +CONFIG_TCG_TPM=y +CONFIG_TCP_CONG_ADVANCED=y +# CONFIG_TCP_CONG_BIC is not set +CONFIG_TCP_CONG_CUBIC=y +# CONFIG_TCP_CONG_HSTCP is not set +# CONFIG_TCP_CONG_HTCP is not set +# CONFIG_TCP_CONG_HYBLA is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +# CONFIG_TCP_CONG_LP is not set +# CONFIG_TCP_CONG_SCALABLE is not set +# CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_VENO is not set +# CONFIG_TCP_CONG_WESTWOOD is not set +# CONFIG_TCP_CONG_YEAH is not set +CONFIG_TCP_MD5SIG=y +# CONFIG_TEGRA_CRYPTO_DEV is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_TEST_POWER is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_TICK_ONESHOT=y +# CONFIG_TIFM_CORE is not set +CONFIG_TIMERFD=y +CONFIG_TIMER_STATS=y +# CONFIG_TIPC is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_TI_ST is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_PANJIT_I2C is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_RM31080A is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +# CONFIG_TOUCHSCREEN_SYN_RMI4_SPI is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_TR is not set +# CONFIG_TRACEDUMP is not set +# CONFIG_TRACELEVEL is not set +CONFIG_TRACEPOINTS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_TRACE_SINK is not set +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_TRANZPORT is not set +CONFIG_TREE_RCU=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_TRUSTED_FOUNDATIONS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_TSL2583 is not set +# CONFIG_TTY_PRINTK is not set +CONFIG_TUN=m +# CONFIG_TWL4030_CORE is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_UFS_FS is not set +CONFIG_UID16=y +# CONFIG_UID_STAT is not set +# CONFIG_UIO is not set +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_USB=y +# CONFIG_USBIP_CORE is not set +CONFIG_USB_ACM=y +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ONOFF_FEATURE is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_ENESTORAGE is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_EZUSB is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_GSPCA is not set +CONFIG_USB_HID=y +CONFIG_USB_HIDDEV=y +# CONFIG_USB_HSO is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_LEGOTOWER is not set +CONFIG_USB_LIBUSUAL=y +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_RAW_IP is not set +CONFIG_USB_NET_RNDIS_WLAN=m +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_S2255 is not set +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BASEBAND is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_DEBUG is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_GARMIN is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +CONFIG_USB_SERIAL_OPTION=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=m +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +CONFIG_USB_SERIAL_WWAN=m +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_ZIO is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STKWEBCAM is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_USBAT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_TMC is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_UAS is not set +CONFIG_USB_VIDEO_CLASS=m +# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set +# CONFIG_USB_XHCI_HCD is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_ZR364XX is not set +CONFIG_USER_NS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_UTS_NS=y +# CONFIG_UWB is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGASTATE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_CAFE_CCIC is not set +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_CX2341X is not set +# CONFIG_VIDEO_CX25840 is not set +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DT3155 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_M52790 is not set +CONFIG_VIDEO_MEDIA=m +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_NOON010PC30 is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_SAA6588 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_USBVISION is not set +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_COMMON=m +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_VPX3220 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRT_TO_BUS=y +# CONFIG_VITESSE_PHY is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_VME_BUS is not set +# CONFIG_VMXNET3 is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +# CONFIG_VT6655 is not set +# CONFIG_VT6656 is not set +CONFIG_VT_CONSOLE=y +# CONFIG_VXFS_FS is not set +# CONFIG_W1 is not set +# CONFIG_W35UND is not set +# CONFIG_WAKELOCK is not set +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WATCHDOG is not set +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PRIV=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +# CONFIG_WIFI_CONTROL_FUNC is not set +# CONFIG_WIMAX is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +# CONFIG_WIRELESS_EXT_SYSFS is not set +# CONFIG_WL1251 is not set +# CONFIG_WL127X_RFKILL is not set +# CONFIG_WL12XX_MENU is not set +CONFIG_WLAN=y +# CONFIG_X25 is not set +CONFIG_XFRM=y +CONFIG_XFRM_IPCOMP=m +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFS_FS is not set +CONFIG_XPS=y +# CONFIG_XVMALLOC is not set +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +# CONFIG_YELLOWFIN is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +# CONFIG_ZRAM is not set diff --git a/chromeos/config/i386/config.common.i386 b/chromeos/config/i386/config.common.i386 new file mode 100644 index 000000000000..8eb8362d12f4 --- /dev/null +++ b/chromeos/config/i386/config.common.i386 @@ -0,0 +1,749 @@ +# +# Config options generated by splitconfig +# +# CONFIG_64BIT is not set +# CONFIG_ACERHDF is not set +# CONFIG_ACER_WMI is not set +CONFIG_ACPI=y +CONFIG_ACPI_AC=y +# CONFIG_ACPI_APEI is not set +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=y +# CONFIG_ACPI_CMPC is not set +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +# CONFIG_ACPI_CUSTOM_METHOD is not set +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=y +# CONFIG_ACPI_EC_DEBUGFS is not set +CONFIG_ACPI_FAN=y +# CONFIG_ACPI_HED is not set +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_PCI_SLOT is not set +CONFIG_ACPI_PROCESSOR=y +# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +# CONFIG_ACPI_QUICKSTART is not set +# CONFIG_ACPI_SBS is not set +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_VIDEO=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_AGP=y +# CONFIG_AGP_ALI is not set +# CONFIG_AGP_AMD is not set +# CONFIG_AGP_AMD64 is not set +# CONFIG_AGP_ATI is not set +# CONFIG_AGP_EFFICEON is not set +CONFIG_AGP_INTEL=y +# CONFIG_AGP_NVIDIA is not set +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_SWORKS is not set +# CONFIG_AGP_VIA is not set +# CONFIG_AIRO is not set +CONFIG_AMD_NB=y +CONFIG_ANDROID_PARANOID_NETWORK=y +# CONFIG_APM is not set +CONFIG_ARCH_CPU_PROBE_RELEASE=y +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx" +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_USES_PG_UNCACHED=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_ASUS_WMI is not set +CONFIG_ATA=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_BMDMA=y +CONFIG_ATA_GENERIC=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_PIIX=y +CONFIG_ATA_SFF=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH5K_PCI=y +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_DEBUGFS=y +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_RATE_CONTROL=y +# CONFIG_AUDIT_ARCH is not set +# CONFIG_BACKLIGHT_APPLE is not set +# CONFIG_BACKLIGHT_PROGEAR is not set +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BATTERY_BQ20Z75 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BT_ATH3K=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +# CONFIG_BT_HCIUART is not set +# CONFIG_CHARGER_GPIO is not set +CONFIG_CHECK_SIGNATURE=y +CONFIG_CLKBLD_I8253=y +CONFIG_CLKEVT_I8253=y +CONFIG_CLKSRC_I8253=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CMPXCHG_DOUBLE=y +CONFIG_CMPXCHG_LOCAL=y +# CONFIG_COMEDI is not set +# CONFIG_COMPAL_LAPTOP is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_COMPAT_VDSO is not set +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +# CONFIG_CPA_DEBUG is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +CONFIG_CRYPTO_AES_586=y +CONFIG_CRYPTO_AES_NI_INTEL=m +# CONFIG_CRYPTO_CRC32C_INTEL is not set +CONFIG_CRYPTO_CRYPTD=m +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_DEV_GEODE is not set +# CONFIG_CRYPTO_DEV_PADLOCK is not set +# CONFIG_CRYPTO_SALSA20_586 is not set +# CONFIG_CRYPTO_TWOFISH_586 is not set +# CONFIG_DCDBAS is not set +CONFIG_DEBUG_BOOT_PARAMS=y +# CONFIG_DEBUG_NX_TEST is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_SET_MODULE_RONX is not set +CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set +# CONFIG_DEBUG_VIRTUAL is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +# CONFIG_DELL_RBU is not set +CONFIG_DELL_WMI=m +# CONFIG_DELL_WMI_AIO is not set +CONFIG_DMI=y +CONFIG_DMIID=y +# CONFIG_DMI_SYSFS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_DNS_RESOLVER is not set +CONFIG_DOUBLEFAULT=y +CONFIG_DRM=y +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I810 is not set +CONFIG_DRM_I915=y +CONFIG_DRM_I915_KMS=y +CONFIG_DRM_KMS_HELPER=y +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_PSB is not set +# CONFIG_DRM_R128 is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_VMWGFX is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_EARLY_PRINTK_DBGP=y +# CONFIG_EDAC is not set +# CONFIG_EDD is not set +# CONFIG_EEEPC_LAPTOP is not set +CONFIG_EFI=y +# CONFIG_EFI_VARS is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_EPIC100 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_EFI is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_I810 is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_N411 is not set +# CONFIG_FB_VESA is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VIA is not set +# CONFIG_FEALNX is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_WARN=2048 +CONFIG_FTRACE_NMI_ENTER=y +CONFIG_FTRACE_SYSCALLS=y +# CONFIG_FUJITSU_LAPTOP is not set +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +# CONFIG_GOOGLE_FIRMWARE is not set +# CONFIG_GPIO_LANGWELL is not set +# CONFIG_GPIO_PCH is not set +# CONFIG_GPIO_SCH is not set +# CONFIG_HANGCHECK_TIMER is not set +CONFIG_HARDLOCKUP_DETECTOR=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KMEMCHECK=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ATOMIC_IOMAP=y +# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_NMI_ENTER=y +CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_TEXT_POKE_SMP=y +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HID_MICROSOFT=m +CONFIG_HID_PID=y +# CONFIG_HIGHMEM4G is not set +# CONFIG_HIGHMEM64G is not set +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_ACPI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_IBM is not set +CONFIG_HOTPLUG_PCI_PCIE=y +# CONFIG_HOTPLUG_PCI_SHPC is not set +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +# CONFIG_HPET_MMAP is not set +CONFIG_HPET_TIMER=y +# CONFIG_HP_ACCEL is not set +CONFIG_HP_WMI=m +CONFIG_HT_IRQ=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HW_RANDOM_AMD is not set +# CONFIG_HW_RANDOM_GEODE is not set +CONFIG_HW_RANDOM_INTEL=y +# CONFIG_HW_RANDOM_VIA is not set +# CONFIG_HW_RANDOM_VIRTIO is not set +# CONFIG_HYPERV is not set +CONFIG_HZ=1000 +# CONFIG_HZ_100 is not set +CONFIG_HZ_1000=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_I801=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_SCMI is not set +# CONFIG_I8K is not set +# CONFIG_IBM_ASM is not set +# CONFIG_IBM_RTL is not set +# CONFIG_IDEAPAD_LAPTOP is not set +# CONFIG_IDE_PHISON is not set +CONFIG_IGBVF=m +CONFIG_ILLEGAL_POINTER_VALUE=0 +# CONFIG_INPUT_APANEL is not set +# CONFIG_INPUT_ATLAS_BTNS is not set +CONFIG_INPUT_SPARSEKMAP=m +# CONFIG_INPUT_WISTRON_BTNS is not set +CONFIG_INSTRUCTION_DECODER=y +# CONFIG_INTEL_IDLE is not set +# CONFIG_INTEL_IOMMU is not set +# CONFIG_INTEL_IPS is not set +# CONFIG_INTEL_MEI is not set +CONFIG_INTEL_MENLOW=m +# CONFIG_INTEL_OAKTRAIL is not set +# CONFIG_IOMMU_HELPER is not set +# CONFIG_IOMMU_STRESS is not set +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IPV6=m +# CONFIG_IP_PNP is not set +CONFIG_IRQ_FORCED_THREADING=y +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_IR_ENE is not set +# CONFIG_IR_FINTEK is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_ITE_CIR is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set +# CONFIG_IR_MCEUSB is not set +CONFIG_IR_MCE_KBD_DECODER=m +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_NUVOTON is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_WINBOND_CIR is not set +# CONFIG_ISA is not set +CONFIG_ISA_DMA_API=y +# CONFIG_ISCSI_IBFT_FIND is not set +CONFIG_JME=m +# CONFIG_JUMP_LABEL is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_KTIME_SCALAR=y +# CONFIG_KVM is not set +# CONFIG_LATENCYTOP is not set +CONFIG_LBDAF=y +# CONFIG_LEDS_ALIX2 is not set +# CONFIG_LEDS_CLEVO_MAIL is not set +# CONFIG_LEDS_DELL_NETBOOKS is not set +# CONFIG_LEDS_INTEL_SS4200 is not set +# CONFIG_LGUEST is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_LIRC=m +# CONFIG_LIRC_STAGING is not set +CONFIG_LPC_SCH=m +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +CONFIG_M686=y +# CONFIG_MACINTOSH_DRIVERS is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_MATOM is not set +# CONFIG_MCA is not set +# CONFIG_MCORE2 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MELAN is not set +# CONFIG_MEMTEST is not set +CONFIG_MFD_CORE=m +# CONFIG_MFD_CS5535 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS6591X is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=y +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_OLD_INTERFACE=y +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MMC is not set +# CONFIG_MMIOTRACE is not set +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +# CONFIG_MOUSE_PS2_SENTELIC is not set +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MSI_LAPTOP is not set +# CONFIG_MSI_WMI is not set +CONFIG_MTRR=y +# CONFIG_MTRR_SANITIZER is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MWAVE is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NEED_DMA_MAP_STATE is not set +CONFIG_NEED_NODE_MEMMAP_SIZE=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_NEED_SG_DMA_LENGTH=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NET_PCI=y +# CONFIG_NET_SB1000 is not set +CONFIG_NOHIGHMEM=y +CONFIG_NO_BOOTMEM=y +CONFIG_NR_CPUS=4 +# CONFIG_NSC_GPIO is not set +CONFIG_NVRAM=y +CONFIG_OPTIMIZE_INLINING=y +CONFIG_OUTPUT_FORMAT="elf32-i386" +CONFIG_PAGE_OFFSET=0x80000000 +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_PARAVIRT_GUEST is not set +# CONFIG_PATA_ACPI is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +# CONFIG_PATA_CS5536 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PC8736x_GPIO is not set +CONFIG_PCIEAER=y +# CONFIG_PCIEAER_INJECT is not set +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +CONFIG_PCIEPORTBUS=y +# CONFIG_PCIE_ECRC is not set +CONFIG_PCIE_PME=y +CONFIG_PCI_BIOS=y +# CONFIG_PCI_CNB20LE_QUIRK is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_IOAPIC=y +CONFIG_PCI_LABEL=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +# CONFIG_PCSPKR_PLATFORM is not set +# CONFIG_PDC_ADMA is not set +CONFIG_PHYSICAL_ALIGN=0x200000 +CONFIG_PHYSICAL_START=0x1000000 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +CONFIG_PNP=y +CONFIG_PNPACPI=y +CONFIG_PNP_DEBUG_MESSAGES=y +# CONFIG_PROCESSOR_SELECT is not set +CONFIG_PROC_KCORE=y +CONFIG_PROVIDE_OHCI1394_DMA_INIT=y +# CONFIG_R6040 is not set +# CONFIG_RAPIDIO is not set +CONFIG_RC_CORE=m +# CONFIG_RC_LOOPBACK is not set +CONFIG_RC_MAP=m +CONFIG_REALTEK_AUTOPM=y +# CONFIG_REGULATOR is not set +# CONFIG_RELOCATABLE is not set +# CONFIG_REPORT_PRESENT_CPUS is not set +CONFIG_RTC_DRV_CMOS=m +# CONFIG_RTC_HCTOSYS is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_SAMSUNG_LAPTOP is not set +# CONFIG_SAMSUNG_Q10 is not set +# CONFIG_SATA_ACARD_AHCI is not set +CONFIG_SATA_AHCI=y +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PMP is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SC92031 is not set +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_SCHED_SMT=y +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCx200 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_ACPI_POWER is not set +# CONFIG_SENSORS_APPLESMC is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATK0110 is not set +CONFIG_SENSORS_CORETEMP=y +# CONFIG_SENSORS_FAM15H_POWER is not set +# CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_K10TEMP is not set +# CONFIG_SENSORS_K8TEMP is not set +# CONFIG_SENSORS_NCT1008 is not set +# CONFIG_SENSORS_VIA_CPUTEMP is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_PCIPS2=m +# CONFIG_SFI is not set +# CONFIG_SIGMA is not set +# CONFIG_SIS900 is not set +# CONFIG_SLAB is not set +# CONFIG_SLICOSS is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ASIHPI is not set +# CONFIG_SND_CS5530 is not set +CONFIG_SND_DMA_SGBUF=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_CA0132=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_HWDEP=y +# CONFIG_SND_HDA_INPUT_BEEP is not set +CONFIG_SND_HDA_INPUT_JACK=y +CONFIG_SND_HDA_INTEL=m +# CONFIG_SND_HDA_PATCH_LOADER is not set +# CONFIG_SND_HDA_PLATFORM_DRIVER is not set +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=5 +CONFIG_SND_HDA_PREALLOC_SIZE=64 +# CONFIG_SND_HDA_RECONFIG is not set +CONFIG_SND_PCM=m +# CONFIG_SND_SIS7019 is not set +# CONFIG_SND_SOC is not set +CONFIG_SND_TIMER=m +# CONFIG_SND_USB_US122L is not set +# CONFIG_SND_USB_USX2Y is not set +CONFIG_SND_VMASTER=y +# CONFIG_SOC_CAMERA is not set +# CONFIG_SONYPI is not set +# CONFIG_SONY_LAPTOP is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPARSE_IRQ=y +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SQUASHFS is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SWAP is not set +# CONFIG_TC1100_WMI is not set +# CONFIG_TCG_INFINEON is not set +CONFIG_TCG_TIS=y +# CONFIG_TELCLOCK is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_TLAN is not set +# CONFIG_TOPSTAR_LAPTOP is not set +# CONFIG_TOSHIBA is not set +# CONFIG_TOSHIBA_BT_RFKILL is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_SMSC95XX=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_STORAGE_REALTEK=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_USBNET=m +CONFIG_USER_STACKTRACE_SUPPORT=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +# CONFIG_VGA_ARB is not set +CONFIG_VGA_CONSOLE=y +# CONFIG_VGA_SWITCHEROO is not set +# CONFIG_VHOST_NET is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_GO7007 is not set +# CONFIG_VIDEO_IR_I2C is not set +# CONFIG_VIDEO_IVTV is not set +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_ZORAN is not set +CONFIG_VIRTIO=m +CONFIG_VIRTIO_BLK=m +# CONFIG_VIRTIO_CONSOLE is not set +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +# CONFIG_VM86 is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_VMSPLIT_2G=y +# CONFIG_VMSPLIT_3G is not set +# CONFIG_VMWARE_BALLOON is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_X86=y +CONFIG_X86_32=y +# CONFIG_X86_32_IRIS is not set +# CONFIG_X86_32_NON_STANDARD is not set +CONFIG_X86_32_SMP=y +# CONFIG_X86_64 is not set +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ANCIENT_MCE is not set +# CONFIG_X86_BIGSMP is not set +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_BSWAP=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_CMOV=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CMPXCHG64=y +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +CONFIG_X86_CPUID=y +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_X86_EXTENDED_PLATFORM=y +# CONFIG_X86_E_POWERSAVER is not set +# CONFIG_X86_GENERIC is not set +# CONFIG_X86_GX_SUSPMOD is not set +CONFIG_X86_HT=y +# CONFIG_X86_INTEL_MID is not set +CONFIG_X86_INTERNODE_CACHE_SHIFT=5 +CONFIG_X86_INVLPG=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=5 +CONFIG_X86_LOCAL_APIC=y +# CONFIG_X86_LONGHAUL is not set +# CONFIG_X86_LONGRUN is not set +CONFIG_X86_MCE=y +# CONFIG_X86_MCE_AMD is not set +# CONFIG_X86_MCE_INJECT is not set +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_THRESHOLD=y +CONFIG_X86_MINIMUM_CPU_FAMILY=5 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=y +# CONFIG_X86_P4_CLOCKMOD is not set +CONFIG_X86_PAE=y +CONFIG_X86_PAT=y +# CONFIG_X86_PCC_CPUFREQ is not set +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POPAD_OK=y +# CONFIG_X86_PPRO_FENCE is not set +# CONFIG_X86_PTDUMP is not set +# CONFIG_X86_RDC321X is not set +# CONFIG_X86_REBOOTFIXUPS is not set +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_RESERVE_LOW=64 +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_SPEEDSTEP_ICH is not set +# CONFIG_X86_SPEEDSTEP_LIB is not set +# CONFIG_X86_SPEEDSTEP_SMI is not set +CONFIG_X86_THERMAL_VECTOR=y +CONFIG_X86_TSC=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_VERBOSE_BOOTUP=y +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM_USER=y +# CONFIG_XO15_EBOOK is not set +CONFIG_ZONE_DMA=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ZONE_DMA_FLAG=1 diff --git a/chromeos/config/i386/config.flavour.chromeos-intel-menlow b/chromeos/config/i386/config.flavour.chromeos-intel-menlow new file mode 120000 index 000000000000..c867d1c41632 --- /dev/null +++ b/chromeos/config/i386/config.flavour.chromeos-intel-menlow @@ -0,0 +1 @@ +config.flavour.chromeos-pinetrail-i386
\ No newline at end of file diff --git a/chromeos/config/i386/config.flavour.chromeos-pinetrail-i386 b/chromeos/config/i386/config.flavour.chromeos-pinetrail-i386 new file mode 100644 index 000000000000..9a9d2991c3fd --- /dev/null +++ b/chromeos/config/i386/config.flavour.chromeos-pinetrail-i386 @@ -0,0 +1,41 @@ +# +# Config options generated by splitconfig +# +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +CONFIG_ACPI_WMI=m +# CONFIG_AMD8111_ETH is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1C is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +# CONFIG_B44 is not set +# CONFIG_BRCMSMAC is not set +# CONFIG_BRCMUTIL is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_RADEON is not set +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FORCEDETH is not set +# CONFIG_IWL3945 is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWLAGN is not set +# CONFIG_MXM_WMI is not set +# CONFIG_PCNET32 is not set +# CONFIG_R8169 is not set +# CONFIG_RT2500USB is not set +# CONFIG_RT2800USB is not set +# CONFIG_RT73USB is not set +CONFIG_RTL8192CE=m +CONFIG_RTL8192C_COMMON=m +CONFIG_RTLWIFI=m +# CONFIG_SKY2 is not set +# CONFIG_SSB is not set +# CONFIG_TIGON3 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_X86_POWERNOW_K6 is not set +# CONFIG_X86_POWERNOW_K7 is not set +# CONFIG_X86_POWERNOW_K8 is not set +# CONFIG_ZD1211RW is not set diff --git a/chromeos/config/i386/config.flavour.chromiumos-i386 b/chromeos/config/i386/config.flavour.chromiumos-i386 new file mode 100644 index 000000000000..244efff4d3ab --- /dev/null +++ b/chromeos/config/i386/config.flavour.chromiumos-i386 @@ -0,0 +1,85 @@ +# +# Config options generated by splitconfig +# +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_8129 is not set +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_ACPI_WMI=y +CONFIG_AMD8111_ETH=m +CONFIG_ATL1=m +CONFIG_ATL1C=m +CONFIG_ATL1E=m +CONFIG_ATL2=m +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +# CONFIG_BRCMDBG is not set +CONFIG_BRCMSMAC=m +CONFIG_BRCMUTIL=m +CONFIG_BROADCOM_PHY=y +CONFIG_DRM_NOUVEAU=y +CONFIG_DRM_NOUVEAU_BACKLIGHT=y +# CONFIG_DRM_NOUVEAU_DEBUG is not set +CONFIG_DRM_RADEON=y +CONFIG_DRM_RADEON_KMS=y +CONFIG_DRM_TTM=y +CONFIG_EXTRA_FIRMWARE="radeon/PALM_me.bin radeon/PALM_pfp.bin radeon/SUMO_rlc.bin" +CONFIG_EXTRA_FIRMWARE_DIR="firmware" +CONFIG_FB_BACKLIGHT=y +CONFIG_FORCEDETH=m +CONFIG_IWL3945=m +CONFIG_IWL4965=m +CONFIG_IWLAGN=m +# CONFIG_IWLWIFI_DEBUG is not set +# CONFIG_IWLWIFI_DEBUGFS is not set +# CONFIG_IWLWIFI_DEVICE_SVTOOL is not set +# CONFIG_IWLWIFI_DEVICE_TRACING is not set +CONFIG_IWLWIFI_LEGACY=m +# CONFIG_IWLWIFI_LEGACY_DEBUG is not set +# CONFIG_IWLWIFI_LEGACY_DEBUGFS is not set +# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set +# CONFIG_IWL_P2P is not set +CONFIG_MXM_WMI=y +CONFIG_PCNET32=m +CONFIG_R8169=m +CONFIG_RT2500USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +# CONFIG_RT2800USB_RT53XX is not set +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_CRYPTO=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT73USB=m +# CONFIG_RTL8192CE is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_SSB=m +# CONFIG_SSB_B43_PCI_BRIDGE is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_SILENT is not set +CONFIG_SSB_SPROM=y +CONFIG_TIGON3=m +CONFIG_USB_RTL8150=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +CONFIG_X86_POWERNOW_K6=y +CONFIG_X86_POWERNOW_K7=y +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set diff --git a/chromeos/config/x86_64/config.common.x86_64 b/chromeos/config/x86_64/config.common.x86_64 new file mode 100644 index 000000000000..ab17b2e1864c --- /dev/null +++ b/chromeos/config/x86_64/config.common.x86_64 @@ -0,0 +1,740 @@ +# +# Config options generated by splitconfig +# +CONFIG_64BIT=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_ACERHDF is not set +# CONFIG_ACER_WMI is not set +CONFIG_ACPI=y +CONFIG_ACPI_AC=y +# CONFIG_ACPI_APEI is not set +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=y +# CONFIG_ACPI_CMPC is not set +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +# CONFIG_ACPI_CUSTOM_METHOD is not set +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=y +# CONFIG_ACPI_EC_DEBUGFS is not set +CONFIG_ACPI_FAN=y +# CONFIG_ACPI_HED is not set +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_PCI_SLOT is not set +CONFIG_ACPI_PROCESSOR=y +# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +# CONFIG_ACPI_QUICKSTART is not set +# CONFIG_ACPI_SBS is not set +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_VIDEO=y +CONFIG_ACPI_WMI=m +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_AGP=y +# CONFIG_AGP_AMD64 is not set +CONFIG_AGP_INTEL=y +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_VIA is not set +# CONFIG_AIRO is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_AMD_IOMMU is not set +CONFIG_AMD_NB=y +CONFIG_ANDROID_PARANOID_NETWORK=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_CPU_PROBE_RELEASE=y +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_USES_PG_UNCACHED=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_ASUS_WMI is not set +CONFIG_ATA=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_BMDMA=y +CONFIG_ATA_GENERIC=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_PIIX=y +CONFIG_ATA_SFF=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH5K_PCI=y +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_DEBUGFS=y +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_RATE_CONTROL=y +# CONFIG_ATL1 is not set +# CONFIG_ATL1C is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +CONFIG_AUDIT_ARCH=y +# CONFIG_B44 is not set +# CONFIG_BACKLIGHT_APPLE is not set +# CONFIG_BACKLIGHT_PROGEAR is not set +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BATTERY_BQ20Z75 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLOCK_COMPAT=y +# CONFIG_BPF_JIT is not set +# CONFIG_BRCMSMAC is not set +# CONFIG_BRCMUTIL is not set +# CONFIG_BROADCOM_PHY is not set +CONFIG_BT_ATH3K=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +# CONFIG_BT_HCIUART is not set +# CONFIG_CALGARY_IOMMU is not set +# CONFIG_CHARGER_GPIO is not set +CONFIG_CHECK_SIGNATURE=y +CONFIG_CLKBLD_I8253=y +CONFIG_CLKEVT_I8253=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CMPXCHG_DOUBLE=y +CONFIG_CMPXCHG_LOCAL=y +# CONFIG_COMEDI is not set +# CONFIG_COMPAL_LAPTOP is not set +CONFIG_COMPAT=y +CONFIG_COMPAT_BINFMT_ELF=y +# CONFIG_COMPAT_BRK is not set +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +# CONFIG_COMPAT_VDSO is not set +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +# CONFIG_CPA_DEBUG is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_CPU_SUP_INTEL=y +# CONFIG_CRASH_DUMP is not set +CONFIG_CRYPTO_AES_NI_INTEL=m +CONFIG_CRYPTO_AES_X86_64=m +# CONFIG_CRYPTO_CRC32C_INTEL is not set +CONFIG_CRYPTO_CRYPTD=m +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_DEV_PADLOCK is not set +# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set +# CONFIG_CRYPTO_SALSA20_X86_64 is not set +# CONFIG_CRYPTO_TWOFISH_X86_64 is not set +# CONFIG_DCDBAS is not set +CONFIG_DEBUG_BOOT_PARAMS=y +# CONFIG_DEBUG_NX_TEST is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_SET_MODULE_RONX is not set +CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set +# CONFIG_DEBUG_VIRTUAL is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +# CONFIG_DELL_RBU is not set +CONFIG_DELL_WMI=m +# CONFIG_DELL_WMI_AIO is not set +CONFIG_DIRECT_GBPAGES=y +CONFIG_DMI=y +CONFIG_DMIID=y +# CONFIG_DMI_SYSFS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_DNS_RESOLVER is not set +CONFIG_DRM=y +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I810 is not set +CONFIG_DRM_I915=y +CONFIG_DRM_I915_KMS=y +CONFIG_DRM_KMS_HELPER=y +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_PSB is not set +# CONFIG_DRM_R128 is not set +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_VMWGFX is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_EARLY_PRINTK_DBGP=y +# CONFIG_EDAC is not set +# CONFIG_EDD is not set +# CONFIG_EEEPC_LAPTOP is not set +CONFIG_EFI=y +# CONFIG_EFI_VARS is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_EPIC100 is not set +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FB_ARC is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_EFI is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_N411 is not set +# CONFIG_FB_VESA is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VIA is not set +# CONFIG_FEALNX is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +# CONFIG_FORCEDETH is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_WARN=2048 +CONFIG_FTRACE_NMI_ENTER=y +CONFIG_FTRACE_SYSCALLS=y +# CONFIG_FUJITSU_LAPTOP is not set +CONFIG_FUNCTION_GRAPH_TRACER=y +CONFIG_GART_IOMMU=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +# CONFIG_GOOGLE_FIRMWARE is not set +# CONFIG_GPIO_LANGWELL is not set +# CONFIG_GPIO_PCH is not set +# CONFIG_GPIO_SCH is not set +# CONFIG_HANGCHECK_TIMER is not set +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_HAVE_AOUT is not set +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KMEMCHECK=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_NMI_ENTER=y +CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_TEXT_POKE_SMP=y +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HID_MICROSOFT=m +CONFIG_HID_PID=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_ACPI is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_PCIE=y +# CONFIG_HOTPLUG_PCI_SHPC is not set +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +# CONFIG_HPET_MMAP is not set +CONFIG_HPET_TIMER=y +# CONFIG_HP_ACCEL is not set +CONFIG_HP_WMI=m +CONFIG_HT_IRQ=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HW_RANDOM_AMD is not set +CONFIG_HW_RANDOM_INTEL=y +# CONFIG_HW_RANDOM_VIA is not set +# CONFIG_HW_RANDOM_VIRTIO is not set +# CONFIG_HYPERV is not set +CONFIG_HZ=1000 +# CONFIG_HZ_100 is not set +CONFIG_HZ_1000=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_I801=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_SCMI is not set +# CONFIG_I7300_IDLE is not set +# CONFIG_I8K is not set +# CONFIG_IA32_AOUT is not set +CONFIG_IA32_EMULATION=y +# CONFIG_IBM_ASM is not set +# CONFIG_IBM_RTL is not set +# CONFIG_IDEAPAD_LAPTOP is not set +# CONFIG_IDE_PHISON is not set +CONFIG_IGBVF=m +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +# CONFIG_INPUT_APANEL is not set +# CONFIG_INPUT_ATLAS_BTNS is not set +CONFIG_INPUT_SPARSEKMAP=m +CONFIG_INSTRUCTION_DECODER=y +# CONFIG_INTEL_IDLE is not set +# CONFIG_INTEL_IOMMU is not set +# CONFIG_INTEL_IPS is not set +# CONFIG_INTEL_MEI is not set +CONFIG_INTEL_MENLOW=m +# CONFIG_INTEL_OAKTRAIL is not set +# CONFIG_IOMMU_DEBUG is not set +CONFIG_IOMMU_HELPER=y +# CONFIG_IOMMU_STRESS is not set +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IPV6=m +# CONFIG_IP_PNP is not set +CONFIG_IRQ_FORCED_THREADING=y +# CONFIG_IRQ_REMAP is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_IR_ENE is not set +# CONFIG_IR_FINTEK is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_ITE_CIR is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set +# CONFIG_IR_MCEUSB is not set +CONFIG_IR_MCE_KBD_DECODER=m +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_NUVOTON is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_WINBOND_CIR is not set +CONFIG_ISA_DMA_API=y +# CONFIG_ISCSI_IBFT_FIND is not set +CONFIG_IWL3945=m +CONFIG_IWL4965=m +CONFIG_IWLAGN=m +# CONFIG_IWLWIFI_DEBUG is not set +# CONFIG_IWLWIFI_DEBUGFS is not set +# CONFIG_IWLWIFI_DEVICE_SVTOOL is not set +# CONFIG_IWLWIFI_DEVICE_TRACING is not set +CONFIG_IWLWIFI_LEGACY=m +# CONFIG_IWLWIFI_LEGACY_DEBUG is not set +# CONFIG_IWLWIFI_LEGACY_DEBUGFS is not set +# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set +# CONFIG_IWL_P2P is not set +CONFIG_JME=m +# CONFIG_JUMP_LABEL is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_XZ is not set +CONFIG_KEYS_COMPAT=y +# CONFIG_KSZ884X_PCI is not set +# CONFIG_KTIME_SCALAR is not set +# CONFIG_KVM is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_LEDS_ALIX2 is not set +# CONFIG_LEDS_CLEVO_MAIL is not set +# CONFIG_LEDS_DELL_NETBOOKS is not set +# CONFIG_LEDS_INTEL_SS4200 is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_LIRC=m +# CONFIG_LIRC_STAGING is not set +CONFIG_LPC_SCH=m +# CONFIG_MACINTOSH_DRIVERS is not set +# CONFIG_MATOM is not set +# CONFIG_MAXSMP is not set +# CONFIG_MCORE2 is not set +# CONFIG_MEMORY_FAILURE is not set +# CONFIG_MEMORY_HOTPLUG is not set +# CONFIG_MEMTEST is not set +CONFIG_MFD_CORE=m +# CONFIG_MFD_CS5535 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS6591X is not set +CONFIG_MICROCODE=y +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_OLD_INTERFACE=y +# CONFIG_MK8 is not set +# CONFIG_MMC is not set +# CONFIG_MMIOTRACE is not set +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +# CONFIG_MOUSE_PS2_SENTELIC is not set +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MPSC is not set +# CONFIG_MSI_LAPTOP is not set +# CONFIG_MSI_WMI is not set +CONFIG_MTRR=y +# CONFIG_MTRR_SANITIZER is not set +# CONFIG_MWAVE is not set +# CONFIG_MXM_WMI is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_NEED_SG_DMA_LENGTH=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NET_PCI=y +# CONFIG_NET_SB1000 is not set +CONFIG_NO_BOOTMEM=y +CONFIG_NR_CPUS=4 +# CONFIG_NUMA is not set +CONFIG_NVRAM=y +CONFIG_OPTIMIZE_INLINING=y +CONFIG_OUTPUT_FORMAT="elf64-x86-64" +CONFIG_PAGEFLAGS_EXTENDED=y +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_PARAVIRT_GUEST is not set +# CONFIG_PATA_ACPI is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5536 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +CONFIG_PCIEAER=y +# CONFIG_PCIEAER_INJECT is not set +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +CONFIG_PCIEPORTBUS=y +# CONFIG_PCIE_ECRC is not set +CONFIG_PCIE_PME=y +# CONFIG_PCI_CNB20LE_QUIRK is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_IOAPIC=y +CONFIG_PCI_LABEL=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +# CONFIG_PCNET32 is not set +# CONFIG_PCSPKR_PLATFORM is not set +# CONFIG_PDC_ADMA is not set +CONFIG_PHYSICAL_ALIGN=0x1000000 +CONFIG_PHYSICAL_START=0x1000000 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +CONFIG_PNP=y +CONFIG_PNPACPI=y +CONFIG_PNP_DEBUG_MESSAGES=y +# CONFIG_PROCESSOR_SELECT is not set +CONFIG_PROC_KCORE=y +CONFIG_PROVIDE_OHCI1394_DMA_INIT=y +# CONFIG_R6040 is not set +# CONFIG_R8169 is not set +# CONFIG_RAPIDIO is not set +CONFIG_RC_CORE=m +# CONFIG_RC_LOOPBACK is not set +CONFIG_RC_MAP=m +CONFIG_REALTEK_AUTOPM=y +# CONFIG_REGULATOR is not set +# CONFIG_RELOCATABLE is not set +# CONFIG_REPORT_PRESENT_CPUS is not set +# CONFIG_RT2500USB is not set +# CONFIG_RT2800USB is not set +# CONFIG_RT73USB is not set +CONFIG_RTC_DRV_CMOS=m +# CONFIG_RTC_HCTOSYS is not set +CONFIG_RTL8192CE=m +CONFIG_RTL8192C_COMMON=m +CONFIG_RTLWIFI=m +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_SAMSUNG_LAPTOP is not set +# CONFIG_SAMSUNG_Q10 is not set +# CONFIG_SATA_ACARD_AHCI is not set +CONFIG_SATA_AHCI=y +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PMP is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SC92031 is not set +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_SCHED_SMT=y +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_ACPI_POWER is not set +# CONFIG_SENSORS_APPLESMC is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATK0110 is not set +CONFIG_SENSORS_CORETEMP=y +# CONFIG_SENSORS_FAM15H_POWER is not set +# CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_K10TEMP is not set +# CONFIG_SENSORS_K8TEMP is not set +# CONFIG_SENSORS_NCT1008 is not set +# CONFIG_SENSORS_VIA_CPUTEMP is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_PCIPS2=m +# CONFIG_SFI is not set +# CONFIG_SIGMA is not set +# CONFIG_SIS900 is not set +# CONFIG_SKY2 is not set +# CONFIG_SLAB is not set +# CONFIG_SLICOSS is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ASIHPI is not set +# CONFIG_SND_CS5530 is not set +CONFIG_SND_DMA_SGBUF=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_CA0132=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_HWDEP=y +# CONFIG_SND_HDA_INPUT_BEEP is not set +CONFIG_SND_HDA_INPUT_JACK=y +CONFIG_SND_HDA_INTEL=m +# CONFIG_SND_HDA_PATCH_LOADER is not set +# CONFIG_SND_HDA_PLATFORM_DRIVER is not set +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=5 +CONFIG_SND_HDA_PREALLOC_SIZE=64 +# CONFIG_SND_HDA_RECONFIG is not set +CONFIG_SND_PCM=m +# CONFIG_SND_SOC is not set +CONFIG_SND_TIMER=m +# CONFIG_SND_USB_US122L is not set +# CONFIG_SND_USB_USX2Y is not set +CONFIG_SND_VMASTER=y +# CONFIG_SOC_CAMERA is not set +# CONFIG_SONY_LAPTOP is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +# CONFIG_SQUASHFS is not set +# CONFIG_SSB is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SWAP is not set +CONFIG_SWIOTLB=y +CONFIG_SYSVIPC_COMPAT=y +# CONFIG_TCG_INFINEON is not set +CONFIG_TCG_TIS=y +# CONFIG_TELCLOCK is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_TIGON3 is not set +# CONFIG_TLAN is not set +# CONFIG_TOPSTAR_LAPTOP is not set +# CONFIG_TOSHIBA_BT_RFKILL is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_SMSC95XX=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_STORAGE_REALTEK=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_USBNET=m +CONFIG_USER_STACKTRACE_SUPPORT=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +# CONFIG_VGA_ARB is not set +CONFIG_VGA_CONSOLE=y +# CONFIG_VGA_SWITCHEROO is not set +# CONFIG_VHOST_NET is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_GO7007 is not set +# CONFIG_VIDEO_IR_I2C is not set +# CONFIG_VIDEO_IVTV is not set +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_ZORAN is not set +CONFIG_VIRTIO=m +CONFIG_VIRTIO_BLK=m +# CONFIG_VIRTIO_CONSOLE is not set +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +# CONFIG_VMWARE_BALLOON is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_X86=y +# CONFIG_X86_32 is not set +CONFIG_X86_64=y +CONFIG_X86_64_SMP=y +CONFIG_X86_ACPI_CPUFREQ=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_CMOV=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CPUID=y +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_X86_EXTENDED_PLATFORM=y +CONFIG_X86_HT=y +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_MCE=y +# CONFIG_X86_MCE_AMD is not set +# CONFIG_X86_MCE_INJECT is not set +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_THRESHOLD=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=y +# CONFIG_X86_P4_CLOCKMOD is not set +CONFIG_X86_PAT=y +# CONFIG_X86_PCC_CPUFREQ is not set +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_X86_PM_TIMER=y +# CONFIG_X86_POWERNOW_K8 is not set +# CONFIG_X86_PTDUMP is not set +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_RESERVE_LOW=64 +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_SPEEDSTEP_LIB is not set +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +CONFIG_X86_THERMAL_VECTOR=y +CONFIG_X86_TSC=y +CONFIG_X86_VERBOSE_BOOTUP=y +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM_USER=y +# CONFIG_XO15_EBOOK is not set +# CONFIG_ZD1211RW is not set +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_ZONE_DMA_FLAG=1 diff --git a/chromeos/config/x86_64/config.flavour.chromeos-intel-pineview b/chromeos/config/x86_64/config.flavour.chromeos-intel-pineview new file mode 100644 index 000000000000..fad4bbee31e2 --- /dev/null +++ b/chromeos/config/x86_64/config.flavour.chromeos-intel-pineview @@ -0,0 +1,3 @@ +# +# Config options generated by splitconfig +# diff --git a/chromeos/scripts/allconfigs b/chromeos/scripts/allconfigs new file mode 100755 index 000000000000..16431991d4da --- /dev/null +++ b/chromeos/scripts/allconfigs @@ -0,0 +1,28 @@ +#!/bin/bash + +bindir="`pwd`/chromeos/scripts" +confdir="`pwd`/chromeos/config" + +get_flavourconfigs() { + for file in `find $confdir`; do + if echo $file | egrep -q "config\.flavour\..*[^~]$"; then + basename $file | awk -F . '{ print $3 }' + fi + done +} + +get_arch() { + if find . -name config.flavour.$1 | grep -q i386; then + echo i386 + else + echo arm + fi +} + +for flavour in $(get_flavourconfigs); do + echo $flavour $(get_arch $flavour) + $bindir/prepareconfig $flavour + yes "" | make ARCH=$(get_arch $flavour) oldconfig + cp .config .config-$flavour +done + diff --git a/chromeos/scripts/kernelconfig b/chromeos/scripts/kernelconfig new file mode 100755 index 000000000000..c056c8c6086f --- /dev/null +++ b/chromeos/scripts/kernelconfig @@ -0,0 +1,123 @@ +#!/bin/bash + +# Script to merge all configs and run 'make silentoldconfig' on it to wade out bad juju. +# Then split the configs into distro-commmon and flavour-specific parts + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + +mode=${1:?"Usage: $0 [oldconfig|editconfig]"} +case "$mode" in + oldconfig) ;; # All is good + editconfig) ;; # All is good + genconfig) ;; # All is good + *) echo "$0 called with invalid mode" 1>&2 + exit 1 ;; +esac +kerneldir="`pwd`" +confdir="$kerneldir/chromeos/config" +archs="x86_64 i386 armel" +family='chromeos' +bindir="`pwd`/chromeos/scripts" +common_conf="$confdir/config.common.$family" +tmpdir=`mktemp -d` + +if [ "$mode" = "genconfig" ]; then + keep=1 + mode="oldconfig" + test -d CONFIGS || mkdir CONFIGS +fi + +test -d build || mkdir build + +for arch in $archs; do + # Map debian archs to kernel archs + case "$arch" in + amd64) kernarch="x86_64" ;; + lpia) kernarch="x86" ;; + sparc) kernarch="sparc64" ;; + armel) kernarch="arm" ;; + *) kernarch="$arch" ;; + esac + + echo "" + echo "***************************************" + echo "* Processing $arch ($kernarch) ... " + archconfdir=$confdir/$arch + flavourconfigs=$(cd $archconfdir && ls config.flavour.*[^~]) + + # Merge configs + # We merge config.common.ubuntu + config.common.<arch> + + # config.flavour.<flavour> + + for config in $flavourconfigs; do + fullconf="$tmpdir/$arch-$config-full" + case $config in + *) + : >"$fullconf" + if [ -f $common_conf ]; then + cat $common_conf >> "$fullconf" + fi + if [ -f $archconfdir/config.common.$arch ]; then + cat $archconfdir/config.common.$arch >> "$fullconf" + fi + cat "$archconfdir/$config" >>"$fullconf" + ;; + esac + done + + for config in $flavourconfigs; do + if [ -f $archconfdir/$config ]; then + fullconf="$tmpdir/$arch-$config-full" + cat "$fullconf" > build/.config + # Call oldconfig or menuconfig + case "$mode" in + oldconfig) + # Weed out incorrect config parameters + echo "* Run silentoldconfig on $arch/$config ..." + make O=`pwd`/build ARCH=$kernarch silentoldconfig ;; + editconfig) + # Interactively edit config parameters + echo " * Run menuconfig on $arch/$config... Press a key." + read + make O=`pwd`/build ARCH=$kernarch menuconfig ;; + *) # Bad! + exit 1 ;; + esac + cat build/.config > $archconfdir/$config + if [ "$keep" = "1" ]; then + cat build/.config > CONFIGS/$arch-$config + fi + else + echo "!! Config not found $archconfdir/$config..." + fi + done + + echo "Running splitconfig for $arch" + echo + + # Can we make this more robust by avoiding $tmpdir completely? + # This approach was used for now because I didn't want to change + # splitconfig + (cd $archconfdir; rm config.common.$arch; $bindir/splitconfig; \ + mv config.common config.common.$arch; \ + cp config.common.$arch $tmpdir) +done + +rm -f $common_conf + +# Now run splitconfig on all the config.common.<arch> copied to +# $tmpdir +(cd $tmpdir; $bindir/splitconfig) +( + cd $confdir; + rm -f *-full + grep -v 'is UNMERGABLE' <$tmpdir/config.common >$common_conf + for arch in $archs; do + grep -v 'is UNMERGABLE' <$tmpdir/config.common.$arch \ + >$arch/config.common.$arch + done +) diff --git a/chromeos/scripts/prepareconfig b/chromeos/scripts/prepareconfig new file mode 100755 index 000000000000..b82cf35919fe --- /dev/null +++ b/chromeos/scripts/prepareconfig @@ -0,0 +1,18 @@ +#!/bin/bash + +family=chromeos + +flavourconf=$(find ${family} -name config.flavour.$1) +if [ ! -f "${flavourconf}" ]; then + echo "Found no flavour configuration for '$1'." 1>&2 + exit 1 +fi + +outputfile="${2:-.config}" + +archconfdir=$(dirname ${flavourconf}) + +# Generate .config +cat ${family}/config/config.common.${family} \ + ${archconfdir}/config.common.* \ + "${flavourconf}" > "${outputfile}" diff --git a/chromeos/scripts/splitconfig b/chromeos/scripts/splitconfig new file mode 100755 index 000000000000..262fa2015c1d --- /dev/null +++ b/chromeos/scripts/splitconfig @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +import os +import re +import sys + +allconfigs = {} + +# Parse config files +for config in os.listdir("."): + # Only config.* + if not config.startswith("config."): + continue + # Ignore emacs backups + if config.endswith("~"): + continue + # Nothing that is disabled, or remnant + if re.search("\.(default|disabled|stub)$", config): + continue + + allconfigs[config] = set() + + for line in open(config): + m = re.match("#*\s*CONFIG_(\w+)[\s=](.*)$", line) + if not m: + continue + option, value = m.groups() + allconfigs[config].add((option, value)) + +# Split out common config options +common = allconfigs.values()[0].copy() +for config in allconfigs.keys(): + common &= allconfigs[config] +for config in allconfigs.keys(): + allconfigs[config] -= common +allconfigs["config.common"] = common + +# Generate new splitconfigs +for config in allconfigs.keys(): + f = open(config, "w") + command = os.path.basename(sys.argv[0]) + print >>f, "#\n# Config options generated by %s\n#" % command + for option, value in sorted(list(allconfigs[config])): + if value == "is not set": + print >>f, "# CONFIG_%s %s" % (option, value) + else: + print >>f, "CONFIG_%s=%s" % (option, value) + + f.close() diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 5987e0ba8c2d..3807e572aef7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -83,6 +83,23 @@ config SATA_AHCI_PLATFORM If unsure, say N. +config SATA_AHCI_TEGRA + tristate "TEGRA AHCI SATA support" + depends on ARCH_TEGRA_3x_SOC + help + This option enables support for TEGRA AHCI Serial ATA. + + If unsure, say N. + +config TEGRA_SATA_IDLE_POWERGATE + bool "TEGRA SATA idle power-gating" + depends on SATA_AHCI_TEGRA && PM && PM_RUNTIME + help + This option enables power-gating during SATA idling. + This option should not be enabled if sata clocks are in dvfs_table. + + If unsure, say N. + config SATA_FSL tristate "Freescale 3.0Gbps SATA support" depends on FSL_SOC diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 9550d691fd19..4245ecf30f05 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_ATA) += libata.o # non-SFF interface obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o +obj-$(CONFIG_SATA_AHCI_TEGRA) += ahci-tegra.o libahci.o obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o obj-$(CONFIG_SATA_FSL) += sata_fsl.o diff --git a/drivers/ata/ahci-tegra.c b/drivers/ata/ahci-tegra.c new file mode 100644 index 000000000000..5c58da143c5a --- /dev/null +++ b/drivers/ata/ahci-tegra.c @@ -0,0 +1,2154 @@ +/* + * ahci-tegra.c - AHCI SATA support for TEGRA AHCI device + * + * Copyright (c) 2011-2012, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * + * libata documentation is available via 'make {ps|pdf}docs', + * as Documentation/DocBook/libata.* + * + * AHCI hardware documentation: + * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf + * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf + * + */ + +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/dma-mapping.h> +#include <linux/device.h> +#include <linux/dmi.h> +#include <scsi/scsi_host.h> +#include <scsi/scsi_cmnd.h> +#include <linux/libata.h> +#include <linux/regulator/machine.h> +#include <linux/pm_runtime.h> +#include "ahci.h" + +#include <linux/clk.h> +#include <mach/clk.h> +#include <mach/iomap.h> +#include <mach/io.h> +#include <mach/powergate.h> + +#define DRV_NAME "tegra-sata" +#define DRV_VERSION "1.0" + +#define ENABLE_AHCI_DBG_PRINT 0 +#if ENABLE_AHCI_DBG_PRINT +#define AHCI_DBG_PRINT(fmt, arg...) printk(KERN_ERR fmt, ## arg) +#else +#define AHCI_DBG_PRINT(fmt, arg...) do {} while (0) +#endif + +/* number of AHCI ports */ +#define TEGRA_AHCI_NUM_PORTS 1 + +/* idle timeout for PM in msec */ +#define TEGRA_AHCI_MIN_IDLE_TIME 1000 +#define TEGRA_AHCI_DEFAULT_IDLE_TIME 2000 + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE +static u32 tegra_ahci_idle_time = TEGRA_AHCI_DEFAULT_IDLE_TIME; +#endif + +/* Bit 0 (EN_FPCI) to allow FPCI accesses to SATA */ +#define SATA_CONFIGURATION_0_OFFSET 0x180 +#define EN_FPCI (1 << 0) + +#define SATA_INTR_MASK_0_OFFSET 0x188 +#define IP_INT_MASK (1 << 16) + +/* Need to write 0x00400200 to 0x70020094 */ +#define SATA_FPCI_BAR5_0_OFFSET 0x094 +#define PRI_ICTLR_CPU_IER_SET_0_OFFSET 0x024 +#define CPU_IER_SATA_CTL (1 << 23) + +#define AHCI_BAR5_CONFIG_LOCATION 0x24 +#define TEGRA_SATA_BAR5_INIT_PROGRAM 0xFFFFFFFF +#define TEGRA_SATA_BAR5_FINAL_PROGRAM 0x40020000 + +#define FUSE_SATA_CALIB_OFFSET 0x224 +#define FUSE_SATA_CALIB_MASK 0x3 + +#define T_SATA0_CFG_PHY_REG 0x120 +#define PHY_USE_7BIT_ALIGN_DET_FOR_SPD_MASK (1 << 11) + +#define T_SATA0_CFG_POWER_GATE 0x4ac +#define POWER_GATE_SSTS_RESTORED_MASK (1 << 23) +#define POWER_GATE_SSTS_RESTORED_YES (1 << 23) +#define POWER_GATE_SSTS_RESTORED_NO (0 << 23) + +#define T_SATA0_DBG0_OFFSET 0x550 + +#define T_SATA0_INDEX_OFFSET 0x680 +#define SATA0_NONE_SELECTED 0 +#define SATA0_CH1_SELECTED (1 << 0) + +#define T_SATA0_CHX_PHY_CTRL1_GEN1_OFFSET 0x690 +#define SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT 0 +#define SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK (0xff << 0) +#define SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT 8 +#define SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK (0xff << 8) + +#define T_SATA0_CHX_PHY_CTRL1_GEN2_OFFSET 0x694 +#define SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT 0 +#define SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK (0xff << 0) +#define SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT 12 +#define SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK (0xff << 12) +#define SATA0_CHX_PHY_CTRL1_GEN2_RX_EQ_SHIFT 24 +#define SATA0_CHX_PHY_CTRL1_GEN2_RX_EQ_MASK (0xf << 24) + +/* AHCI config space defines */ +#define TEGRA_PRIVATE_AHCI_CC_BKDR 0x4a4 +#define TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE 0x54c +#define TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE_EN (1 << 12) +#define TEGRA_PRIVATE_AHCI_CC_BKDR_PGM 0x01060100 + +/* AHCI HBA_CAP */ +#define TEGRA_PRIVATE_AHCI_CAP_BKDR 0xa0 +#define T_SATA0_AHCI_HBA_CAP_BKDR 0x300 + +#define TEGRA_SATA_IO_SPACE_OFFSET 4 +#define TEGRA_SATA_ENABLE_IO_SPACE (1 << 0) +#define TEGRA_SATA_ENABLE_MEM_SPACE (1 << 1) +#define TEGRA_SATA_ENABLE_BUS_MASTER (1 << 2) +#define TEGRA_SATA_ENABLE_SERR (1 << 8) + +#define TEGRA_SATA_CORE_CLOCK_FREQ_HZ (108*1000*1000) +#define TEGRA_SATA_OOB_CLOCK_FREQ_HZ (216*1000*1000) + +#define APB_PMC_SATA_PWRGT_0_REG 0x1ac +#define CLK_RST_SATA_PLL_CFG0_REG 0x490 +#define CLK_RST_SATA_PLL_CFG1_REG 0x494 +#define SATA_AUX_PAD_PLL_CNTL_1_REG 0x1100 +#define SATA_AUX_MISC_CNTL_1_REG 0x1108 + +/* for APB_PMC_SATA_PWRGT_0_REG */ +#define PG_INFO_MASK (1 << 6) +#define PG_INFO_ON (1 << 6) +#define PG_INFO_OFF (0 << 6) +#define PLLE_IDDQ_SWCTL_MASK (1 << 4) +#define PLLE_IDDQ_SWCTL_ON (1 << 4) +#define PLLE_IDDQ_SWCTL_OFF (0 << 4) +#define PADPHY_IDDQ_OVERRIDE_VALUE_MASK (1 << 3) +#define PADPHY_IDDQ_OVERRIDE_VALUE_ON (1 << 3) +#define PADPHY_IDDQ_OVERRIDE_VALUE_OFF (0 << 3) +#define PADPHY_IDDQ_SWCTL_MASK (1 << 2) +#define PADPHY_IDDQ_SWCTL_ON (1 << 2) +#define PADPHY_IDDQ_SWCTL_OFF (0 << 2) +#define PADPLL_IDDQ_OVERRIDE_VALUE_MASK (1 << 1) +#define PADPLL_IDDQ_OVERRIDE_VALUE_ON (1 << 1) +#define PADPLL_IDDQ_OVERRIDE_VALUE_OFF (0 << 1) +#define PADPLL_IDDQ_SWCTL_MASK (1 << 0) +#define PADPLL_IDDQ_SWCTL_ON (1 << 0) +#define PADPLL_IDDQ_SWCTL_OFF (0 << 0) + +/* for CLK_RST_SATA_PLL_CFG0_REG */ +#define PADPLL_RESET_OVERRIDE_VALUE_MASK (1 << 1) +#define PADPLL_RESET_OVERRIDE_VALUE_ON (1 << 1) +#define PADPLL_RESET_OVERRIDE_VALUE_OFF (0 << 1) +#define PADPLL_RESET_SWCTL_MASK (1 << 0) +#define PADPLL_RESET_SWCTL_ON (1 << 0) +#define PADPLL_RESET_SWCTL_OFF (0 << 0) + +/* for CLK_RST_SATA_PLL_CFG1_REG */ +#define IDDQ2LANE_SLUMBER_DLY_MASK (0xffL << 16) +#define IDDQ2LANE_SLUMBER_DLY_SHIFT 16 +#define IDDQ2LANE_SLUMBER_DLY_3MS (3 << 16) +#define IDDQ2LANE_IDDQ_DLY_SHIFT 0 +#define IDDQ2LANE_IDDQ_DLY_MASK (0xffL << 0) + +/* for SATA_AUX_PAD_PLL_CNTL_1_REG */ +#define REFCLK_SEL_MASK (3 << 11) +#define REFCLK_SEL_INT_CML (0 << 11) +#define LOCKDET_FIELD (1 << 6) + +/* for SATA_AUX_MISC_CNTL_1_REG */ +#define NVA2SATA_OOB_ON_POR_MASK (1 << 7) +#define NVA2SATA_OOB_ON_POR_YES (1 << 7) +#define NVA2SATA_OOB_ON_POR_NO (0 << 7) +#define L0_RX_IDLE_T_SAX_SHIFT 5 +#define L0_RX_IDLE_T_SAX_MASK (3 << 5) +#define L0_RX_IDLE_T_NPG_SHIFT 3 +#define L0_RX_IDLE_T_NPG_MASK (3 << 3) +#define L0_RX_IDLE_T_MUX_MASK (1 << 2) +#define L0_RX_IDLE_T_MUX_FROM_APB_MISC (1 << 2) +#define L0_RX_IDLE_T_MUX_FROM_SATA (0 << 2) + +#define SSTAT_IPM_STATE_MASK 0xF00 +#define SSTAT_IPM_SLUMBER_STATE 0x600 + +enum { + AHCI_PCI_BAR = 5, +}; + +enum port_idle_status { + PORT_IS_NOT_IDLE, + PORT_IS_IDLE, + PORT_IS_IDLE_NOT_SLUMBER, + PORT_IS_SLUMBER, +}; + +enum sata_state { + SATA_ON, + SATA_OFF, + SATA_GOING_ON, + SATA_GOING_OFF, + SATA_ABORT_OFF, +}; + +char *sata_power_rails[] = { + "avdd_sata", + "vdd_sata", + "hvdd_sata", + "avdd_sata_pll" +}; + +#define NUM_SATA_POWER_RAILS ARRAY_SIZE(sata_power_rails) + +struct tegra_qc_list { + struct list_head list; + struct ata_queued_cmd *qc; +}; + +/* + * tegra_ahci_host_priv is the extension of ahci_host_priv + * with extra fields: idle_timer, pg_save, pg_state, etc. + */ +struct tegra_ahci_host_priv { + struct ahci_host_priv ahci_host_priv; + struct regulator *power_rails[NUM_SATA_POWER_RAILS]; + void __iomem *bars_table[6]; + struct ata_host *host; + struct timer_list idle_timer; + struct device *dev; + void *pg_save; + enum sata_state pg_state; + struct list_head qc_list; +}; + +static int tegra_ahci_init_one(struct platform_device *pdev); +static int tegra_ahci_remove_one(struct platform_device *pdev); + +#ifdef CONFIG_PM +static bool tegra_ahci_power_un_gate(struct ata_host *host); +static bool tegra_ahci_power_gate(struct ata_host *host); +static void tegra_ahci_abort_power_gate(struct ata_host *host); +static int tegra_ahci_controller_suspend(struct platform_device *pdev); +static int tegra_ahci_controller_resume(struct platform_device *pdev); +static int tegra_ahci_suspend(struct platform_device *pdev, pm_message_t mesg); +static int tegra_ahci_resume(struct platform_device *pdev); +static enum port_idle_status tegra_ahci_is_port_idle(struct ata_port *ap); +static enum port_idle_status tegra_ahci_is_port_slumber(struct ata_port *ap); +static bool tegra_ahci_are_all_ports_idle(struct ata_host *host); +static bool tegra_ahci_are_all_ports_slumber(struct ata_host *host); +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE +static unsigned int tegra_ahci_qc_issue(struct ata_queued_cmd *qc); +static int tegra_ahci_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline); +static int tegra_ahci_runtime_suspend(struct device *dev); +static int tegra_ahci_runtime_resume(struct device *dev); +static void tegra_ahci_idle_timer(unsigned long arg); +static int tegra_ahci_queue_one_qc(struct tegra_ahci_host_priv *tegra_hpriv, + struct ata_queued_cmd *qc); +static void tegra_ahci_dequeue_qcs(struct tegra_ahci_host_priv *tegra_hpriv); +#endif +#else +#define tegra_ahci_controller_suspend NULL +#define tegra_ahci_controller_resume NULL +#define tegra_ahci_suspend NULL +#define tegra_ahci_resume NULL +#endif + +static struct scsi_host_template ahci_sht = { + AHCI_SHT("tegra-sata"), +}; + +static struct ata_port_operations tegra_ahci_ops = { + .inherits = &ahci_ops, +#ifdef CONFIG_PM +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE + .qc_issue = tegra_ahci_qc_issue, + .hardreset = tegra_ahci_hardreset, +#endif +#endif +}; + +static const struct ata_port_info ahci_port_info = { + .flags = AHCI_FLAG_COMMON, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = ATA_UDMA6, + .port_ops = &tegra_ahci_ops, +}; + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE +static const struct dev_pm_ops tegra_ahci_dev_rt_ops = { + .runtime_suspend = tegra_ahci_runtime_suspend, + .runtime_resume = tegra_ahci_runtime_resume, +}; +#endif + +static struct platform_driver tegra_platform_ahci_driver = { + .probe = tegra_ahci_init_one, + .remove = __devexit_p(tegra_ahci_remove_one), +#ifdef CONFIG_PM + .suspend = tegra_ahci_suspend, + .resume = tegra_ahci_resume, + .driver = { + .name = DRV_NAME, +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE + .pm = &tegra_ahci_dev_rt_ops, +#endif + } +#else + .driver = { + .name = DRV_NAME, + } +#endif +}; + +struct tegra_ahci_host_priv *g_tegra_hpriv; + +static inline u32 pmc_readl(u32 offset) +{ + u32 val; + val = readl(IO_ADDRESS(TEGRA_PMC_BASE + offset)); + AHCI_DBG_PRINT("[0x%x] => 0x%08x\n", TEGRA_PMC_BASE+offset, val); + return val; +} + +static inline void pmc_writel(u32 val, u32 offset) +{ + AHCI_DBG_PRINT("[0x%x] <= 0x%08x\n", TEGRA_PMC_BASE+offset, val); + writel(val, IO_ADDRESS(TEGRA_PMC_BASE + offset)); +} + +static inline u32 clk_readl(u32 offset) +{ + u32 val; + + val = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + offset)); + AHCI_DBG_PRINT("[0x%x] => 0x%08x\n", TEGRA_CLK_RESET_BASE+offset, val); + return val; +} + +static inline void clk_writel(u32 val, u32 offset) +{ + AHCI_DBG_PRINT("[0x%x] <= 0x%08x\n", TEGRA_CLK_RESET_BASE+offset, val); + writel(val, IO_ADDRESS(TEGRA_CLK_RESET_BASE + offset)); +} + +static inline u32 misc_readl(u32 offset) +{ + u32 val; + + val = readl(IO_ADDRESS(TEGRA_APB_MISC_BASE + offset)); + AHCI_DBG_PRINT("[0x%x] => 0x%08x\n", TEGRA_APB_MISC_BASE+offset, val); + return val; +} + +static inline void misc_writel(u32 val, u32 offset) +{ + AHCI_DBG_PRINT("[0x%x] <= 0x%08x\n", TEGRA_APB_MISC_BASE+offset, val); + writel(val, IO_ADDRESS(TEGRA_APB_MISC_BASE + offset)); +} + +static inline u32 sata_readl(u32 offset) +{ + u32 val; + + val = readl(IO_ADDRESS(TEGRA_SATA_BASE + offset)); + AHCI_DBG_PRINT("[0x%x] => 0x%08x\n", TEGRA_SATA_BASE+offset, val); + return val; +} + +static inline void sata_writel(u32 val, u32 offset) +{ + AHCI_DBG_PRINT("[0x%x] <= 0x%08x\n", TEGRA_SATA_BASE+offset, val); + writel(val, IO_ADDRESS(TEGRA_SATA_BASE + offset)); +} + +static inline u32 scfg_readl(u32 offset) +{ + u32 val; + + val = readl(IO_ADDRESS(TEGRA_SATA_CONFIG_BASE + offset)); + AHCI_DBG_PRINT("[0x%x] => 0x%08x\n", TEGRA_SATA_CONFIG_BASE+offset, + val); + return val; +} + +static inline void scfg_writel(u32 val, u32 offset) +{ + AHCI_DBG_PRINT("[0x%x] <= 0x%08x\n", TEGRA_SATA_CONFIG_BASE+offset, + val); + writel(val, IO_ADDRESS(TEGRA_SATA_CONFIG_BASE + offset)); +} + +static inline u32 pictlr_readl(u32 offset) +{ + u32 val; + + val = readl(IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE + offset)); + AHCI_DBG_PRINT("[0x%x] => 0x%08x\n", TEGRA_PRIMARY_ICTLR_BASE+offset, + val); + return val; +} + +static inline void pictlr_writel(u32 val, u32 offset) +{ + AHCI_DBG_PRINT("[0x%x] <= 0x%08x\n", TEGRA_PRIMARY_ICTLR_BASE+offset, + val); + writel(val, IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE + offset)); +} + +static inline u32 fuse_readl(u32 offset) +{ + u32 val; + + val = readl(IO_ADDRESS(TEGRA_FUSE_BASE + offset)); + AHCI_DBG_PRINT("[0x%x] => 0x%08x\n", TEGRA_FUSE_BASE+offset, val); + + return val; +} + +/* Sata Pad Cntrl Values */ +struct sata_pad_cntrl { + u8 gen1_tx_amp; + u8 gen1_tx_peak; + u8 gen2_tx_amp; + u8 gen2_tx_peak; +}; + +static const struct sata_pad_cntrl sata_calib_pad_val[] = { + { /* SATA_CALIB[1:0] = 00 */ + 0x0c, + 0x04, + 0x0e, + 0x0a + }, + { /* SATA_CALIB[1:0] = 01 */ + 0x0e, + 0x04, + 0x14, + 0x0a + }, + { /* SATA_CALIB[1:0] = 10 */ + 0x0e, + 0x07, + 0x1a, + 0x0e + }, + { /* SATA_CALIB[1:0] = 11 */ + 0x14, + 0x0e, + 0x1a, + 0x0e + } +}; + +static void tegra_ahci_set_pad_cntrl_regs(void) +{ + int calib_val; + int val; + int i; + + calib_val = fuse_readl(FUSE_SATA_CALIB_OFFSET) & FUSE_SATA_CALIB_MASK; + + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) { + scfg_writel((1 << i), T_SATA0_INDEX_OFFSET); + + val = scfg_readl(T_SATA0_CHX_PHY_CTRL1_GEN1_OFFSET); + val &= ~SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK; + val |= (sata_calib_pad_val[calib_val].gen1_tx_amp << + SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT); + scfg_writel(val, T_SATA0_CHX_PHY_CTRL1_GEN1_OFFSET); + + val = scfg_readl(T_SATA0_CHX_PHY_CTRL1_GEN1_OFFSET); + val &= ~SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK; + val |= (sata_calib_pad_val[calib_val].gen1_tx_peak << + SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT); + scfg_writel(val, T_SATA0_CHX_PHY_CTRL1_GEN1_OFFSET); + + val = scfg_readl(T_SATA0_CHX_PHY_CTRL1_GEN2_OFFSET); + val &= ~SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK; + val |= (sata_calib_pad_val[calib_val].gen2_tx_amp << + SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT); + scfg_writel(val, T_SATA0_CHX_PHY_CTRL1_GEN2_OFFSET); + + val = scfg_readl(T_SATA0_CHX_PHY_CTRL1_GEN2_OFFSET); + val &= ~SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK; + val |= (sata_calib_pad_val[calib_val].gen2_tx_peak << + SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT); + scfg_writel(val, T_SATA0_CHX_PHY_CTRL1_GEN2_OFFSET); + + /* set 2 to SATA0_CHX_PHY_CTRL1_GEN2_RX_EQ field */ + val = scfg_readl(T_SATA0_CHX_PHY_CTRL1_GEN2_OFFSET); + val &= ~SATA0_CHX_PHY_CTRL1_GEN2_RX_EQ_MASK; + val |= (2 << SATA0_CHX_PHY_CTRL1_GEN2_RX_EQ_SHIFT); + scfg_writel(val, T_SATA0_CHX_PHY_CTRL1_GEN2_OFFSET); + } + scfg_writel(SATA0_NONE_SELECTED, T_SATA0_INDEX_OFFSET); +} + +int tegra_ahci_get_rails(struct regulator *regulators[]) +{ + struct regulator *reg; + int i; + int ret = 0; + + for (i = 0; i < NUM_SATA_POWER_RAILS; ++i) { + reg = regulator_get(NULL, sata_power_rails[i]); + if (IS_ERR_OR_NULL(reg)) { + pr_err("%s: can't get regulator %s\n", + __func__, sata_power_rails[i]); + WARN_ON(1); + ret = PTR_ERR(reg); + goto exit; + } + regulators[i] = reg; + } +exit: + return ret; +} + +void tegra_ahci_put_rails(struct regulator *regulators[]) +{ + int i; + + for (i = 0; i < NUM_SATA_POWER_RAILS; ++i) + regulator_put(regulators[i]); +} + +int tegra_ahci_power_on_rails(struct regulator *regulators[]) +{ + struct regulator *reg; + int i; + int ret = 0; + + for (i = 0; i < NUM_SATA_POWER_RAILS; ++i) { + reg = regulators[i]; + ret = regulator_enable(reg); + if (ret) { + pr_err("%s: can't enable regulator[%d]\n", + __func__, i); + WARN_ON(1); + goto exit; + } + } + +exit: + return ret; +} + +int tegra_ahci_power_off_rails(struct regulator *regulators[]) +{ + struct regulator *reg; + int i; + int ret = 0; + + for (i = 0; i < NUM_SATA_POWER_RAILS; ++i) { + reg = regulators[i]; + if (!IS_ERR_OR_NULL(reg)) { + ret = regulator_disable(reg); + if (ret) { + pr_err("%s: can't disable regulator[%d]\n", + __func__, i); + WARN_ON(1); + goto exit; + } + } + } + +exit: + return ret; +} +static int tegra_ahci_controller_init(struct tegra_ahci_host_priv *tegra_hpriv) +{ + int err; + struct clk *clk_sata = NULL; + struct clk *clk_sata_oob = NULL; + struct clk *clk_sata_cold = NULL; + struct clk *clk_pllp = NULL; + u32 val; + u32 timeout; + + err = tegra_ahci_get_rails(tegra_hpriv->power_rails); + if (err) { + pr_err("%s: fails to get rails (%d)\n", __func__, err); + goto exit; + } + + err = tegra_ahci_power_on_rails(tegra_hpriv->power_rails); + if (err) { + pr_err("%s: fails to power on rails (%d)\n", __func__, err); + goto exit; + } + + /* pll_p is the parent of tegra_sata and tegra_sata_oob */ + clk_pllp = clk_get_sys(NULL, "pll_p"); + if (IS_ERR_OR_NULL(clk_pllp)) { + pr_err("%s: unable to get PLL_P clock\n", __func__); + err = -ENODEV; + goto exit; + } + + clk_sata = clk_get_sys("tegra_sata", NULL); + if (IS_ERR_OR_NULL(clk_sata)) { + pr_err("%s: unable to get SATA clock\n", __func__); + err = -ENODEV; + goto exit; + } + + clk_sata_oob = clk_get_sys("tegra_sata_oob", NULL); + if (IS_ERR_OR_NULL(clk_sata_oob)) { + pr_err("%s: unable to get SATA OOB clock\n", __func__); + err = -ENODEV; + goto exit; + } + + clk_sata_cold = clk_get_sys("tegra_sata_cold", NULL); + if (IS_ERR_OR_NULL(clk_sata_cold)) { + pr_err("%s: unable to get SATA COLD clock\n", __func__); + err = -ENODEV; + goto exit; + } + + tegra_periph_reset_assert(clk_sata); + tegra_periph_reset_assert(clk_sata_oob); + tegra_periph_reset_assert(clk_sata_cold); + udelay(10); + + /* need to establish both clocks divisors before setting clk sources */ + clk_set_rate(clk_sata, clk_get_rate(clk_sata)/10); + clk_set_rate(clk_sata_oob, clk_get_rate(clk_sata_oob)/10); + + /* set SATA clk and SATA_OOB clk source */ + clk_set_parent(clk_sata, clk_pllp); + clk_set_parent(clk_sata_oob, clk_pllp); + + /* Configure SATA clocks */ + /* Core clock runs at 108MHz */ + if (clk_set_rate(clk_sata, TEGRA_SATA_CORE_CLOCK_FREQ_HZ)) { + err = -ENODEV; + goto exit; + } + /* OOB clock runs at 216MHz */ + if (clk_set_rate(clk_sata_oob, TEGRA_SATA_OOB_CLOCK_FREQ_HZ)) { + err = -ENODEV; + goto exit; + } + + /**** Init the SATA PAD PLL ****/ + /* SATA_PADPLL_IDDQ_SWCTL=1 and SATA_PADPLL_IDDQ_OVERRIDE_VALUE=1 */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~(PADPLL_IDDQ_SWCTL_MASK | PADPLL_IDDQ_OVERRIDE_VALUE_MASK); + val |= (PADPLL_IDDQ_SWCTL_ON | PADPLL_IDDQ_OVERRIDE_VALUE_ON); + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + /* SATA_PADPLL_RESET_OVERRIDE_VALUE=1 and SATA_PADPLL_RESET_SWCTL=1 */ + val = clk_readl(CLK_RST_SATA_PLL_CFG0_REG); + val &= ~(PADPLL_RESET_OVERRIDE_VALUE_MASK | PADPLL_RESET_SWCTL_MASK); + val |= (PADPLL_RESET_OVERRIDE_VALUE_ON | PADPLL_RESET_SWCTL_ON); + clk_writel(val, CLK_RST_SATA_PLL_CFG0_REG); + + /* SATA_PADPHY_IDDQ_OVERRIDE_VALUE and SATA_PADPHY_IDDQ_SWCTL = 1 */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~(PADPHY_IDDQ_OVERRIDE_VALUE_MASK | PADPHY_IDDQ_SWCTL_MASK); + val |= (PADPHY_IDDQ_OVERRIDE_VALUE_ON | PADPHY_IDDQ_SWCTL_ON); + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + /* Get SATA pad PLL out of IDDQ mode */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~PADPLL_IDDQ_OVERRIDE_VALUE_MASK; + val |= PADPLL_IDDQ_OVERRIDE_VALUE_OFF; + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + udelay(3); + + /* select internal CML ref clk + * select PLLE as input to IO phy */ + val = misc_readl(SATA_AUX_PAD_PLL_CNTL_1_REG); + val &= ~REFCLK_SEL_MASK; + val |= REFCLK_SEL_INT_CML; + misc_writel(val, SATA_AUX_PAD_PLL_CNTL_1_REG); + + /* wait for SATA_PADPLL_IDDQ2LANE_SLUMBER_DLY = 3 microseconds. */ + val = clk_readl(CLK_RST_SATA_PLL_CFG1_REG); + val &= ~IDDQ2LANE_SLUMBER_DLY_MASK; + val |= IDDQ2LANE_SLUMBER_DLY_3MS; + clk_writel(val, CLK_RST_SATA_PLL_CFG1_REG); + udelay(3); + + /* de-assert IDDQ mode signal going to PHY */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~PADPHY_IDDQ_OVERRIDE_VALUE_MASK; + val |= PADPHY_IDDQ_OVERRIDE_VALUE_OFF; + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + err = tegra_unpowergate_partition_with_clk_on(TEGRA_POWERGATE_SATA); + if (err) { + pr_err("%s: ** failed to turn-on SATA (0x%x) **\n", + __func__, err); + goto exit; + } + + /* + * place SATA Pad PLL out of reset by writing + * SATA_PADPLL_RST_OVERRIDE_VALUE = 0 + */ + val = clk_readl(CLK_RST_SATA_PLL_CFG0_REG); + val &= ~PADPLL_RESET_OVERRIDE_VALUE_MASK; + val |= PADPLL_RESET_OVERRIDE_VALUE_OFF; + clk_writel(val, CLK_RST_SATA_PLL_CFG0_REG); + + /* + * Wait for SATA_AUX_PAD_PLL_CNTL_1_0_LOCKDET to turn 1 with a timeout + * of 15 us. + */ + timeout = 15; + while (timeout--) { + udelay(1); + val = misc_readl(SATA_AUX_PAD_PLL_CNTL_1_REG); + if (val & LOCKDET_FIELD) + break; + } + if (timeout == 0) + pr_err("%s: AUX_PAD_PLL_CNTL_1 (0x%x) is not locked in 15us.\n", + __func__, val); + + /* clear SW control of SATA PADPLL, SATA PHY and PLLE */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~(PADPLL_IDDQ_SWCTL_MASK | PADPHY_IDDQ_SWCTL_MASK | + PLLE_IDDQ_SWCTL_MASK); + val |= (PADPLL_IDDQ_SWCTL_OFF | PADPHY_IDDQ_SWCTL_OFF | + PLLE_IDDQ_SWCTL_OFF); + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + val = clk_readl(CLK_RST_SATA_PLL_CFG0_REG); + val &= ~PADPLL_RESET_SWCTL_MASK; + val |= PADPLL_RESET_SWCTL_OFF; + clk_writel(val, CLK_RST_SATA_PLL_CFG0_REG); + + /* clear NVA2SATA_OOB_ON_POR in SATA_AUX_MISC_CNTL_1_REG */ + val = misc_readl(SATA_AUX_MISC_CNTL_1_REG); + val &= ~NVA2SATA_OOB_ON_POR_MASK; + misc_writel(val, SATA_AUX_MISC_CNTL_1_REG); + + val = sata_readl(SATA_CONFIGURATION_0_OFFSET); + val |= EN_FPCI; + sata_writel(val, SATA_CONFIGURATION_0_OFFSET); + + /* program sata pad control based on the fuse */ + tegra_ahci_set_pad_cntrl_regs(); + + /* + * clear bit T_SATA0_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD of + * T_SATA0_CFG_PHY_0 + */ + val = scfg_readl(T_SATA0_CFG_PHY_REG); + val &= ~PHY_USE_7BIT_ALIGN_DET_FOR_SPD_MASK; + scfg_writel(val, T_SATA0_CFG_PHY_REG); + + /* + * WAR: Before enabling SATA PLL shutdown, lockdet needs to be ignored. + * To ignore lockdet, T_SATA0_DBG0_OFFSET register bit 10 needs to + * be 1, and bit 8 needs to be 0. + */ + val = scfg_readl(T_SATA0_DBG0_OFFSET); + val |= (1 << 10); + val &= ~(1 << 8); + scfg_writel(val, T_SATA0_DBG0_OFFSET); + + /* program class code and programming interface for AHCI */ + val = scfg_readl(TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE); + val |= TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE_EN; + scfg_writel(val, TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE); + scfg_writel(TEGRA_PRIVATE_AHCI_CC_BKDR_PGM, TEGRA_PRIVATE_AHCI_CC_BKDR); + val &= ~TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE_EN; + scfg_writel(val, TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE); + + /* Program config space registers: */ + + /* Enable BUS_MASTER+MEM+IO space, and SERR */ + val = scfg_readl(TEGRA_SATA_IO_SPACE_OFFSET); + val |= TEGRA_SATA_ENABLE_IO_SPACE | TEGRA_SATA_ENABLE_MEM_SPACE | + TEGRA_SATA_ENABLE_BUS_MASTER | TEGRA_SATA_ENABLE_SERR; + scfg_writel(val, TEGRA_SATA_IO_SPACE_OFFSET); + + /* program bar5 space, by first writing 1's to bar5 register */ + scfg_writel(TEGRA_SATA_BAR5_INIT_PROGRAM, AHCI_BAR5_CONFIG_LOCATION); + /* flush */ + val = scfg_readl(AHCI_BAR5_CONFIG_LOCATION); + + /* then, write the BAR5_FINAL_PROGRAM address */ + scfg_writel(TEGRA_SATA_BAR5_FINAL_PROGRAM, AHCI_BAR5_CONFIG_LOCATION); + /* flush */ + scfg_readl(AHCI_BAR5_CONFIG_LOCATION); + + sata_writel((TEGRA_SATA_BAR5_FINAL_PROGRAM >> 8), + SATA_FPCI_BAR5_0_OFFSET); + + val = scfg_readl(T_SATA0_AHCI_HBA_CAP_BKDR); + val |= (HOST_CAP_ALPM | HOST_CAP_SSC | HOST_CAP_PART); + scfg_writel(val, T_SATA0_AHCI_HBA_CAP_BKDR); + + /* enable Interrupt channel */ + val = pictlr_readl(PRI_ICTLR_CPU_IER_SET_0_OFFSET); + val |= CPU_IER_SATA_CTL; + pictlr_writel(val, PRI_ICTLR_CPU_IER_SET_0_OFFSET); + + /* set IP_INT_MASK */ + val = sata_readl(SATA_INTR_MASK_0_OFFSET); + val |= IP_INT_MASK; + sata_writel(val, SATA_INTR_MASK_0_OFFSET); + +exit: + if (!IS_ERR_OR_NULL(clk_pllp)) + clk_put(clk_pllp); + if (!IS_ERR_OR_NULL(clk_sata)) + clk_put(clk_sata); + if (!IS_ERR_OR_NULL(clk_sata_oob)) + clk_put(clk_sata_oob); + if (!IS_ERR_OR_NULL(clk_sata_cold)) + clk_put(clk_sata_cold); + + if (err) { + /* turn off all SATA power rails; ignore returned status */ + tegra_ahci_power_off_rails(tegra_hpriv->power_rails); + /* return regulators to system */ + tegra_ahci_put_rails(tegra_hpriv->power_rails); + } + + return err; +} + +static void tegra_ahci_save_initial_config(struct platform_device *pdev, + struct ahci_host_priv *hpriv) +{ + ahci_save_initial_config(&pdev->dev, hpriv, 0, 0); +} + +static void tegra_ahci_controller_remove(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct tegra_ahci_host_priv *tegra_hpriv; + int status; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + +#ifdef CONFIG_PM + /* call tegra_ahci_controller_suspend() to power-down the SATA */ + status = tegra_ahci_controller_suspend(pdev); + if (status) + dev_err(host->dev, "remove: error suspend SATA (0x%x)\n", + status); +#else + /* power off the sata */ + status = tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA); + if (status) + dev_err(host->dev, "remove: error turn-off SATA (0x%x)\n", + status); + tegra_ahci_power_off_rails(tegra_hpriv->power_rails); +#endif + + /* return system resources */ + tegra_ahci_put_rails(tegra_hpriv->power_rails); +} + +#ifdef CONFIG_PM +static int tegra_ahci_controller_suspend(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct tegra_ahci_host_priv *tegra_hpriv; + unsigned long flags; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + /* stop the idle timer */ + if (timer_pending(&tegra_hpriv->idle_timer)) + del_timer_sync(&tegra_hpriv->idle_timer); + + spin_lock_irqsave(&host->lock, flags); + if (tegra_hpriv->pg_state == SATA_OFF) + dev_dbg(host->dev, "suspend: SATA already power gated\n"); + else { + bool pg_ok; + + dev_dbg(host->dev, "suspend: power gating SATA...\n"); + pg_ok = tegra_ahci_power_gate(host); + if (pg_ok) { + tegra_hpriv->pg_state = SATA_OFF; + dev_dbg(host->dev, "suspend: SATA is power gated\n"); + } else { + dev_err(host->dev, "suspend: abort power gating\n"); + tegra_ahci_abort_power_gate(host); + spin_unlock_irqrestore(&host->lock, flags); + return -EBUSY; + } + } + spin_unlock_irqrestore(&host->lock, flags); + + return tegra_ahci_power_off_rails(tegra_hpriv->power_rails); +} + +static int tegra_ahci_controller_resume(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct tegra_ahci_host_priv *tegra_hpriv; + unsigned long flags; + int err; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + err = tegra_ahci_power_on_rails(tegra_hpriv->power_rails); + if (err) { + pr_err("%s: fails to power on rails (%d)\n", __func__, err); + return err; + } + + spin_lock_irqsave(&host->lock, flags); + if (!tegra_hpriv->pg_state == SATA_ON) { + dev_dbg(host->dev, "resume: SATA already powered on\n"); + } else { + dev_dbg(host->dev, "resume: powering on SATA...\n"); + tegra_ahci_power_un_gate(host); + tegra_hpriv->pg_state = SATA_ON; + } + spin_unlock_irqrestore(&host->lock, flags); + + return 0; +} + +static int tegra_ahci_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; + u32 ctl; + int rc; + + dev_dbg(host->dev, "** entering %s: **\n", __func__); + if (mesg.event & PM_EVENT_SLEEP) { + /* + * AHCI spec rev1.1 section 8.3.3: + * Software must disable interrupts prior to requesting a + * transition of the HBA to D3 state. + */ + ctl = readl(mmio + HOST_CTL); + ctl &= ~HOST_IRQ_EN; + writel(ctl, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + } + + rc = ata_host_suspend(host, mesg); + if (rc) + return rc; + + return tegra_ahci_controller_suspend(pdev); +} + +static int tegra_ahci_resume(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int rc; + + dev_dbg(host->dev, "** entering %s: **\n", __func__); + rc = tegra_ahci_controller_resume(pdev); + if (rc) + return rc; + + if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { + rc = ahci_reset_controller(host); + if (rc) + return rc; + + ahci_init_controller(host); + } + + ata_host_resume(host); + return 0; +} + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE +static int tegra_ahci_runtime_suspend(struct device *dev) +{ + struct ata_host *host; + struct tegra_ahci_host_priv *tegra_hpriv; + bool pg_ok; + unsigned long flags; + int err = 0; + + host = dev_get_drvdata(dev); + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + spin_lock_irqsave(&host->lock, flags); + + switch (tegra_hpriv->pg_state) { + case SATA_OFF: + dev_dbg(dev, "** rt-suspend: already power gated **\n"); + break; + + case SATA_ABORT_OFF: + dev_dbg(dev, "** rt-suspend: abort suspend **\n"); + pm_runtime_get_noresume(dev); + tegra_hpriv->pg_state = SATA_ON; + tegra_ahci_dequeue_qcs(tegra_hpriv); + err = -EBUSY; + break; + + case SATA_ON: + case SATA_GOING_OFF: + if (tegra_ahci_are_all_ports_idle(host)) { + /* if all ports are in idle, do power-gate */ + dev_dbg(dev, "** rt-suspend: power-down sata (%u) **\n", + tegra_hpriv->pg_state); + pg_ok = tegra_ahci_power_gate(host); + dev_dbg(dev, "** rt-suspend: done **\n"); + if (pg_ok) { + tegra_hpriv->pg_state = SATA_OFF; + } else { + dev_err(dev, "** rt-suspend: abort pg **\n"); + tegra_ahci_abort_power_gate(host); + tegra_hpriv->pg_state = SATA_ON; + err = -EBUSY; + } + } else { + dev_dbg(dev, "** rt-suspend: port not idle (%u) **\n", + tegra_hpriv->pg_state); + err = -EBUSY; + } + break; + + case SATA_GOING_ON: + default: + dev_err(dev, "** rt-suspend: bad state (%u) **\n", + tegra_hpriv->pg_state); + WARN_ON(1); + err = -EBUSY; + break; + + } + + spin_unlock_irqrestore(&host->lock, flags); + + return err; +} + +static int tegra_ahci_runtime_resume(struct device *dev) +{ + struct ata_host *host; + struct tegra_ahci_host_priv *tegra_hpriv; + unsigned long flags; + int err = 0; + + host = dev_get_drvdata(dev); + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + spin_lock_irqsave(&host->lock, flags); + + if (tegra_hpriv->pg_state == SATA_ON) { + dev_dbg(dev, "** rt-resume: already power ungated **\n"); + goto exit; + } + + if ((tegra_hpriv->pg_state == SATA_OFF) || + (tegra_hpriv->pg_state == SATA_GOING_ON)) { + dev_dbg(dev, "** rt-resume: power-up sata (%u) **\n", + tegra_hpriv->pg_state); + tegra_ahci_power_un_gate(host); + dev_dbg(dev, "** rt-resume: done **\n"); + tegra_hpriv->pg_state = SATA_ON; + + /* now qc_issue all qcs in the qc_list */ + tegra_ahci_dequeue_qcs(tegra_hpriv); + } else { + dev_err(dev, "** rt-resume: bad state (%u) **\n", + tegra_hpriv->pg_state); + WARN_ON(1); + err = -EBUSY; + } + +exit: + spin_unlock_irqrestore(&host->lock, flags); + return err; +} +#endif + +static u16 pg_save_bar5_registers[] = { + 0x018, /* T_AHCI_HBA_CCC_PORTS */ + 0x004, /* T_AHCI_HBA_GHC */ + 0x014, /* T_AHCI_HBA_CCC_CTL - OP (optional) */ + 0x01C, /* T_AHCI_HBA_EM_LOC */ + 0x020 /* T_AHCI_HBA_EM_CTL - OP */ +}; + +static u16 pg_save_bar5_port_registers[] = { + 0x100, /* T_AHCI_PORT_PXCLB */ + 0x104, /* T_AHCI_PORT_PXCLBU */ + 0x108, /* T_AHCI_PORT_PXFB */ + 0x10C, /* T_AHCI_PORT_PXFBU */ + 0x114, /* T_AHCI_PORT_PXIE */ + 0x118, /* T_AHCI_PORT_PXCMD */ + 0x12C /* T_AHCI_PORT_PXSCTL */ +}; + +/* + * pg_save_bar5_bkdr_registers: + * These registers in BAR5 are read only. + * To restore back those register values, write the saved value + * to the registers specified in pg_restore_bar5_bkdr_registers[]. + * These pg_restore_bar5_bkdr_registers[] are in SATA_CONFIG space. + */ +static u16 pg_save_bar5_bkdr_registers[] = { + /* Save and restore via bkdr writes */ + 0x000, /* T_AHCI_HBA_CAP */ + 0x00C, /* T_AHCI_HBA_PI */ + 0x024 /* T_AHCI_HBA_CAP2 */ +}; + +static u16 pg_restore_bar5_bkdr_registers[] = { + /* Save and restore via bkdr writes */ + 0x300, /* BKDR of T_AHCI_HBA_CAP */ + 0x33c, /* BKDR of T_AHCI_HBA_PI */ + 0x330 /* BKDR of T_AHCI_HBA_CAP2 */ +}; + +/* These registers are saved for each port */ +static u16 pg_save_bar5_bkdr_port_registers[] = { + 0x120, /* NV_PROJ__SATA0_CHX_AHCI_PORT_PXTFD */ + 0x124, /* NV_PROJ__SATA0_CHX_AHCI_PORT_PXSIG */ + 0x128 /* NV_PROJ__SATA0_CHX_AHCI_PORT_PXSSTS */ +}; + +static u16 pg_restore_bar5_bkdr_port_registers[] = { + /* Save and restore via bkdr writes */ + 0x790, /* BKDR of NV_PROJ__SATA0_CHX_AHCI_PORT_PXTFD */ + 0x794, /* BKDR of NV_PROJ__SATA0_CHX_AHCI_PORT_PXSIG */ + 0x798 /* BKDR of NV_PROJ__SATA0_CHX_AHCI_PORT_PXSSTS */ +}; + +static u16 pg_save_config_registers[] = { + 0x004, /* T_SATA0_CFG_1 */ + 0x00C, /* T_SATA0_CFG_3 */ + 0x024, /* T_SATA0_CFG_9 */ + 0x028, /* T_SATA0_CFG_10 */ + 0x030, /* T_SATA0_CFG_12 */ + 0x034, /* T_SATA0_CFG_13 */ + 0x038, /* T_SATA0_CFG_14 */ + 0x03C, /* T_SATA0_CFG_15 */ + 0x040, /* T_SATA0_CFG_16 */ + 0x044, /* T_SATA0_CFG_17 */ + 0x048, /* T_SATA0_CFG_18 */ + 0x0B0, /* T_SATA0_MSI_CTRL */ + 0x0B4, /* T_SATA0_MSI_ADDR1 */ + 0x0B8, /* T_SATA0_MSI_ADDR2 */ + 0x0BC, /* T_SATA0_MSI_DATA */ + 0x0C0, /* T_SATA0_MSI_QUEUE */ + 0x0EC, /* T_SATA0_MSI_MAP */ + 0x124, /* T_SATA0_CFG_PHY_POWER */ + 0x128, /* T_SATA0_CFG_PHY_POWER_1 */ + 0x12C, /* T_SATA0_CFG_PHY_1 */ + 0x174, /* T_SATA0_CFG_LINK_0 */ + 0x178, /* T_SATA0_CFG_LINK_1 */ + 0x1D0, /* MCP_SATA0_CFG_TRANS_0 */ + 0x238, /* T_SATA0_ALPM_CTRL */ + 0x30C, /* T_SATA0_AHCI_HBA_CYA_0 */ + 0x320, /* T_SATA0_AHCI_HBA_SPARE_1 */ + 0x324, /* T_SATA0_AHCI_HBA_SPARE_2 */ + 0x328, /* T_SATA0_AHCI_HBA_DYN_CLK_CLAMP */ + 0x32C, /* T_SATA0_AHCI_CFG_ERR_CTRL */ + 0x338, /* T_SATA0_AHCI_HBA_CYA_1 */ + 0x340, /* T_SATA0_AHCI_HBA_PRE_STAGING_CONTROL */ + 0x430, /* T_SATA0_CFG_FPCI_0 */ + 0x494, /* T_SATA0_CFG_ESATA_CTRL */ + 0x4A0, /* T_SATA0_CYA1 */ + 0x4B0, /* T_SATA0_CFG_GLUE */ + 0x534, /* T_SATA0_PHY_CTRL */ + 0x540, /* T_SATA0_CTRL */ + 0x550, /* T_SATA0_DBG0 */ + 0x554 /* T_SATA0_LOW_POWER_COUNT */ +}; + +static u16 pg_save_config_port_registers[] = { + /* Save and restore per port */ + /* need to have port selected */ + 0x530, /* T_SATA0_CHXCFG1 */ + 0x684, /* T_SATA0_CHX_MISC */ + 0x700, /* T_SATA0_CHXCFG3 */ + 0x704, /* T_SATA0_CHXCFG4_CHX */ + 0x690, /* T_SATA0_CHX_PHY_CTRL1_GEN1 */ + 0x694, /* T_SATA0_CHX_PHY_CTRL1_GEN2 */ + 0x698, /* T_SATA0_CHX_PHY_CTRL1_GEN3 */ + 0x69C, /* T_SATA0_CHX_PHY_CTRL_2 */ + 0x6B0, /* T_SATA0_CHX_PHY_CTRL_3 */ + 0x6B4, /* T_SATA0_CHX_PHY_CTRL_4 */ + 0x6B8, /* T_SATA0_CHX_PHY_CTRL_5 */ + 0x6BC, /* T_SATA0_CHX_PHY_CTRL_6 */ + 0x714, /* T_SATA0_PRBS_CHX - OP */ + 0x750, /* T_SATA0_CHX_LINK0 */ + 0x7F0 /* T_SATA0_CHX_GLUE */ +}; + +static u16 pg_save_ipfs_registers[] = { + 0x094, /* SATA_FPCI_BAR5_0 */ + 0x0C0, /* SATA_MSI_BAR_SZ_0 */ + 0x0C4, /* SATA_MSI_AXI_BAR_ST_0 */ + 0x0C8, /* SATA_MSI_FPCI_BAR_ST_0 */ + 0x140, /* SATA_MSI_EN_VEC0_0 */ + 0x144, /* SATA_MSI_EN_VEC1_0 */ + 0x148, /* SATA_MSI_EN_VEC2_0 */ + 0x14C, /* SATA_MSI_EN_VEC3_0 */ + 0x150, /* SATA_MSI_EN_VEC4_0 */ + 0x154, /* SATA_MSI_EN_VEC5_0 */ + 0x158, /* SATA_MSI_EN_VEC6_0 */ + 0x15C, /* SATA_MSI_EN_VEC7_0 */ + 0x180, /* SATA_CONFIGURATION_0 */ + 0x184, /* SATA_FPCI_ERROR_MASKS_0 */ + 0x188, /* SATA_INTR_MASK_0 */ + 0x1A0, /* SATA_CFG_REVID_0 */ + 0x198, /* SATA_IPFS_INTR_ENABLE_0 */ + 0x1BC, /* SATA_CLKGATE_HYSTERSIS_0 */ + 0x1DC /* SATA_SATA_MCCIF_FIFOCTRL_0 */ +}; + +static void tegra_ahci_save_regs(u32 **save_addr, + u32 reg_base, + u16 reg_array[], + u32 regs) +{ + u32 i; + u32 *dest = (u32 *)*save_addr; + u32 base = (u32)IO_ADDRESS(reg_base); + + for (i = 0; i < regs; ++i, ++dest) { + *dest = readl(base + (u32)reg_array[i]); + AHCI_DBG_PRINT("save: [0x%x]=0x%08x\n", + (reg_base+(u32)reg_array[i]), *dest); + } + *save_addr = dest; +} + +static void tegra_ahci_restore_regs(void **save_addr, + u32 reg_base, + u16 reg_array[], + u32 regs) +{ + u32 i; + u32 *src = (u32 *)*save_addr; + u32 base = (u32)IO_ADDRESS(reg_base); + + for (i = 0; i < regs; ++i, ++src) { + writel(*src, base + (u32)reg_array[i]); + AHCI_DBG_PRINT("restore: [0x%x]=0x%08x\n", + (reg_base+(u32)reg_array[i]), *src); + } + *save_addr = src; +} + +static void tegra_ahci_pg_save_registers(struct ata_host *host) +{ + struct tegra_ahci_host_priv *tegra_hpriv; + u32 *pg_save; + u32 regs; + int i; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + pg_save = tegra_hpriv->pg_save; + + /* + * Driver should save/restore the registers in the order of + * IPFS, CFG, Ext CFG, BAR5. + */ + + /* save IPFS registers */ + regs = ARRAY_SIZE(pg_save_ipfs_registers); + tegra_ahci_save_regs(&pg_save, TEGRA_SATA_BASE, + pg_save_ipfs_registers, regs); + /* after the call, pg_save should point to the next address to save */ + + /* save CONFIG registers */ + regs = ARRAY_SIZE(pg_save_config_registers); + tegra_ahci_save_regs(&pg_save, TEGRA_SATA_CONFIG_BASE, + pg_save_config_registers, regs); + + /* save CONFIG per port registers */ + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) { + scfg_writel((1 << i), T_SATA0_INDEX_OFFSET); + regs = ARRAY_SIZE(pg_save_config_port_registers); + tegra_ahci_save_regs(&pg_save, TEGRA_SATA_CONFIG_BASE, + pg_save_config_port_registers, regs); + } + scfg_writel(SATA0_NONE_SELECTED, T_SATA0_INDEX_OFFSET); + + /* save BAR5 registers */ + regs = ARRAY_SIZE(pg_save_bar5_registers); + tegra_ahci_save_regs(&pg_save, TEGRA_SATA_BAR5_BASE, + pg_save_bar5_registers, regs); + + /* save BAR5 port_registers */ + regs = ARRAY_SIZE(pg_save_bar5_port_registers); + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) + tegra_ahci_save_regs(&pg_save, TEGRA_SATA_BAR5_BASE + (0x80*i), + pg_save_bar5_port_registers, regs); + + /* save bkdr registers */ + regs = ARRAY_SIZE(pg_save_bar5_bkdr_registers); + tegra_ahci_save_regs(&pg_save, TEGRA_SATA_BAR5_BASE, + pg_save_bar5_bkdr_registers, regs); + + /* and save bkdr per_port registers */ + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) { + scfg_writel((1 << i), T_SATA0_INDEX_OFFSET); + regs = ARRAY_SIZE(pg_save_bar5_bkdr_port_registers); + tegra_ahci_save_regs(&pg_save, TEGRA_SATA_BAR5_BASE + (0x80*i), + pg_save_bar5_bkdr_port_registers, + regs); + } + scfg_writel(SATA0_NONE_SELECTED, T_SATA0_INDEX_OFFSET); +} + +static void tegra_ahci_pg_restore_registers(struct ata_host *host) +{ + struct tegra_ahci_host_priv *tegra_hpriv; + void *pg_save; + u32 regs, val; + int i; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + pg_save = tegra_hpriv->pg_save; + + /* + * Driver should restore the registers in the order of + * IPFS, CFG, Ext CFG, BAR5. + */ + + /* restore IPFS registers */ + regs = ARRAY_SIZE(pg_save_ipfs_registers); + tegra_ahci_restore_regs(&pg_save, TEGRA_SATA_BASE, + pg_save_ipfs_registers, regs); + /* after the call, pg_save should point to the next addr to restore */ + + /* restore CONFIG registers */ + regs = ARRAY_SIZE(pg_save_config_registers); + tegra_ahci_restore_regs(&pg_save, TEGRA_SATA_CONFIG_BASE, + pg_save_config_registers, regs); + + /* restore CONFIG per port registers */ + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) { + scfg_writel((1 << i), T_SATA0_INDEX_OFFSET); + regs = ARRAY_SIZE(pg_save_config_port_registers); + tegra_ahci_restore_regs(&pg_save, TEGRA_SATA_CONFIG_BASE, + pg_save_config_port_registers, + regs); + } + scfg_writel(SATA0_NONE_SELECTED, T_SATA0_INDEX_OFFSET); + + /* restore BAR5 registers */ + regs = ARRAY_SIZE(pg_save_bar5_registers); + tegra_ahci_restore_regs(&pg_save, TEGRA_SATA_BAR5_BASE, + pg_save_bar5_registers, regs); + + /* restore BAR5 port_registers */ + regs = ARRAY_SIZE(pg_save_bar5_port_registers); + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) + tegra_ahci_restore_regs(&pg_save, TEGRA_SATA_BAR5_BASE+(0x80*i), + pg_save_bar5_port_registers, regs); + + /* restore bkdr registers */ + regs = ARRAY_SIZE(pg_restore_bar5_bkdr_registers); + tegra_ahci_restore_regs(&pg_save, TEGRA_SATA_CONFIG_BASE, + pg_restore_bar5_bkdr_registers, regs); + + /* and restore BAR5 bkdr per_port registers */ + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) { + scfg_writel((1 << i), T_SATA0_INDEX_OFFSET); + regs = ARRAY_SIZE(pg_restore_bar5_bkdr_port_registers); + tegra_ahci_restore_regs(&pg_save, TEGRA_SATA_CONFIG_BASE, + pg_restore_bar5_bkdr_port_registers, + regs); + } + scfg_writel(SATA0_NONE_SELECTED, T_SATA0_INDEX_OFFSET); + + /* program class code and programming interface for AHCI */ + val = scfg_readl(TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE); + val |= TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE_EN; + scfg_writel(val, TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE); + scfg_writel(TEGRA_PRIVATE_AHCI_CC_BKDR_PGM, TEGRA_PRIVATE_AHCI_CC_BKDR); + val &= ~TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE_EN; + scfg_writel(val, TEGRA_PRIVATE_AHCI_CC_BKDR_OVERRIDE); +} + +static u32 tegra_ahci_port_error(struct ata_port *ap) +{ + void __iomem *port_mmio = ahci_port_base(ap); + u32 err_status; + + err_status = readl(port_mmio + PORT_IRQ_STAT); + /* excludes PhyRdy and Connect Change status */ + err_status &= (PORT_IRQ_ERROR & (~(PORT_IRQ_PHYRDY|PORT_IRQ_CONNECT))); + return err_status; +} + +static bool tegra_ahci_check_errors(struct ata_host *host) +{ int i; + struct ata_port *ap; + u32 err; + + for (i = 0; i < host->n_ports; i++) { + ap = host->ports[i]; + err = tegra_ahci_port_error(ap); + if (err) { + dev_err(host->dev, + "pg-chk-err = 0x%08x on port %d\n", err, i); + return true; + } + } + return false; +} + +static void tegra_ahci_abort_power_gate(struct ata_host *host) +{ + u32 val; + + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~PG_INFO_MASK; + val |= PG_INFO_OFF; + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); +} + +static bool tegra_ahci_power_gate(struct ata_host *host) +{ + u32 val; + u32 dat; + struct tegra_ahci_host_priv *tegra_hpriv; + int status; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~PG_INFO_MASK; + val |= PG_INFO_ON; + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + tegra_ahci_pg_save_registers(host); + + /* + * Read SATA_AUX_MISC_CNTL_1_0 register L0_RX_IDLE_T_SAX field and + * write that value into same register L0_RX_IDLE_T_NPG field. + * And write 1 to L0_RX_IDLE_T_MUX field. + */ + val = misc_readl(SATA_AUX_MISC_CNTL_1_REG); + dat = val; + dat &= L0_RX_IDLE_T_SAX_MASK; + dat >>= L0_RX_IDLE_T_SAX_SHIFT; + dat <<= L0_RX_IDLE_T_NPG_SHIFT; + val &= ~L0_RX_IDLE_T_NPG_MASK; + val |= dat; + val &= ~L0_RX_IDLE_T_MUX_MASK; + val |= L0_RX_IDLE_T_MUX_FROM_APB_MISC; + misc_writel(val, SATA_AUX_MISC_CNTL_1_REG); + + /* abort PG if there are errors occurred */ + if (tegra_ahci_check_errors(host)) { + dev_err(host->dev, "** pg: errors; abort power gating **\n"); + return false; + } + /* make sure all ports have no outstanding commands and are idle. */ + if (!tegra_ahci_are_all_ports_idle(host)) { + dev_err(host->dev, "** pg: cmds; abort power gating **\n"); + return false; + } + + /* + * Hw wake up is not needed: + * Driver/RM shall place the SATA PHY and SATA PADPLL in IDDQ. + * SATA_PADPLL_RESET_SWCTL =1 + * SATA_PADPLL_RESET_OVERRIDE_VALUE=1 + * SATA_PADPHY_IDDQ_SWCTL=1 + * SATA_PADPHY_IDDQ_OVERRIDE_VALUE=1 + */ + val = clk_readl(CLK_RST_SATA_PLL_CFG0_REG); + val &= ~(PADPLL_RESET_SWCTL_MASK | PADPLL_RESET_OVERRIDE_VALUE_MASK); + val |= (PADPLL_RESET_SWCTL_ON | PADPLL_RESET_OVERRIDE_VALUE_ON); + clk_writel(val, CLK_RST_SATA_PLL_CFG0_REG); + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~(PADPHY_IDDQ_OVERRIDE_VALUE_MASK | PADPHY_IDDQ_SWCTL_MASK); + val |= (PADPHY_IDDQ_SWCTL_ON | PADPHY_IDDQ_OVERRIDE_VALUE_ON); + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + /* Wait for time specified in SATA_LANE_IDDQ2_PADPLL_IDDQ */ + val = clk_readl(CLK_RST_SATA_PLL_CFG1_REG); + dat = (val & IDDQ2LANE_IDDQ_DLY_MASK) >> IDDQ2LANE_IDDQ_DLY_SHIFT; + udelay(dat); + + /* SATA_PADPLL_IDDQ_SWCTL=1 & SATA_PADPLL_IDDQ_OVERRIDE_VALUE=1 */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~(PADPLL_IDDQ_OVERRIDE_VALUE_MASK | PADPLL_IDDQ_SWCTL_MASK); + val |= (PADPLL_IDDQ_SWCTL_ON | PADPLL_IDDQ_OVERRIDE_VALUE_ON); + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + /* power off the sata */ + status = tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA); + if (status) + dev_err(host->dev, "** failed to turn-off SATA (0x%x) **\n", + status); + + return true; +} + +static bool tegra_ahci_power_un_gate(struct ata_host *host) +{ + u32 val; + u32 dat; + u32 timeout; + struct tegra_ahci_host_priv *tegra_hpriv; + int status; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + /* get sata phy and pll out of iddq: */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~PADPLL_IDDQ_OVERRIDE_VALUE_MASK; + val |= PADPLL_IDDQ_OVERRIDE_VALUE_OFF; + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + /* wait for delay of IDDQ2LAND_SLUMBER_DLY */ + val = clk_readl(CLK_RST_SATA_PLL_CFG1_REG); + dat = (val & IDDQ2LANE_SLUMBER_DLY_MASK) >> IDDQ2LANE_SLUMBER_DLY_SHIFT; + udelay(dat); + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~PADPHY_IDDQ_OVERRIDE_VALUE_MASK; + val |= PADPHY_IDDQ_OVERRIDE_VALUE_OFF; + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + status = tegra_unpowergate_partition_with_clk_on(TEGRA_POWERGATE_SATA); + if (status) + dev_err(host->dev, "** failed to turn-on SATA (0x%x) **\n", + status); + + /* deasset PADPLL and wait until it locks. */ + val = clk_readl(CLK_RST_SATA_PLL_CFG0_REG); + val &= ~PADPLL_RESET_OVERRIDE_VALUE_MASK; + val |= PADPLL_RESET_OVERRIDE_VALUE_OFF; + clk_writel(val, CLK_RST_SATA_PLL_CFG0_REG); + + /* + * Wait for SATA_AUX_PAD_PLL_CNTL_1_0_LOCKDET to turn 1 with a timeout + * of 15 us. + */ + timeout = 15; + while (timeout--) { + udelay(1); + val = misc_readl(SATA_AUX_PAD_PLL_CNTL_1_REG); + if (val & LOCKDET_FIELD) + break; + } + if (timeout == 0) + pr_err("%s: SATA_PAD_PLL is not locked in 15us.\n", __func__); + + /* restore registers */ + tegra_ahci_pg_restore_registers(host); + + /* + * During the restoration of the registers, the driver would now need to + * restore the register T_SATA0_CFG_POWER_GATE_SSTS_RESTORED after the + * ssts_det, ssts_spd are restored. This register is used to tell the + * controller whether a drive existed earlier or not and move the PHY + * state machines into either HR_slumber or not. + */ + val = scfg_readl(T_SATA0_CFG_POWER_GATE); + val &= ~POWER_GATE_SSTS_RESTORED_MASK; + val |= POWER_GATE_SSTS_RESTORED_YES; + scfg_writel(val, T_SATA0_CFG_POWER_GATE); + + /* + * Driver needs to switch the rx_idle_t driven source back to from + * Sata controller after SAX is power-ungated. + */ + val = misc_readl(SATA_AUX_MISC_CNTL_1_REG); + val &= ~L0_RX_IDLE_T_MUX_MASK; + val |= L0_RX_IDLE_T_MUX_FROM_SATA; + misc_writel(val, SATA_AUX_MISC_CNTL_1_REG); + + /* + * Driver can start to use main SATA interrupt instead of the + * rx_stat_t interrupt. + */ + val = pictlr_readl(PRI_ICTLR_CPU_IER_SET_0_OFFSET); + val |= CPU_IER_SATA_CTL; + pictlr_writel(val, PRI_ICTLR_CPU_IER_SET_0_OFFSET); + + /* Set the bits in the CAR to allow HW based low power sequencing. */ + val = clk_readl(CLK_RST_SATA_PLL_CFG0_REG); + val &= ~PADPLL_RESET_SWCTL_MASK; + val |= PADPLL_RESET_SWCTL_OFF; + clk_writel(val, CLK_RST_SATA_PLL_CFG0_REG); + + /* + * power un-gating process is complete by clearing + * APBDEV_PMC_SATA_PWRGT_0.Pmc2sata_pg_info = 0 + */ + val = pmc_readl(APB_PMC_SATA_PWRGT_0_REG); + val &= ~PG_INFO_MASK; + val |= PG_INFO_OFF; + pmc_writel(val, APB_PMC_SATA_PWRGT_0_REG); + + return true; +} + +static enum port_idle_status tegra_ahci_is_port_idle(struct ata_port *ap) +{ + void __iomem *port_mmio = ahci_port_base(ap); + + if (readl(port_mmio + PORT_CMD_ISSUE) || + readl(port_mmio + PORT_SCR_ACT)) + return PORT_IS_NOT_IDLE; + return PORT_IS_IDLE; +} + +static enum port_idle_status tegra_ahci_is_port_slumber(struct ata_port *ap) +{ + void __iomem *port_mmio = ahci_port_base(ap); + u32 sstat; + + if (tegra_ahci_is_port_idle(ap) == PORT_IS_NOT_IDLE) + return PORT_IS_NOT_IDLE; + + /* return 1 if PORT_SCR_STAT is in IPM_SLUMBER_STATE */ + sstat = readl(port_mmio + PORT_SCR_STAT); + if ((sstat & SSTAT_IPM_STATE_MASK) == SSTAT_IPM_SLUMBER_STATE) + return PORT_IS_SLUMBER; + return PORT_IS_IDLE_NOT_SLUMBER; +} + +/* check if all supported ports are idle (no outstanding commands) */ +static bool tegra_ahci_are_all_ports_idle(struct ata_host *host) +{ int i; + struct ata_port *ap; + + for (i = 0; i < host->n_ports; i++) { + ap = host->ports[i]; + if (ap && (tegra_ahci_is_port_idle(ap) == PORT_IS_NOT_IDLE)) + return false; + } + return true; +} + +/* check if all supported ports are in slumber */ +static bool tegra_ahci_are_all_ports_slumber(struct ata_host *host) +{ int i; + struct ata_port *ap; + + for (i = 0; i < host->n_ports; i++) { + ap = host->ports[i]; + if (ap && (tegra_ahci_is_port_slumber(ap) != PORT_IS_SLUMBER)) + return false; + } + return true; +} + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE +static void tegra_ahci_to_add_idle_timer(struct ata_host *host) +{ + struct tegra_ahci_host_priv *tegra_hpriv; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + /* note: the routine is called from interrupt context */ + spin_lock(&host->lock); + /* start idle-timer if all ports have no outstanding commands */ + if (tegra_ahci_are_all_ports_idle(host)) { + /* adjust tegra_ahci_idle_time to minimum if it is too small */ + tegra_ahci_idle_time = max((u32)TEGRA_AHCI_MIN_IDLE_TIME, + tegra_ahci_idle_time); + tegra_hpriv->idle_timer.expires = + ata_deadline(jiffies, tegra_ahci_idle_time); + mod_timer(&tegra_hpriv->idle_timer, + tegra_hpriv->idle_timer.expires); + } + spin_unlock(&host->lock); +} + +static void tegra_ahci_idle_timer(unsigned long arg) +{ + struct ata_host *host = (void *)arg; + struct tegra_ahci_host_priv *tegra_hpriv; + unsigned long flags; + + tegra_hpriv = (struct tegra_ahci_host_priv *)host->private_data; + + spin_lock_irqsave(&host->lock, flags); + if (tegra_hpriv->pg_state == SATA_ON) + tegra_hpriv->pg_state = SATA_GOING_OFF; + else { + dev_err(host->dev, "idle_timer: bad state (%u)\n", + tegra_hpriv->pg_state); + WARN_ON(1); + spin_unlock_irqrestore(&host->lock, flags); + return; + } + spin_unlock_irqrestore(&host->lock, flags); + + pm_runtime_put(tegra_hpriv->dev); +} + +static int tegra_ahci_queue_one_qc(struct tegra_ahci_host_priv *tegra_hpriv, + struct ata_queued_cmd *qc) +{ + struct tegra_qc_list *qc_list; + + qc_list = kmalloc(sizeof(struct tegra_qc_list), GFP_ATOMIC); + if (!qc_list) { + dev_err(tegra_hpriv->dev, "failed to alloc qc_list\n"); + return AC_ERR_SYSTEM; + } + qc_list->qc = qc; + list_add_tail(&(qc_list->list), &(tegra_hpriv->qc_list)); + dev_dbg(tegra_hpriv->dev, "queuing qc=%x\n", (unsigned int)qc); + return 0; +} + +static void tegra_ahci_dequeue_qcs(struct tegra_ahci_host_priv *tegra_hpriv) +{ + struct list_head *list, *next; + struct tegra_qc_list *qc_list; + struct ata_queued_cmd *qc; + + /* now qc_issue all qcs in the qc_list */ + list_for_each_safe(list, next, &tegra_hpriv->qc_list) { + qc_list = list_entry(list, struct tegra_qc_list, list); + qc = qc_list->qc; + dev_dbg(tegra_hpriv->dev, "dequeue qc=%x\n", (unsigned int)qc); + ahci_ops.qc_issue(qc); + list_del(list); + kfree(qc_list); + } +} + +static unsigned int tegra_ahci_qc_issue(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_host *host = ap->host; + struct tegra_ahci_host_priv *tegra_hpriv = host->private_data; + int rc; + + /* stop the idle timer */ + if (timer_pending(&tegra_hpriv->idle_timer)) + del_timer_sync(&tegra_hpriv->idle_timer); + + /* note: host->lock is locked */ + switch (tegra_hpriv->pg_state) { + case SATA_ON: + /* normal case, issue the qc */ + return ahci_ops.qc_issue(qc); + case SATA_GOING_OFF: + case SATA_ABORT_OFF: + /* SATA is going OFF, let's abort the suspend */ + dev_dbg(host->dev, "** qc_issue: going OFF **\n"); + tegra_hpriv->pg_state = SATA_ABORT_OFF; + return tegra_ahci_queue_one_qc(tegra_hpriv, qc); + case SATA_OFF: + dev_dbg(host->dev, "** qc_issue: request power-up sata **\n"); + rc = pm_runtime_get(tegra_hpriv->dev); + /* rc == 0 means the request has been queued successfully */ + if (rc) { + dev_err(host->dev, "** qc_issue: rt_get()=%d **\n", + rc); + WARN_ON(1); + return AC_ERR_SYSTEM; + } + tegra_hpriv->pg_state = SATA_GOING_ON; + /* continue with the following code to queue the qc */ + case SATA_GOING_ON: + return tegra_ahci_queue_one_qc(tegra_hpriv, qc); + default: + dev_err(host->dev, "** qc_issue: bad state (%u) **\n", + tegra_hpriv->pg_state); + WARN_ON(1); + return AC_ERR_SYSTEM; + } +} + +static int tegra_ahci_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + struct ata_port *ap = link->ap; + struct ata_host *host = ap->host; + struct tegra_ahci_host_priv *tegra_hpriv = host->private_data; + int rc; + + if (tegra_hpriv->pg_state == SATA_OFF) { + dev_dbg(host->dev, "** hreset: request power-up sata **\n"); + rc = pm_runtime_get_sync(tegra_hpriv->dev); + /* rc == 0 means the request has been run successfully */ + if (rc) { + dev_err(host->dev, "** hreset: rt_get()=%d **\n", rc); + WARN_ON(1); + return AC_ERR_SYSTEM; + } + tegra_hpriv->pg_state = SATA_ON; + } + + return ahci_ops.hardreset(link, class, deadline); +} + +static irqreturn_t tegra_ahci_interrupt(int irq, void *dev_instance) +{ + irqreturn_t irq_retval; + + irq_retval = ahci_interrupt(irq, dev_instance); + if (irq_retval == IRQ_NONE) + return IRQ_NONE; + +#ifdef CONFIG_PM + tegra_ahci_to_add_idle_timer((struct ata_host *)dev_instance); +#endif + + return irq_retval; +} +#endif +#endif + +static int __devexit tegra_ahci_remove_one(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ahci_host_priv *hpriv; + + BUG_ON(host == NULL); + BUG_ON(host->iomap[AHCI_PCI_BAR] == NULL); + hpriv = host->private_data; + + tegra_ahci_controller_remove(pdev); + + devm_iounmap(&pdev->dev, host->iomap[AHCI_PCI_BAR]); + devres_free(host); + +#ifdef CONFIG_PM + /* Free PG save/restore area */ + devm_kfree(&pdev->dev, ((struct tegra_ahci_host_priv *)hpriv)->pg_save); + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE + pm_runtime_disable(&pdev->dev); +#endif +#endif + + devm_kfree(&pdev->dev, hpriv); + + return 0; +} + +static int __devinit tegra_ahci_init_one(struct platform_device *pdev) +{ + struct ata_port_info pi = ahci_port_info; + const struct ata_port_info *ppi[] = { &pi, NULL }; + struct device *dev = &pdev->dev; + struct ahci_host_priv *hpriv = NULL; + struct tegra_ahci_host_priv *tegra_hpriv; + struct ata_host *host = NULL; + int n_ports, i, rc; + struct resource *res, *irq_res; + void __iomem *mmio; + u32 save_size; + irq_handler_t irq_handler = ahci_interrupt; + + VPRINTK("ENTER\n"); + + WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS); + + ata_print_version_once(&pdev->dev, DRV_VERSION); + + /* Simple resource validation */ + if (pdev->num_resources != 3) { + dev_err(dev, "invalid number of resources\n"); + dev_err(dev, "not enough SATA resources\n"); + return -EINVAL; + } + + /* acquire bar resources */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) + return -EINVAL; + + /* acquire IRQ resource */ + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (irq_res == NULL) + return -EINVAL; + if (irq_res->start <= 0) + return -EINVAL; + + /* allocate sizeof tegra_ahci_host_priv, which contains extra fields */ + hpriv = devm_kzalloc(dev, sizeof(struct tegra_ahci_host_priv), + GFP_KERNEL); + if (!hpriv) { + rc = -ENOMEM; + goto fail; + } + hpriv->flags |= (unsigned long)pi.private_data; + tegra_hpriv = (struct tegra_ahci_host_priv *)hpriv; + g_tegra_hpriv = tegra_hpriv; + + /* Call tegra init routine */ + rc = tegra_ahci_controller_init(tegra_hpriv); + if (rc != 0) { + dev_err(dev, "TEGRA SATA init failed\n"); + goto fail; + } + + /* + * We reserve a table of 6 BARs in tegra_hpriv to store BARs. + * Save the mapped AHCI_PCI_BAR address to the table. + */ + mmio = devm_ioremap(dev, res->start, (res->end-res->start+1)); + tegra_hpriv->bars_table[AHCI_PCI_BAR] = mmio; + hpriv->mmio = mmio; + + /* save initial config */ + tegra_ahci_save_initial_config(pdev, hpriv); + dev_dbg(dev, "past save init config\n"); + + /* prepare host */ + if (hpriv->cap & HOST_CAP_NCQ) { + pi.flags |= ATA_FLAG_NCQ; + pi.flags |= ATA_FLAG_FPDMA_AA; + } + + /* + * CAP.NP sometimes indicate the index of the last enabled + * port, at other times, that of the last possible port, so + * determining the maximum port number requires looking at + * both CAP.NP and port_map. + */ + n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); + host = ata_host_alloc_pinfo(dev, ppi, n_ports); + if (!host) { + rc = -ENOMEM; + goto fail; + } + host->private_data = hpriv; + tegra_hpriv->host = host; + tegra_hpriv->dev = dev; + host->iomap = tegra_hpriv->bars_table; + + if (!(hpriv->cap & HOST_CAP_SSS)) + host->flags |= ATA_HOST_PARALLEL_SCAN; + else + printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + /* set initial link pm policy */ + ap->target_lpm_policy = ATA_LPM_UNKNOWN; + + /* disabled/not-implemented port */ + if (!(hpriv->port_map & (1 << i))) + ap->ops = &ata_dummy_port_ops; + else + ap->target_lpm_policy = ATA_LPM_MIN_POWER; + } + + rc = ahci_reset_controller(host); + if (rc) { + dev_err(dev, "Reset controller failed! (rc=%d)\n", rc); + goto fail; + } + + ahci_init_controller(host); + ahci_print_info(host, "TEGRA-SATA"); + dev_dbg(dev, "controller init okay\n"); + +#ifdef CONFIG_PM + /* Setup PG save/restore area: */ + + /* calculate the size */ + save_size = ARRAY_SIZE(pg_save_ipfs_registers) + + ARRAY_SIZE(pg_save_config_registers) + + ARRAY_SIZE(pg_save_bar5_registers) + + ARRAY_SIZE(pg_save_bar5_bkdr_registers); + + /* and add save port_registers for all the ports */ + save_size += TEGRA_AHCI_NUM_PORTS * + (ARRAY_SIZE(pg_save_config_port_registers) + + ARRAY_SIZE(pg_save_bar5_port_registers) + + ARRAY_SIZE(pg_save_bar5_bkdr_port_registers)); + + /* + * save_size is number of registers times number of bytes per + * register to get total save size. + */ + save_size *= sizeof(u32); + tegra_hpriv->pg_save = devm_kzalloc(dev, save_size, GFP_KERNEL); + if (!tegra_hpriv->pg_save) { + rc = -ENOMEM; + goto fail; + } + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE + pm_runtime_set_active(dev); + pm_suspend_ignore_children(dev, true); + pm_runtime_enable(dev); + + tegra_hpriv->pg_state = SATA_ON; + + /* setup sata idle timer */ + init_timer_deferrable(&tegra_hpriv->idle_timer); + tegra_hpriv->idle_timer.function = tegra_ahci_idle_timer; + tegra_hpriv->idle_timer.data = (unsigned long)host; + + INIT_LIST_HEAD(&tegra_hpriv->qc_list); + + /* use our own irq handler */ + irq_handler = tegra_ahci_interrupt; +#endif + +#endif + + rc = ata_host_activate(host, irq_res->start, irq_handler, 0, &ahci_sht); + if (rc == 0) + return 0; + + /* Free PG save/restore area */ + devm_kfree(dev, tegra_hpriv->pg_save); + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE + pm_runtime_put(dev); + pm_runtime_enable(dev); +#endif + +fail: + if (host) { + if (host->iomap[AHCI_PCI_BAR]) + devm_iounmap(dev, host->iomap[AHCI_PCI_BAR]); + devres_free(host); + } + if (hpriv) + devm_kfree(dev, hpriv); + + return rc; +} + +static int __init ahci_init(void) +{ + return platform_driver_register(&tegra_platform_ahci_driver); +} + +static void __exit ahci_exit(void) +{ + platform_driver_unregister(&tegra_platform_ahci_driver); +} + + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static void dbg_ahci_dump_regs(struct seq_file *s, u32 *ptr, u32 base, u32 regs) +{ +#define REGS_PER_LINE 4 + + u32 i, j; + u32 lines = regs / REGS_PER_LINE; + + for (i = 0; i < lines; i++) { + seq_printf(s, "0x%08x: ", base+(i*16)); + for (j = 0; j < REGS_PER_LINE; ++j) { + seq_printf(s, "0x%08x ", readl(ptr)); + ++ptr; + } + seq_printf(s, "\n"); + } +#undef REGS_PER_LINE +} + +static int dbg_ahci_dump_show(struct seq_file *s, void *unused) +{ + u32 base; + u32 *ptr; + u32 i; + + base = TEGRA_SATA_CONFIG_BASE; + ptr = (u32 *)IO_TO_VIRT(base); + seq_printf(s, "SATA CONFIG Registers:\n"); + seq_printf(s, "----------------------\n"); + dbg_ahci_dump_regs(s, ptr, base, 0x200); + + base = TEGRA_SATA_BAR5_BASE; + ptr = (u32 *)IO_TO_VIRT(base); + seq_printf(s, "\nAHCI HBA Registers:\n"); + seq_printf(s, "-------------------\n"); + dbg_ahci_dump_regs(s, ptr, base, 64); + + for (i = 0; i < TEGRA_AHCI_NUM_PORTS; ++i) { + base = TEGRA_SATA_BAR5_BASE + 0x100 + (0x80*i); + ptr = (u32 *)IO_TO_VIRT(base); + seq_printf(s, "\nPort %u Registers:\n", i); + seq_printf(s, "---------------\n"); + dbg_ahci_dump_regs(s, ptr, base, 16); + } + +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE + /* adjust tegra_ahci_idle_time to minimum if it is too small */ + tegra_ahci_idle_time = max((u32)TEGRA_AHCI_MIN_IDLE_TIME, + tegra_ahci_idle_time); + seq_printf(s, "\nIdle Timeout = %u milli-seconds.\n", + tegra_ahci_idle_time); +#endif + + if (tegra_powergate_is_powered(TEGRA_POWERGATE_SATA)) + seq_printf(s, "\n=== SATA controller is powered on ===\n\n"); + else + seq_printf(s, "\n=== SATA controller is powered off ===\n\n"); + + return 0; +} + +static int dbg_ahci_dump_open(struct inode *inode, struct file *file) +{ + return single_open(file, dbg_ahci_dump_show, &inode->i_private); +} + +static const struct file_operations debug_fops = { + .open = dbg_ahci_dump_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init tegra_ahci_dump_debuginit(void) +{ + (void) debugfs_create_file("tegra_ahci", S_IRUGO, + NULL, NULL, &debug_fops); +#ifdef CONFIG_TEGRA_SATA_IDLE_POWERGATE + (void) debugfs_create_u32("tegra_ahci_idle_ms", S_IRWXUGO, + NULL, &tegra_ahci_idle_time); +#endif + return 0; +} +late_initcall(tegra_ahci_dump_debuginit); +#endif + +MODULE_AUTHOR("NVIDIA"); +MODULE_DESCRIPTION("Tegra AHCI SATA low-level driver"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(DRV_VERSION); + +module_init(ahci_init); +module_exit(ahci_exit); diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 96916bed997f..1358dc70b0e4 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -331,12 +331,19 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev) { u32 val; int tx_fifo_avail; - u8 *buf = i2c_dev->msg_buf; - size_t buf_remaining = i2c_dev->msg_buf_remaining; + u8 *buf; + size_t buf_remaining; int words_to_transfer; unsigned long flags; spin_lock_irqsave(&i2c_dev->fifo_lock, flags); + if (!i2c_dev->msg_buf_remaining) { + spin_unlock_irqrestore(&i2c_dev->fifo_lock, flags); + return 0; + } + + buf = i2c_dev->msg_buf; + buf_remaining = i2c_dev->msg_buf_remaining; val = i2c_readl(i2c_dev, I2C_FIFO_STATUS); tx_fifo_avail = (val & I2C_FIFO_STATUS_TX_MASK) >> @@ -375,7 +382,12 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev) * boundary and fault. */ if (tx_fifo_avail > 0 && buf_remaining > 0) { - BUG_ON(buf_remaining > 3); + if (buf_remaining > 3) { + dev_err(i2c_dev->dev, + "Remaining buffer more than 3 %d\n", + buf_remaining); + BUG(); + } memcpy(&val, buf, buf_remaining); /* Again update before writing to FIFO to make sure isr sees. */ diff --git a/drivers/media/video/tegra/Kconfig b/drivers/media/video/tegra/Kconfig index f5aea996e2d6..5099fe12c3e2 100644 --- a/drivers/media/video/tegra/Kconfig +++ b/drivers/media/video/tegra/Kconfig @@ -95,3 +95,10 @@ config VIDEO_AD5820 ---help--- This is a driver for the AD5820 focuser for use with the tegra isp. + +config VIDEO_AD5816 + tristate "AD5816 focuser support" + depends on I2C && ARCH_TEGRA + ---help--- + This is a driver for the AD5816 focuser + for use with the tegra isp. diff --git a/drivers/media/video/tegra/Makefile b/drivers/media/video/tegra/Makefile index 08b81e261611..3c1a0ce4638e 100644 --- a/drivers/media/video/tegra/Makefile +++ b/drivers/media/video/tegra/Makefile @@ -18,4 +18,5 @@ obj-$(CONFIG_TORCH_SSL3250A) += ssl3250a.o obj-$(CONFIG_TORCH_TPS61050) += tps61050.o obj-$(CONFIG_VIDEO_SH532U) += sh532u.o obj-$(CONFIG_VIDEO_AD5820) += ad5820.o +obj-$(CONFIG_VIDEO_AD5816) += ad5816.o diff --git a/drivers/media/video/tegra/ad5816.c b/drivers/media/video/tegra/ad5816.c new file mode 100644 index 000000000000..d95368f43cf6 --- /dev/null +++ b/drivers/media/video/tegra/ad5816.c @@ -0,0 +1,1204 @@ +/* Copyright (C) 2011-2012 NVIDIA Corporation. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ +/* This is a NVC kernel driver for a focuser device called + * ad5816. + */ +/* Implementation + * -------------- + * The board level details about the device need to be provided in the board + * file with the <device>_platform_data structure. + * Standard among NVC kernel drivers in this structure is: + * .cfg = Use the NVC_CFG_ defines that are in nvc.h. + * Descriptions of the configuration options are with the defines. + * This value is typically 0. + * .num = The number of the instance of the device. This should start at 1 and + * and increment for each device on the board. This number will be + * appended to the MISC driver name, Example: /dev/focuser.1 + * If not used or 0, then nothing is appended to the name. + * .sync = If there is a need to synchronize two devices, then this value is + * the number of the device instance (.num above) this device is to + * sync to. For example: + * Device 1 platform entries = + * .num = 1, + * .sync = 2, + * Device 2 platfrom entries = + * .num = 2, + * .sync = 1, + * The above example sync's device 1 and 2. + * To disable sync, set .sync = 0. Note that the .num = 0 device is not + * allowed to be synced to. + * This is typically used for stereo applications. + * .dev_name = The MISC driver name the device registers as. If not used, + * then the part number of the device is used for the driver name. + * If using the NVC user driver then use the name found in this + * driver under _default_pdata. + * .gpio_count = The ARRAY_SIZE of the nvc_gpio_pdata table. + * .gpio = A pointer to the nvc_gpio_pdata structure's platform GPIO data. + * The GPIO mechanism works by cross referencing the .gpio_type key + * among the nvc_gpio_pdata GPIO data and the driver's nvc_gpio_init + * GPIO data to build a GPIO table the driver can use. The GPIO's + * defined in the device header file's _gpio_type enum are the + * gpio_type keys for the nvc_gpio_pdata and nvc_gpio_init structures. + * These need to be present in the board file's nvc_gpio_pdata + * structure for the GPIO's that are used. + * The driver's GPIO logic uses assert/deassert throughout until the + * low level _gpio_wr/rd calls where the .assert_high is used to + * convert the value to the correct signal level. + * See the GPIO notes in nvc.h for additional information. + * + * The following is specific to NVC kernel focus drivers: + * .nvc = Pointer to the nvc_focus_nvc structure. This structure needs to + * be defined and populated if overriding the driver defaults. + * .cap = Pointer to the nvc_focus_cap structure. This structure needs to + * be defined and populated if overriding the driver defaults. + * + * The following is specific to this NVC kernel focus driver: + * .info = Pointer to the ad5816_pdata_info structure. This structure does + * not need to be defined and populated unless overriding ROM data. + * + * Power Requirements: + * The device's header file defines the voltage regulators needed with the + * enumeration <device>_vreg. The order these are enumerated is the order + * the regulators will be enabled when powering on the device. When the + * device is powered off the regulators are disabled in descending order. + * The <device>_vregs table in this driver uses the nvc_regulator_init + * structure to define the regulator ID strings that go with the regulators + * defined with <device>_vreg. These regulator ID strings (or supply names) + * will be used in the regulator_get function in the _vreg_init function. + * The board power file and <device>_vregs regulator ID strings must match. + */ + +#include <linux/fs.h> +#include <linux/i2c.h> +#include <linux/miscdevice.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/uaccess.h> +#include <linux/list.h> +#include <linux/regulator/consumer.h> +#include <linux/gpio.h> +#include <media/ad5816.h> + +#define AD5816_ID 0x04 +#define AD5816_FOCAL_LENGTH (4.570f) +#define AD5816_FNUMBER (2.8f) +#define AD5816_ACTUATOR_RANGE 680 +#define AD5816_SETTLETIME 110 +#define AD5816_FOCUS_MACRO 810 +#define AD5816_FOCUS_INFINITY 50 /* Exact value needs to be decided */ +#define AD5816_POS_LOW_DEFAULT 220 +#define AD5816_POS_HIGH_DEFAULT 900 +/* Need to decide exact value of VCM_THRESHOLD and its use */ +/* define AD5816_VCM_THRESHOLD 20 */ + +static u8 ad5816_ids[] = { + 0x04, +}; + +static struct nvc_gpio_init ad5816_gpios[] = { + { AD5816_GPIO_RESET, GPIOF_OUT_INIT_LOW, "reset", false, true, }, + { AD5816_GPIO_I2CMUX, 0, "i2c_mux", 0, false}, + { AD5816_GPIO_GP1, 0, "gp1", 0, false}, + { AD5816_GPIO_GP2, 0, "gp2", 0, false}, + { AD5816_GPIO_GP3, 0, "gp3", 0, false}, +}; + +static struct nvc_regulator_init ad5816_vregs[] = { + { AD5816_VREG_VDD, "vdd"}, + { AD5816_VREG_VDD_AF, "vdd_af"}, + { AD5816_VREG_VDD_I2C, "vdd_i2c"}, +}; + +struct ad5816_info { + atomic_t in_use; + struct i2c_client *i2c_client; + struct ad5816_platform_data *pdata; + struct miscdevice miscdev; + struct list_head list; + struct nvc_gpio gpio[ARRAY_SIZE(ad5816_gpios)]; + struct nvc_regulator vreg[ARRAY_SIZE(ad5816_vregs)]; + int pwr_api; + int pwr_dev; + int id_minor; + u32 pos; + u8 s_mode; + bool reset_flag; + struct ad5816_info *s_info; + struct nvc_focus_nvc nvc; + struct nvc_focus_cap cap; + struct ad5816_pdata_info config; +}; + +/** + * The following are default values + */ + +static struct ad5816_pdata_info ad5816_default_info = { + .pos_low = AD5816_POS_LOW_DEFAULT, + .pos_high = AD5816_POS_HIGH_DEFAULT, +}; + +static struct nvc_focus_cap ad5816_default_cap = { + .version = NVC_FOCUS_CAP_VER2, + .actuator_range = AD5816_ACTUATOR_RANGE, + .settle_time = AD5816_SETTLETIME, + .focus_macro = AD5816_FOCUS_MACRO, + .focus_infinity = AD5816_FOCUS_INFINITY, +}; + +static struct nvc_focus_nvc ad5816_default_nvc = { + .focal_length = AD5816_FOCAL_LENGTH, + .fnumber = AD5816_FNUMBER, +}; + +static struct ad5816_platform_data ad5816_default_pdata = { + .cfg = 0, + .num = 0, + .sync = 0, + .dev_name = "focuser", +}; +static LIST_HEAD(ad5816_info_list); +static DEFINE_SPINLOCK(ad5816_spinlock); + +static int ad5816_i2c_rd8(struct ad5816_info *info, u8 addr, u8 reg, u8 *val) +{ + struct i2c_msg msg[2]; + u8 buf[2]; + buf[0] = reg; + if (addr) { + msg[0].addr = addr; + msg[1].addr = addr; + } else { + msg[0].addr = info->i2c_client->addr; + msg[1].addr = info->i2c_client->addr; + } + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = &buf[0]; + msg[1].flags = I2C_M_RD; + msg[1].len = 1; + msg[1].buf = &buf[1]; + *val = 0; + if (i2c_transfer(info->i2c_client->adapter, msg, 2) != 2) + return -EIO; + *val = buf[1]; + return 0; +} + +static int ad5816_i2c_wr8(struct ad5816_info *info, u8 reg, u8 val) +{ + struct i2c_msg msg; + u8 buf[2]; + buf[0] = reg; + buf[1] = val; + msg.addr = info->i2c_client->addr; + msg.flags = 0; + msg.len = 2; + msg.buf = &buf[0]; + if (i2c_transfer(info->i2c_client->adapter, &msg, 1) != 1) + return -EIO; + return 0; +} + +static int ad5816_i2c_rd16(struct ad5816_info *info, u8 reg, u16 *val) +{ + struct i2c_msg msg[2]; + u8 buf[3]; + buf[0] = reg; + msg[0].addr = info->i2c_client->addr; + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = &buf[0]; + msg[1].addr = info->i2c_client->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = 2; + msg[1].buf = &buf[1]; + if (i2c_transfer(info->i2c_client->adapter, msg, 2) != 2) + return -EIO; + *val = (((u16)buf[1] << 8) | (u16)buf[2]); + return 0; +} + +static int ad5816_i2c_wr16(struct ad5816_info *info, u8 reg, u16 val) +{ + struct i2c_msg msg; + u8 buf[3]; + buf[0] = reg; + buf[1] = (u8)(val >> 8); + buf[2] = (u8)(val & 0xff); + msg.addr = info->i2c_client->addr; + msg.flags = 0; + msg.len = 3; + msg.buf = &buf[0]; + if (i2c_transfer(info->i2c_client->adapter, &msg, 1) != 1) + return -EIO; + return 0; +} + +static int ad5816_gpio_wr(struct ad5816_info *info, + enum ad5816_gpio_types i, + int val) /* val: 0=deassert, 1=assert */ +{ + int err = -EINVAL; + if (info->gpio[i].valid) { + if (val) + val = 1; + if (!info->gpio[i].active_high) + val = !val; + val &= 1; + err = val; + gpio_set_value_cansleep(info->gpio[i].gpio, val); + dev_dbg(&info->i2c_client->dev, "%s %u %d\n", __func__, info->gpio[i].gpio, val); + } + return err; /* return value written or error */ +} + +static int ad5816_gpio_reset(struct ad5816_info *info, int val) +{ + int err = 0; + + if (val) { + if (!info->reset_flag) { + info->reset_flag = true; + err = ad5816_gpio_wr(info, AD5816_GPIO_RESET, 1); + if (err < 0) + return 0; /* flag no reset */ + + mdelay(1); + ad5816_gpio_wr(info, AD5816_GPIO_RESET, 0); + mdelay(10); /* startup delay needs to be modified*/ + err = 1; /* flag that a reset was done */ + } + } else { + info->reset_flag = false; + } + return err; +} + +static void ad5816_gpio_able(struct ad5816_info *info, int val) +{ + /** + * This is a feature that allows driver to control GPIOs + * that may be needed for the board (not the device). + * */ + if (val) { + ad5816_gpio_wr(info, AD5816_GPIO_GP1, val); + ad5816_gpio_wr(info, AD5816_GPIO_GP2, val); + ad5816_gpio_wr(info, AD5816_GPIO_GP3, val); + } else { + ad5816_gpio_wr(info, AD5816_GPIO_GP3, val); + ad5816_gpio_wr(info, AD5816_GPIO_GP2, val); + ad5816_gpio_wr(info, AD5816_GPIO_GP1, val); + } +} +static void ad5816_gpio_exit(struct ad5816_info *info) +{ + unsigned i; + for (i = 0; i <= ARRAY_SIZE(ad5816_gpios); i++) { + if (info->gpio[i].flag && info->gpio[i].own) { + gpio_free(info->gpio[i].gpio); + info->gpio[i].own = false; + } + } +} + +static void ad5816_gpio_init(struct ad5816_info *info) +{ + char label[32]; + unsigned long flags; + unsigned type; + unsigned i; + unsigned j; + int err; + for (i = 0; i < ARRAY_SIZE(ad5816_gpios); i++) + info->gpio[i].flag = false; + + if (!info->pdata->gpio_count || !info->pdata->gpio) + return; + + for (i = 0; i < ARRAY_SIZE(ad5816_gpios); i++) { + type = ad5816_gpios[i].gpio_type; + + for (j = 0; j < info->pdata->gpio_count; j++) { + if (type == info->pdata->gpio[j].gpio_type) + break; + } + + if (j == info->pdata->gpio_count) + continue; + info->gpio[type].gpio = info->pdata->gpio[j].gpio; + info->gpio[type].flag = true; + + if (ad5816_gpios[i].use_flags) { + flags = ad5816_gpios[i].flags; + info->gpio[type].active_high = ad5816_gpios[i].active_high; + } else { + info->gpio[type].active_high = info->pdata->gpio[j].active_high; + if (info->gpio[type].active_high) + flags = GPIOF_OUT_INIT_LOW; + else + flags = GPIOF_OUT_INIT_HIGH; + } + + if (!info->pdata->gpio[j].init_en) + continue; + snprintf(label, sizeof(label), "ad5816_%u_%s", + info->pdata->num, ad5816_gpios[i].label); + err = gpio_request_one(info->gpio[type].gpio, flags, label); + if (err) { + dev_err(&info->i2c_client->dev, "%s ERR %s %u\n", + __func__, label, info->gpio[type].gpio); + } else { + info->gpio[type].own = true; + dev_dbg(&info->i2c_client->dev, "%s %s %u\n", + __func__, label, info->gpio[type].gpio); + } + } +} + +static int ad5816_vreg_dis(struct ad5816_info *info, + enum ad5816_vreg i) +{ + int err = 0; + if (info->vreg[i].vreg_flag && (info->vreg[i].vreg != NULL)) { + err = regulator_disable(info->vreg[i].vreg); + if (!err) + dev_dbg(&info->i2c_client->dev, "%s: %s\n", + __func__, info->vreg[i].vreg_name); + else + dev_err(&info->i2c_client->dev, "%s %s ERR\n", + __func__, info->vreg[i].vreg_name); + } + info->vreg[i].vreg_flag = false; + return err; +} + +static int ad5816_vreg_dis_all(struct ad5816_info *info) +{ + unsigned i; + int err = 0; + for (i = ARRAY_SIZE(ad5816_vregs); i > 0; i--) + err |= ad5816_vreg_dis(info, (i - 1)); + return err; +} + +static int ad5816_vreg_en(struct ad5816_info *info, + enum ad5816_vreg i) +{ + int err = 0; + if (!info->vreg[i].vreg_flag && (info->vreg[i].vreg != NULL)) { + err = regulator_enable(info->vreg[i].vreg); + + if (!err) { + dev_dbg(&info->i2c_client->dev, "%s: %s\n", + __func__, info->vreg[i].vreg_name); + info->vreg[i].vreg_flag = true; + err = 1; /* flag regulator state change */ + } else { + dev_err(&info->i2c_client->dev, "%s %s ERR\n", + __func__, info->vreg[i].vreg_name); + } + + } + return err; +} + +static int ad5816_vreg_en_all(struct ad5816_info *info) +{ + unsigned i; + int err = 0; + for (i = 0; i < ARRAY_SIZE(ad5816_vregs); i++) + err |= ad5816_vreg_en(info, i); + return err; +} + +static void ad5816_vreg_exit(struct ad5816_info *info) +{ + unsigned i; + for (i = 0; i < ARRAY_SIZE(ad5816_vregs); i++) { + regulator_put(info->vreg[i].vreg); + info->vreg[i].vreg = NULL; + } +} + +static int ad5816_vreg_init(struct ad5816_info *info) +{ + unsigned i; + unsigned j; + int err = 0; + for (i = 0; i < ARRAY_SIZE(ad5816_vregs); i++) { + j = ad5816_vregs[i].vreg_num; + info->vreg[j].vreg_name = ad5816_vregs[i].vreg_name; + info->vreg[j].vreg_flag = false; + info->vreg[j].vreg = regulator_get(&info->i2c_client->dev, + info->vreg[j].vreg_name); + if (IS_ERR_OR_NULL(info->vreg[j].vreg)) { + dev_dbg(&info->i2c_client->dev, "%s %s ERR: %d\n", + __func__, info->vreg[j].vreg_name, + (int)info->vreg[j].vreg); + err |= PTR_ERR(info->vreg[j].vreg); + info->vreg[j].vreg = NULL; + } else { + dev_dbg(&info->i2c_client->dev, "%s: %s\n", + __func__, info->vreg[j].vreg_name); + } + } + return err; +} + +void ad5816_set_power_down(struct ad5816_info *info) +{ + int err; + u16 data = 0x0000; + err = ad5816_i2c_wr16(info, VCM_CODE_MSB, data); + if (err) + dev_err(&info->i2c_client->dev, " %s: failed \n", + __func__); +} + +void ad5816_set_arc_mode(struct ad5816_info *info) +{ + int err = 0; + /* set ARC enable */ + err = ad5816_i2c_wr8(info, CONTROL, 0x02); + if (err) + dev_err(&info->i2c_client->dev, + "%s: CONTROL reg write failed \n", __func__); + + /* set the ARC RES2 */ + err = ad5816_i2c_wr8(info, MODE, 0x01); + if (err) + dev_err(&info->i2c_client->dev, + "%s: MODE reg write failed \n", __func__); + + /* set the VCM_FREQ to 12.8mS */ + err = ad5816_i2c_wr8(info, VCM_FREQ, 0x80); + if (err) + dev_err(&info->i2c_client->dev, + "%s: VCM_FREQ reg write failed \n", __func__); +} + +static int ad5816_pm_wr(struct ad5816_info *info, int pwr) +{ + int err = 0; + + if ((info->pdata->cfg & (NVC_CFG_OFF2STDBY | NVC_CFG_BOOT_INIT)) && + (pwr == NVC_PWR_OFF || + pwr == NVC_PWR_STDBY_OFF)) + pwr = NVC_PWR_STDBY; + + if (pwr == info->pwr_dev) + return 0; + + switch (pwr) + { + case NVC_PWR_OFF_FORCE: + case NVC_PWR_OFF: + err = ad5816_vreg_dis_all(info); + ad5816_gpio_able(info, 0); + ad5816_gpio_reset(info, 0); + break; + case NVC_PWR_STDBY_OFF: + case NVC_PWR_STDBY: + err = ad5816_vreg_en_all(info); + ad5816_gpio_able(info, 1); + ad5816_gpio_reset(info, 1); + break; + case NVC_PWR_COMM: + case NVC_PWR_ON: + err = ad5816_vreg_en_all(info); + ad5816_gpio_able(info, 1); + ad5816_gpio_reset(info, 1); + break; + default: + err = -EINVAL; + break; + } + + if (err < 0) { + dev_err(&info->i2c_client->dev, "%s err %d\n", __func__, err); + pwr = NVC_PWR_ERR; + } + + info->pwr_dev = pwr; + dev_dbg(&info->i2c_client->dev, "%s pwr_dev=%d\n", __func__, info->pwr_dev); + + if (err > 0) + return 0; + + return err; +} +static int ad5816_pm_wr_s(struct ad5816_info *info, int pwr) +{ + int err1 = 0; + int err2 = 0; + if ((info->s_mode == NVC_SYNC_OFF) || + (info->s_mode == NVC_SYNC_MASTER) || + (info->s_mode == NVC_SYNC_STEREO)) + err1 = ad5816_pm_wr(info, pwr); + if ((info->s_mode == NVC_SYNC_SLAVE) || + (info->s_mode == NVC_SYNC_STEREO)) + err2 = ad5816_pm_wr(info->s_info, pwr); + return err1 | err2; +} + +static int ad5816_pm_api_wr(struct ad5816_info *info, int pwr) +{ + int err = 0; + if (!pwr || (pwr > NVC_PWR_ON)) + return 0; + if (pwr > info->pwr_dev) { + err = ad5816_pm_wr_s(info, pwr); + } + if (!err) { + info->pwr_api = pwr; + } else + info->pwr_api = NVC_PWR_ERR; + if (info->pdata->cfg & NVC_CFG_NOERR) + return 0; + return err; +} + +static int ad5816_pm_dev_wr(struct ad5816_info *info, int pwr) +{ + if (pwr < info->pwr_api) + pwr = info->pwr_api; + return ad5816_pm_wr(info, pwr); +} + +static void ad5816_pm_exit(struct ad5816_info *info) +{ + ad5816_pm_wr(info, NVC_PWR_OFF_FORCE); + ad5816_vreg_exit(info); + ad5816_gpio_exit(info); +} +static void ad5816_pm_init(struct ad5816_info *info) +{ + ad5816_gpio_init(info); + ad5816_vreg_init(info); +} + +static int ad5816_reset(struct ad5816_info *info, u32 level) +{ + int err; + if (level == NVC_RESET_SOFT) { + err = ad5816_pm_wr(info, NVC_PWR_COMM); + err |= ad5816_i2c_wr8(info, CONTROL, 0x01); /* SW reset */ + } else { + err = ad5816_pm_wr(info, NVC_PWR_OFF_FORCE); + } + err |= ad5816_pm_wr(info, info->pwr_api); + return err; +} + +static int ad5816_dev_id(struct ad5816_info *info) +{ + u16 val = 0; + unsigned i; + int err; + ad5816_pm_dev_wr(info, NVC_PWR_COMM); + err = ad5816_i2c_rd16(info, IC_INFO, &val); + if (!err) { + dev_dbg(&info->i2c_client->dev, "%s found devId: %x\n", __func__, val); + info->id_minor = 0; + val = val & 0xff; + for (i = 0; i < ARRAY_SIZE(ad5816_ids); i++) { + if (val == ad5816_ids[i]) { + info->id_minor = val; + break; + } + } + if (!info->id_minor) { + err = -ENODEV; + dev_dbg(&info->i2c_client->dev, "%s No devId match\n", __func__); + } + } + ad5816_pm_dev_wr(info, NVC_PWR_OFF); + return err; +} + +static void ad5816_sts_rd(struct ad5816_info *info) +{ + /** + * Device specific code for status + * + * TODO: Ad5816 has support to get status for over/under + * voltage conditions but currently this feature is not + * required. + */ +} +/** + * Below are device specific functions. + */ + +static int ad5816_position_rd(struct ad5816_info *info, unsigned *position) +{ + + u16 pos = 0; + u8 t1 = 0; + int err = 0; + + err = ad5816_i2c_rd8(info, 0, VCM_CODE_MSB, &t1); + pos = t1 & 0x03; + err = ad5816_i2c_rd8(info, 0, VCM_CODE_LSB, &t1); + pos = (pos << 8) | t1; + if(pos) + *position = pos - info->config.pos_low; + else + *position = info->config.pos_low; + + return 0; +} + +static int ad5816_position_wr(struct ad5816_info *info, unsigned position) +{ + position = position + info->config.pos_low; + + if(position > info->config.pos_high) + position = info->config.pos_high; + + u16 data = position & 0x03ff; + + return ad5816_i2c_wr16(info, VCM_CODE_MSB, data); +} + +static int ad5816_param_rd(struct ad5816_info *info, unsigned long arg) +{ + struct nvc_param params; + const void *data_ptr; + u32 data_size = 0; + u32 position; + int err; + if (copy_from_user(¶ms, + (const void __user *)arg, + sizeof(struct nvc_param))) { + dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n", __func__, __LINE__); + return -EFAULT; + } + if (info->s_mode == NVC_SYNC_SLAVE) + info = info->s_info; + switch (params.param) { + case NVC_PARAM_LOCUS: + ad5816_pm_dev_wr(info, NVC_PWR_COMM); + err = ad5816_position_rd(info, &position); + if (err && !(info->pdata->cfg & NVC_CFG_NOERR)) + return err; + data_ptr = &position; + data_size = sizeof(position); + ad5816_pm_dev_wr(info, NVC_PWR_STDBY); + dev_dbg(&info->i2c_client->dev, "%s LOCUS: %d\n", + __func__, position); + break; + case NVC_PARAM_FOCAL_LEN: + info->nvc.focal_length = AD5816_FOCAL_LENGTH; + data_ptr = &info->nvc.focal_length; + data_size = sizeof(info->nvc.focal_length); + break; + case NVC_PARAM_MAX_APERTURE: + data_ptr = &info->nvc.max_aperature; + data_size = sizeof(info->nvc.max_aperature); + dev_dbg(&info->i2c_client->dev, "%s MAX_APERTURE: %x\n", + __func__, info->nvc.max_aperature); + break; + case NVC_PARAM_FNUMBER: + data_ptr = &info->nvc.fnumber; + data_size = sizeof(info->nvc.fnumber); + dev_dbg(&info->i2c_client->dev, "%s FNUMBER: %u\n", + __func__, info->nvc.fnumber); + break; + case NVC_PARAM_CAPS: + data_ptr = &info->cap; + /* there are different sizes depending on the version */ + /* send back just what's requested or our max size */ + if (params.sizeofvalue < sizeof(info->cap)) + data_size = params.sizeofvalue; + else + data_size = sizeof(info->cap); + dev_err(&info->i2c_client->dev, "%s CAPS\n", __func__); + break; + case NVC_PARAM_STS: + /*data_ptr = &info->sts; + data_size = sizeof(info->sts);*/ + dev_dbg(&info->i2c_client->dev, "%s \n", __func__); + break; + case NVC_PARAM_STEREO: + data_ptr = &info->s_mode; + data_size = sizeof(info->s_mode); + dev_err(&info->i2c_client->dev, "%s STEREO: %d\n", __func__, info->s_mode); + break; + default: + dev_err(&info->i2c_client->dev, "%s unsupported parameter: %d\n", + __func__, params.param); + return -EINVAL; + } + if (params.sizeofvalue < data_size) { + dev_err(&info->i2c_client->dev, + "%s data size mismatch %d != %d Param: %d\n", + __func__, params.sizeofvalue, data_size, params.param); + return -EINVAL; + } + if (copy_to_user((void __user *)params.p_value, data_ptr, data_size)) { + dev_err(&info->i2c_client->dev, "%s copy_to_user err line %d\n", + __func__, __LINE__); + return -EFAULT; + } + return 0; +} + +static int ad5816_param_wr_s(struct ad5816_info *info, + struct nvc_param *params, + u32 u32val) +{ + struct nvc_focus_cap cap; + u8 u8val; + int err = 0; + u8val = (u8)u32val; + switch (params->param) { + case NVC_PARAM_LOCUS: + dev_dbg(&info->i2c_client->dev, "%s LOCUS: %u\n", __func__, u32val); + err = ad5816_position_wr(info, u32val); + return err; + case NVC_PARAM_RESET: + err = ad5816_reset(info, u32val); + dev_dbg(&info->i2c_client->dev, "%s RESET: %d\n", __func__, err); + return err; + case NVC_PARAM_SELF_TEST: + err = 0; + dev_dbg(&info->i2c_client->dev, "%s SELF_TEST: %d\n", __func__, err); + return err; + default: + dev_dbg(&info->i2c_client->dev, + "%s unsupported parameter: %d\n", + __func__, params->param); + return -EINVAL; + } +} + +static int ad5816_param_wr(struct ad5816_info *info, unsigned long arg) +{ + struct nvc_param params; + u8 u8val; + u32 u32val; + int err = 0; + if (copy_from_user(¶ms, (const void __user *)arg, + sizeof(struct nvc_param))) { + dev_err(&info->i2c_client->dev, "%s copy_from_user err line %d\n", + __func__, __LINE__); + return -EFAULT; + } + if (copy_from_user(&u32val, (const void __user *)params.p_value, sizeof(u32val))) { + dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n", __func__, __LINE__); + return -EFAULT; + } + u8val = (u8)u32val; + /* parameters independent of sync mode */ + switch (params.param) { + case NVC_PARAM_STEREO: + dev_dbg(&info->i2c_client->dev, "%s STEREO: %d\n", __func__, u8val); + if (u8val == info->s_mode) + return 0; + switch (u8val) { + case NVC_SYNC_OFF: + info->s_mode = u8val; + ad5816_gpio_wr(info, AD5816_GPIO_I2CMUX, 0); + if (info->s_info != NULL) { + info->s_info->s_mode = u8val; + ad5816_pm_wr(info->s_info, NVC_PWR_OFF); + } + break; + case NVC_SYNC_MASTER: + info->s_mode = u8val; + ad5816_gpio_wr(info, AD5816_GPIO_I2CMUX, 0); + if (info->s_info != NULL) + info->s_info->s_mode = u8val; + break; + case NVC_SYNC_SLAVE: + if (info->s_info != NULL) { + /* default slave lens position */ + err = ad5816_position_wr(info->s_info, + info->s_info->cap.focus_infinity); + if (!err) { + info->s_mode = u8val; + info->s_info->s_mode = u8val; + ad5816_gpio_wr(info, + AD5816_GPIO_I2CMUX, 0); + } + else { + if (info->s_mode != NVC_SYNC_STEREO) + ad5816_pm_wr(info->s_info, + NVC_PWR_OFF); + err = -EIO; + } + } else { + err = -EINVAL; + } + break; + case NVC_SYNC_STEREO: + if (info->s_info != NULL) { + /* sync power */ + info->s_info->pwr_api = info->pwr_api; + /* move slave lens to master position */ + err = ad5816_position_wr(info->s_info, info->pos); + if (!err) { + info->s_mode = u8val; + info->s_info->s_mode = u8val; + ad5816_gpio_wr(info, AD5816_GPIO_I2CMUX, 1); + } + else { + if (info->s_mode != NVC_SYNC_SLAVE) + ad5816_pm_wr(info->s_info, NVC_PWR_OFF); + err = -EIO; + } + } else { + err = -EINVAL; + } + break; + default: + err = -EINVAL; + } + if (info->pdata->cfg & NVC_CFG_NOERR) + return 0; + return err; + default: + /* parameters dependent on sync mode */ + switch (info->s_mode) { + case NVC_SYNC_OFF: + case NVC_SYNC_MASTER: + return ad5816_param_wr_s(info, ¶ms, u32val); + case NVC_SYNC_SLAVE: + return ad5816_param_wr_s(info->s_info, ¶ms, u32val); + case NVC_SYNC_STEREO: + err = ad5816_param_wr_s(info, ¶ms, u32val); + if (!(info->pdata->cfg & NVC_CFG_SYNC_I2C_MUX)) + err |= ad5816_param_wr_s(info->s_info, + ¶ms, + u32val); + return err; + default: + dev_err(&info->i2c_client->dev, "%s %d internal err\n", + __func__, __LINE__); + return -EINVAL; + } + } +} + +static long ad5816_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + struct ad5816_info *info = file->private_data; + int pwr; + int err = 0; + switch (cmd) { + case NVC_IOCTL_PARAM_WR: + err = ad5816_param_wr(info, arg); + return err; + case NVC_IOCTL_PARAM_RD: + err = ad5816_param_rd(info, arg); + return err; + case NVC_IOCTL_PWR_WR: + /* This is a Guaranteed Level of Service (GLOS) call */ + pwr = (int)arg * 2; + dev_dbg(&info->i2c_client->dev, "%s PWR_WR: %d\n", + __func__, pwr); + err = ad5816_pm_api_wr(info, pwr); + return err; + case NVC_IOCTL_PWR_RD: + if (info->s_mode == NVC_SYNC_SLAVE) + pwr = info->s_info->pwr_api / 2; + else + pwr = info->pwr_api / 2; + dev_dbg(&info->i2c_client->dev, "%s PWR_RD: %d\n", + __func__, pwr); + if (copy_to_user((void __user *)arg, (const void *)&pwr, sizeof(pwr))) { + dev_err(&info->i2c_client->dev, "%s copy_to_user err line %d\n", + __func__, __LINE__); + return -EFAULT; + } + return 0; + default: + dev_dbg(&info->i2c_client->dev, "%s unsupported ioctl: %x\n", __func__, cmd); + } + return -EINVAL; +} + + +static void ad5816_sdata_init(struct ad5816_info *info) +{ + /* set defaults */ + memcpy(&info->config, &ad5816_default_info, sizeof(info->config)); + memcpy(&info->nvc, &ad5816_default_nvc, sizeof(info->nvc)); + memcpy(&info->cap, &ad5816_default_cap, sizeof(info->cap)); + + info->config.settle_time = AD5816_SETTLETIME; + info->config.focal_length = AD5816_FOCAL_LENGTH; + info->config.fnumber = AD5816_FNUMBER; + info->config.pos_low = AD5816_POS_LOW_DEFAULT; + info->config.pos_high = AD5816_POS_HIGH_DEFAULT; + + /* set to proper value */ + info->cap.actuator_range = info->config.pos_high - info->config.pos_low; + + /* set overrides if any */ + if (info->pdata->nvc) { + if (info->pdata->nvc->fnumber) + info->nvc.fnumber = info->pdata->nvc->fnumber; + if (info->pdata->nvc->focal_length) + info->nvc.focal_length = info->pdata->nvc->focal_length; + if (info->pdata->nvc->max_aperature) + info->nvc.max_aperature = info->pdata->nvc->max_aperature; + } + + if (info->pdata->cap) { + if (info->pdata->cap->actuator_range) + info->cap.actuator_range = info->pdata->cap->actuator_range; + if (info->pdata->cap->settle_time) + info->cap.settle_time = info->pdata->cap->settle_time; + if (info->pdata->cap->focus_macro) + info->cap.focus_macro = info->pdata->cap->focus_macro; + if (info->pdata->cap->focus_hyper) + info->cap.focus_hyper = info->pdata->cap->focus_hyper; + if (info->pdata->cap->focus_infinity) + info->cap.focus_infinity = info->pdata->cap->focus_infinity; + } +} + +static int ad5816_sync_en(unsigned num, unsigned sync) +{ + struct ad5816_info *master = NULL; + struct ad5816_info *slave = NULL; + struct ad5816_info *pos = NULL; + rcu_read_lock(); + list_for_each_entry_rcu(pos, &ad5816_info_list, list) { + if (pos->pdata->num == num) { + master = pos; + break; + } + } + pos = NULL; + list_for_each_entry_rcu(pos, &ad5816_info_list, list) { + if (pos->pdata->num == sync) { + slave = pos; + break; + } + } + rcu_read_unlock(); + if (master != NULL) + master->s_info = NULL; + if (slave != NULL) + slave->s_info = NULL; + if (!sync) + return 0; /* no err if sync disabled */ + if (num == sync) + return -EINVAL; /* err if sync instance is itself */ + if ((master != NULL) && (slave != NULL)) { + master->s_info = slave; + slave->s_info = master; + } + return 0; +} + +static int ad5816_sync_dis(struct ad5816_info *info) +{ + if (info->s_info != NULL) { + info->s_info->s_mode = 0; + info->s_info->s_info = NULL; + info->s_mode = 0; + info->s_info = NULL; + return 0; + } + return -EINVAL; +} + +static int ad5816_open(struct inode *inode, struct file *file) +{ + struct ad5816_info *info = NULL; + struct ad5816_info *pos = NULL; + int err; + rcu_read_lock(); + list_for_each_entry_rcu(pos, &ad5816_info_list, list) { + if (pos->miscdev.minor == iminor(inode)) { + info = pos; + break; + } + } + rcu_read_unlock(); + if (!info) + return -ENODEV; + err = ad5816_sync_en(info->pdata->num, info->pdata->sync); + if (err == -EINVAL) + dev_err(&info->i2c_client->dev, "%s err: invalid num (%u) and sync (%u) instance\n", + __func__, info->pdata->num, info->pdata->sync); + if (atomic_xchg(&info->in_use, 1)) + return -EBUSY; + if (info->s_info != NULL) { + if (atomic_xchg(&info->s_info->in_use, 1)) + return -EBUSY; + } + file->private_data = info; + ad5816_pm_dev_wr(info, NVC_PWR_ON); + /* set ARC Mode to ensure faster focus */ + ad5816_set_arc_mode(info); + dev_dbg(&info->i2c_client->dev, "%s\n", __func__); + + return 0; +} + +static int ad5816_release(struct inode *inode, struct file *file) +{ + struct ad5816_info *info = file->private_data; + dev_dbg(&info->i2c_client->dev, "%s\n", __func__); + ad5816_pm_wr_s(info, NVC_PWR_OFF); + file->private_data = NULL; + WARN_ON(!atomic_xchg(&info->in_use, 0)); + if (info->s_info != NULL) + WARN_ON(!atomic_xchg(&info->s_info->in_use, 0)); + ad5816_sync_dis(info); + return 0; +} + +static const struct file_operations ad5816_fileops = { + .owner = THIS_MODULE, + .open = ad5816_open, + .unlocked_ioctl = ad5816_ioctl, + .release = ad5816_release, +}; + +static void ad5816_del(struct ad5816_info *info) +{ + ad5816_pm_exit(info); + if ((info->s_mode == NVC_SYNC_SLAVE) || + (info->s_mode == NVC_SYNC_STEREO)) + ad5816_pm_exit(info->s_info); + + ad5816_sync_dis(info); + spin_lock(&ad5816_spinlock); + list_del_rcu(&info->list); + spin_unlock(&ad5816_spinlock); + synchronize_rcu(); +} + +static int ad5816_remove(struct i2c_client *client) +{ + struct ad5816_info *info = i2c_get_clientdata(client); + dev_dbg(&info->i2c_client->dev, "%s\n", __func__); + misc_deregister(&info->miscdev); + ad5816_del(info); + return 0; +} + +static int ad5816_probe( + struct i2c_client *client, + const struct i2c_device_id *id) +{ + pr_info("ad5816: probing focuser.\n"); + struct ad5816_info *info; + char dname[16]; + int err; + dev_dbg(&client->dev, "%s\n", __func__); + info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); + if (info == NULL) { + dev_err(&client->dev, "%s: kzalloc error\n", __func__); + return -ENOMEM; + } + info->i2c_client = client; + if (client->dev.platform_data) { + info->pdata = client->dev.platform_data; + } else { + info->pdata = &ad5816_default_pdata; + dev_dbg(&client->dev,"%s No platform data. Using defaults.\n", __func__); + } + + i2c_set_clientdata(client, info); + INIT_LIST_HEAD(&info->list); + spin_lock(&ad5816_spinlock); + list_add_rcu(&info->list, &ad5816_info_list); + spin_unlock(&ad5816_spinlock); + ad5816_pm_init(info); + ad5816_sdata_init(info); + + err = ad5816_dev_id(info); + if (err < 0) { + dev_err(&client->dev, "%s device not found\n", __func__); + ad5816_pm_wr(info, NVC_PWR_OFF); + if (info->pdata->cfg & NVC_CFG_NODEV) { + ad5816_del(info); + return -ENODEV; + } + } else { + dev_dbg(&client->dev, "%s device found\n", __func__); + if (info->pdata->cfg & NVC_CFG_BOOT_INIT) { + /* initial move causes full initialization */ + ad5816_pm_dev_wr(info, NVC_PWR_ON); + ad5816_position_wr(info, info->cap.focus_infinity); + ad5816_pm_dev_wr(info, NVC_PWR_OFF); + } + } + + if (info->pdata->dev_name != 0) + strcpy(dname, info->pdata->dev_name); + else + strcpy(dname, "ad5816"); + + if (info->pdata->num) + snprintf(dname, sizeof(dname), "%s.%u", dname, info->pdata->num); + + info->miscdev.name = dname; + info->miscdev.fops = &ad5816_fileops; + info->miscdev.minor = MISC_DYNAMIC_MINOR; + if (misc_register(&info->miscdev)) { + dev_err(&client->dev, "%s unable to register misc device %s\n", + __func__, dname); + ad5816_del(info); + return -ENODEV; + } + + return 0; +} + + +static const struct i2c_device_id ad5816_id[] = { + { "ad5816", 0 }, + { }, +}; + + +MODULE_DEVICE_TABLE(i2c, ad5816_id); + +static struct i2c_driver ad5816_i2c_driver = { + .driver = { + .name = "ad5816", + .owner = THIS_MODULE, + }, + .id_table = ad5816_id, + .probe = ad5816_probe, + .remove = ad5816_remove, +}; + +static int __init ad5816_init(void) +{ + return i2c_add_driver(&ad5816_i2c_driver); +} + +static void __exit ad5816_exit(void) +{ + i2c_del_driver(&ad5816_i2c_driver); +} + +module_init(ad5816_init); +module_exit(ad5816_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c index 94ba777bcdb3..f0f2ce1f6840 100644 --- a/drivers/mfd/tps80031.c +++ b/drivers/mfd/tps80031.c @@ -105,6 +105,9 @@ #define TPS80031_CFG_INPUT_PUPD3 0xF2 #define TPS80031_CFG_INPUT_PUPD4 0xF3 +#define TPS80031_BBSPOR_CFG 0xE6 +#define TPS80031_BBSPOR_CHG_EN 0x8 + struct tps80031_pupd_data { u8 reg; u8 pullup_bit; @@ -568,6 +571,17 @@ static void tps80031_pupd_init(struct tps80031 *tps80031, } } +static void tps80031_backup_battery_charger_control(struct tps80031 *tps80031, + int enable) +{ + if (enable) + tps80031_update(tps80031->dev, SLAVE_ID1, TPS80031_BBSPOR_CFG, + TPS80031_BBSPOR_CHG_EN, TPS80031_BBSPOR_CHG_EN); + else + tps80031_update(tps80031->dev, SLAVE_ID1, TPS80031_BBSPOR_CFG, + 0, TPS80031_BBSPOR_CHG_EN); +} + static void tps80031_init_ext_control(struct tps80031 *tps80031, struct tps80031_platform_data *pdata) { int ret; @@ -1287,6 +1301,8 @@ static int __devinit tps80031_i2c_probe(struct i2c_client *client, tps80031_debuginit(tps80031); + tps80031_backup_battery_charger_control(tps80031, 1); + if (pdata->use_power_off && !pm_power_off) pm_power_off = tps80031_power_off; @@ -1302,13 +1318,17 @@ fail: #ifdef CONFIG_PM static int tps80031_i2c_suspend(struct i2c_client *client, pm_message_t state) { + struct tps80031 *tps80031 = i2c_get_clientdata(client); if (client->irq) disable_irq(client->irq); + tps80031_backup_battery_charger_control(tps80031, 0); return 0; } static int tps80031_i2c_resume(struct i2c_client *client) { + struct tps80031 *tps80031 = i2c_get_clientdata(client); + tps80031_backup_battery_charger_control(tps80031, 1); if (client->irq) enable_irq(client->irq); return 0; diff --git a/drivers/misc/tegra-baseband/bb-m7400.c b/drivers/misc/tegra-baseband/bb-m7400.c index 5808a6e321cd..99698a860917 100644 --- a/drivers/misc/tegra-baseband/bb-m7400.c +++ b/drivers/misc/tegra-baseband/bb-m7400.c @@ -28,10 +28,12 @@ #include <linux/device.h> #include <linux/usb.h> #include <linux/wakelock.h> +#include <linux/platform_data/tegra_usb.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/tegra-bb-power.h> #include <mach/usb_phy.h> + #include "bb-power.h" static struct tegra_bb_gpio_data m7400_gpios[] = { @@ -193,20 +195,17 @@ static int m7400_power(int code) static void m7400_ehci_customize(struct platform_device *pdev) { - struct tegra_ehci_platform_data *ehci_pdata; - struct tegra_uhsic_config *hsic_config; + struct tegra_usb_platform_data *ehci_pdata; - ehci_pdata = (struct tegra_ehci_platform_data *) + ehci_pdata = (struct usb_platform_data *) pdev->dev.platform_data; - hsic_config = (struct tegra_uhsic_config *) - ehci_pdata->phy_config; /* Register PHY callbacks */ - hsic_config->postsuspend = m7400_l2_suspend; - hsic_config->preresume = m7400_l2_resume; + ehci_pdata->ops->post_suspend = m7400_l2_suspend; + ehci_pdata->ops->pre_resume = m7400_l2_resume; /* Override required settings */ - ehci_pdata->power_down_on_bus_suspend = 0; + ehci_pdata->u_data.host.power_off_on_suspend = false; } static int m7400_attrib_write(struct device *dev, int value) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 8fec147471a8..609fd6391d1f 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -545,11 +545,6 @@ static int tegra_sdhci_signal_voltage_switch(struct sdhci_host *sdhci, u16 clk, ctrl; unsigned int val; - /* Switch OFF the card clock to prevent glitches on the clock line */ - clk = sdhci_readw(sdhci, SDHCI_CLOCK_CONTROL); - clk &= ~SDHCI_CLOCK_CARD_EN; - sdhci_writew(sdhci, clk, SDHCI_CLOCK_CONTROL); - ctrl = sdhci_readw(sdhci, SDHCI_HOST_CONTROL2); if (signal_voltage == MMC_SIGNAL_VOLTAGE_180) { ctrl |= SDHCI_CTRL_VDD_180; @@ -559,6 +554,17 @@ static int tegra_sdhci_signal_voltage_switch(struct sdhci_host *sdhci, if (ctrl & SDHCI_CTRL_VDD_180) ctrl &= ~SDHCI_CTRL_VDD_180; } + + /* Check if the slot can support the required voltage */ + if (min_uV > tegra_host->vddio_max_uv) + return 0; + + /* Switch OFF the card clock to prevent glitches on the clock line */ + clk = sdhci_readw(sdhci, SDHCI_CLOCK_CONTROL); + clk &= ~SDHCI_CLOCK_CARD_EN; + sdhci_writew(sdhci, clk, SDHCI_CLOCK_CONTROL); + + /* Set/clear the 1.8V signalling */ sdhci_writew(sdhci, ctrl, SDHCI_HOST_CONTROL2); /* Switch the I/O rail voltage */ diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c index 434e584f830c..e71ab64c2caa 100644 --- a/drivers/net/wireless/bcm4329/wl_iw.c +++ b/drivers/net/wireless/bcm4329/wl_iw.c @@ -5109,6 +5109,7 @@ wl_iw_set_pmksa( uint i; int ret = 0; char eabuf[ETHER_ADDR_STR_LEN]; + pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid; WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name)); CHECK_EXTRA_FOR_NULL(extra); @@ -5139,18 +5140,18 @@ wl_iw_set_pmksa( } for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, + if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, ETHER_ADDR_LEN)) break; if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) { - bzero(&pmkid_list.pmkids.pmkid[i], sizeof(pmkid_t)); + bzero(&pmkid_array[i], sizeof(pmkid_t)); for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - bcopy(&pmkid_list.pmkids.pmkid[i+1].BSSID, - &pmkid_list.pmkids.pmkid[i].BSSID, + bcopy(&pmkid_array[i+1].BSSID, + &pmkid_array[i].BSSID, ETHER_ADDR_LEN); - bcopy(&pmkid_list.pmkids.pmkid[i+1].PMKID, - &pmkid_list.pmkids.pmkid[i].PMKID, + bcopy(&pmkid_array[i+1].PMKID, + &pmkid_array[i].PMKID, WPA2_PMKID_LEN); } pmkid_list.pmkids.npmkid--; @@ -5161,14 +5162,14 @@ wl_iw_set_pmksa( else if (iwpmksa->cmd == IW_PMKSA_ADD) { for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, + if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, ETHER_ADDR_LEN)) break; if (i < MAXPMKID) { bcopy(&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, + &pmkid_array[i].BSSID, ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkid_list.pmkids.pmkid[i].PMKID, + bcopy(&iwpmksa->pmkid[0], &pmkid_array[i].PMKID, WPA2_PMKID_LEN); if (i == pmkid_list.pmkids.npmkid) pmkid_list.pmkids.npmkid++; @@ -5181,10 +5182,10 @@ wl_iw_set_pmksa( uint k; k = pmkid_list.pmkids.npmkid; WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[k].BSSID, + bcm_ether_ntoa(&pmkid_array[k].BSSID, eabuf))); for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[k].PMKID[j])); + WL_WSEC(("%02x ", pmkid_array[k].PMKID[j])); WL_WSEC(("\n")); } } @@ -5192,10 +5193,10 @@ wl_iw_set_pmksa( for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { uint j; WL_WSEC(("PMKID[%d]: %s = ", i, - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[i].BSSID, + bcm_ether_ntoa(&pmkid_array[i].BSSID, eabuf))); for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j])); + WL_WSEC(("%02x ", pmkid_array[i].PMKID[j])); WL_WSEC(("\n")); } WL_WSEC(("\n")); diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 4901114f746c..d4b9c3344eee 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c @@ -144,7 +144,6 @@ #define DATA_DIR_TX (1 << 0) #define DATA_DIR_RX (1 << 1) -#define SPI_FIFO_DEPTH 32 #define SLINK_DMA_TIMEOUT (msecs_to_jiffies(1000)) @@ -169,7 +168,7 @@ static const unsigned long spi_tegra_req_sels[] = { RX_FIFO_FULL_COUNT_ZERO << 16) #define MAX_CHIP_SELECT 4 -#define SLINK_FIFO_DEPTH 4 +#define SLINK_FIFO_DEPTH 32 struct spi_tegra_data { struct spi_master *master; @@ -247,6 +246,9 @@ struct spi_tegra_data { struct work_struct spi_transfer_work; }; +static int tegra_spi_runtime_idle(struct device *dev); +static int tegra_spi_runtime_resume(struct device *dev); + static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, unsigned long reg) { @@ -261,6 +263,9 @@ static inline void spi_tegra_writel(struct spi_tegra_data *tspi, if (!tspi->clk_state) BUG(); writel(val, tspi->base + reg); + + /* Synchronize write by reading back the register */ + readl(tspi->base + SLINK_MAS_DATA); } static void cancel_dma(struct tegra_dma_channel *dma_chan, @@ -731,12 +736,7 @@ static void spi_tegra_start_transfer(struct spi_device *spi, command2 = tspi->def_command2_reg; if (is_first_of_msg) { - if (!tspi->is_clkon_always) { - if (!tspi->clk_state) { - pm_runtime_get_sync(&tspi->pdev->dev); - tspi->clk_state = 1; - } - } + pm_runtime_get_sync(&tspi->pdev->dev); spi_tegra_clear_status(tspi); @@ -806,7 +806,7 @@ static void spi_tegra_start_transfer(struct spi_device *spi, spi_tegra_writel(tspi, command2, SLINK_COMMAND2); tspi->command2_reg = command2; - if (total_fifo_words > SPI_FIFO_DEPTH) + if (total_fifo_words > SLINK_FIFO_DEPTH) ret = spi_tegra_start_dma_based_transfer(tspi, t); else ret = spi_tegra_start_cpu_based_transfer(tspi, t); @@ -848,6 +848,8 @@ static int spi_tegra_setup(struct spi_device *spi) return -EINVAL; } + pm_runtime_get_sync(&tspi->pdev->dev); + spin_lock_irqsave(&tspi->lock, flags); val = tspi->def_command_reg; if (spi->mode & SPI_CS_HIGH) @@ -855,20 +857,10 @@ static int spi_tegra_setup(struct spi_device *spi) else val &= ~cs_bit; tspi->def_command_reg = val; - - if (!tspi->is_clkon_always && !tspi->clk_state) { - spin_unlock_irqrestore(&tspi->lock, flags); - pm_runtime_get_sync(&tspi->pdev->dev); - spin_lock_irqsave(&tspi->lock, flags); - tspi->clk_state = 1; - } spi_tegra_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); - if (!tspi->is_clkon_always && tspi->clk_state) { - tspi->clk_state = 0; - spin_unlock_irqrestore(&tspi->lock, flags); - pm_runtime_put_sync(&tspi->pdev->dev); - } else - spin_unlock_irqrestore(&tspi->lock, flags); + spin_unlock_irqrestore(&tspi->lock, flags); + + pm_runtime_put_sync(&tspi->pdev->dev); return 0; } @@ -1010,19 +1002,11 @@ static void spi_tegra_curr_transfer_complete(struct spi_tegra_data *tspi, SLINK_COMMAND); spi_tegra_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); - if (!tspi->is_clkon_always) { - if (tspi->clk_state) { - /* Provide delay to stablize the signal - state */ - spin_unlock_irqrestore(&tspi->lock, - *irq_flags); - udelay(10); - pm_runtime_put_sync(&tspi->pdev->dev); - spin_lock_irqsave(&tspi->lock, - *irq_flags); - tspi->clk_state = 0; - } - } + /* Provide delay to stablize the signal state */ + spin_unlock_irqrestore(&tspi->lock, *irq_flags); + udelay(10); + pm_runtime_put_sync(&tspi->pdev->dev); + spin_lock_irqsave(&tspi->lock, *irq_flags); tspi->is_transfer_in_progress = false; /* Check if any new request has come between * clock disable */ @@ -1173,7 +1157,7 @@ static irqreturn_t spi_tegra_isr_thread(int irq, void *context_data) /* Continue transfer in current message */ total_fifo_words = spi_tegra_calculate_curr_xfer_param(tspi->cur_spi, tspi, t); - if (total_fifo_words > SPI_FIFO_DEPTH) + if (total_fifo_words > SLINK_FIFO_DEPTH) err = spi_tegra_start_dma_based_transfer(tspi, t); else err = spi_tegra_start_cpu_based_transfer(tspi, t); @@ -1201,6 +1185,87 @@ static irqreturn_t spi_tegra_isr(int irq, void *context_data) return IRQ_WAKE_THREAD; } +static void spi_tegra_deinit_dma_param(struct spi_tegra_data *tspi, + bool dma_to_memory) +{ + struct tegra_dma_channel *tdc; + u32 *dma_buf; + dma_addr_t dma_phys; + + if (dma_to_memory) { + dma_buf = tspi->rx_buf; + tdc = tspi->rx_dma; + dma_phys = tspi->rx_buf_phys; + tspi->rx_dma = NULL; + tspi->rx_buf = NULL; + } else { + dma_buf = tspi->tx_buf; + tdc = tspi->tx_dma; + dma_phys = tspi->tx_buf_phys; + tspi->tx_buf = NULL; + tspi->tx_dma = NULL; + } + + dma_free_coherent(&tspi->pdev->dev, tspi->dma_buf_size, + dma_buf, dma_phys); + tegra_dma_free_channel(tdc); +} + +static int __init spi_tegra_init_dma_param(struct spi_tegra_data *tspi, + bool dma_to_memory) +{ + struct tegra_dma_req *dma_req; + struct tegra_dma_channel *tdc; + u32 *dma_buf; + dma_addr_t dma_phys; + + tdc = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT, "spi_%s_%d", + (dma_to_memory) ? "rx" : "tx", tspi->pdev->id); + if (!tdc) { + dev_err(&tspi->pdev->dev, "can not allocate rx dma channel\n"); + return -ENODEV; + } + + dma_buf = dma_alloc_coherent(&tspi->pdev->dev, tspi->dma_buf_size, + &dma_phys, GFP_KERNEL); + if (!dma_buf) { + dev_err(&tspi->pdev->dev, "can not allocate rx bounce buffer"); + tegra_dma_free_channel(tdc); + return -ENOMEM; + } + + dma_req = (dma_to_memory) ? &tspi->rx_dma_req : &tspi->tx_dma_req; + memset(dma_req, 0, sizeof(*dma_req)); + + dma_req->req_sel = spi_tegra_req_sels[tspi->pdev->id]; + dma_req->dev = tspi; + dma_req->dest_bus_width = 32; + dma_req->source_bus_width = 32; + dma_req->to_memory = (dma_to_memory) ? 1 : 0; + dma_req->virt_addr = dma_buf; + dma_req->dest_wrap = 0; + dma_req->source_wrap = 0; + + if (dma_to_memory) { + dma_req->complete = tegra_spi_rx_dma_complete; + dma_req->dest_addr = dma_phys; + dma_req->source_addr = tspi->phys + SLINK_RX_FIFO; + dma_req->source_wrap = 4; + tspi->rx_buf_phys = dma_phys; + tspi->rx_buf = dma_buf; + tspi->rx_dma = tdc; + } else { + dma_req->complete = tegra_spi_tx_dma_complete; + dma_req->dest_addr = tspi->phys + SLINK_TX_FIFO; + dma_req->source_addr = dma_phys; + dma_req->dest_wrap = 4; + tspi->tx_buf = dma_buf; + tspi->tx_buf_phys = dma_phys; + tspi->tx_dma = tdc; + } + return 0; +} + static int __init spi_tegra_probe(struct platform_device *pdev) { struct spi_master *master; @@ -1236,55 +1301,50 @@ static int __init spi_tegra_probe(struct platform_device *pdev) spin_lock_init(&tspi->lock); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) { + if (!r) { + dev_err(&pdev->dev, "No IO memory resource\n"); ret = -ENODEV; - goto fail_no_mem; - } - - if (!request_mem_region(r->start, resource_size(r), - dev_name(&pdev->dev))) { - ret = -EBUSY; - goto fail_no_mem; + goto exit_free_master; } - tspi->phys = r->start; - tspi->base = ioremap(r->start, resource_size(r)); + tspi->base = devm_request_and_ioremap(&pdev->dev, r); if (!tspi->base) { - dev_err(&pdev->dev, "can't ioremap iomem\n"); - ret = -ENOMEM; - goto fail_io_map; + dev_err(&pdev->dev, + "Cannot request memregion/iomap dma address\n"); + ret = -EADDRNOTAVAIL; + goto exit_free_master; } spi_irq = platform_get_irq(pdev, 0); if (unlikely(spi_irq < 0)) { dev_err(&pdev->dev, "can't find irq resource\n"); ret = -ENXIO; - goto fail_irq_req; + goto exit_free_master; } tspi->irq = spi_irq; sprintf(tspi->port_name, "tegra_spi_%d", pdev->id); - ret = request_threaded_irq(tspi->irq, spi_tegra_isr, - spi_tegra_isr_thread, IRQF_ONESHOT, + ret = devm_request_threaded_irq(&pdev->dev, tspi->irq, + spi_tegra_isr, spi_tegra_isr_thread, IRQF_ONESHOT, tspi->port_name, tspi); if (ret < 0) { dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", tspi->irq); - goto fail_irq_req; + goto exit_free_master; } - tspi->clk = clk_get(&pdev->dev, "spi"); + tspi->clk = devm_clk_get(&pdev->dev, "spi"); if (IS_ERR(tspi->clk)) { dev_err(&pdev->dev, "can not get clock\n"); ret = PTR_ERR(tspi->clk); - goto fail_clk_get; + goto exit_free_master; } - tspi->sclk = clk_get(&pdev->dev, "sclk"); + tspi->sclk = devm_clk_get(&pdev->dev, "sclk"); if (IS_ERR(tspi->sclk)) { dev_err(&pdev->dev, "can not get sclock\n"); ret = PTR_ERR(tspi->sclk); - goto fail_sclk_get; + goto exit_free_master; } INIT_LIST_HEAD(&tspi->queue); @@ -1327,84 +1387,41 @@ static int __init spi_tegra_probe(struct platform_device *pdev) init_completion(&tspi->tx_dma_complete); init_completion(&tspi->rx_dma_complete); - - tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT, - "spi_rx_%d", pdev->id); - if (!tspi->rx_dma) { - dev_err(&pdev->dev, "can not allocate rx dma channel\n"); - ret = -ENODEV; - goto fail_rx_dma_alloc; - } - - tspi->rx_buf = dma_alloc_coherent(&pdev->dev, tspi->dma_buf_size, - &tspi->rx_buf_phys, GFP_KERNEL); - if (!tspi->rx_buf) { - dev_err(&pdev->dev, "can not allocate rx bounce buffer\n"); - ret = -ENOMEM; - goto fail_rx_buf_alloc; - } - - memset(&tspi->rx_dma_req, 0, sizeof(struct tegra_dma_req)); - tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete; - tspi->rx_dma_req.to_memory = 1; - tspi->rx_dma_req.dest_addr = tspi->rx_buf_phys; - tspi->rx_dma_req.virt_addr = tspi->rx_buf; - tspi->rx_dma_req.dest_bus_width = 32; - tspi->rx_dma_req.source_addr = tspi->phys + SLINK_RX_FIFO; - tspi->rx_dma_req.source_bus_width = 32; - tspi->rx_dma_req.source_wrap = 4; - tspi->rx_dma_req.dest_wrap = 0; - tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id]; - tspi->rx_dma_req.dev = tspi; - - tspi->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT, - "spi_tx_%d", pdev->id); - if (!tspi->tx_dma) { - dev_err(&pdev->dev, "can not allocate tx dma channel\n"); - ret = -ENODEV; - goto fail_tx_dma_alloc; + ret = spi_tegra_init_dma_param(tspi, true); + if (ret < 0) { + dev_err(&pdev->dev, "Error in rx dma init\n"); + goto exit_free_master; } - tspi->tx_buf = dma_alloc_coherent(&pdev->dev, tspi->dma_buf_size, - &tspi->tx_buf_phys, GFP_KERNEL); - if (!tspi->tx_buf) { - dev_err(&pdev->dev, "can not allocate tx bounce buffer\n"); - ret = -ENOMEM; - goto fail_tx_buf_alloc; + ret = spi_tegra_init_dma_param(tspi, false); + if (ret < 0) { + dev_err(&pdev->dev, "Error in tx dma init\n"); + goto exit_rx_dma_free; } - memset(&tspi->tx_dma_req, 0, sizeof(struct tegra_dma_req)); - tspi->tx_dma_req.complete = tegra_spi_tx_dma_complete; - tspi->tx_dma_req.to_memory = 0; - tspi->tx_dma_req.dest_addr = tspi->phys + SLINK_TX_FIFO; - tspi->tx_dma_req.virt_addr = tspi->tx_buf; - tspi->tx_dma_req.dest_bus_width = 32; - tspi->tx_dma_req.dest_wrap = 4; - tspi->tx_dma_req.source_wrap = 0; - tspi->tx_dma_req.source_addr = tspi->tx_buf_phys; - tspi->tx_dma_req.source_bus_width = 32; - tspi->tx_dma_req.req_sel = spi_tegra_req_sels[pdev->id]; - tspi->tx_dma_req.dev = tspi; tspi->max_buf_size = tspi->dma_buf_size; tspi->def_command_reg = SLINK_CS_SW | SLINK_M_S; tspi->def_command2_reg = SLINK_CS_ACTIVE_BETWEEN; skip_dma_alloc: pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - tspi->clk_state = 1; - master->dev.of_node = pdev->dev.of_node; - ret = spi_register_master(master); - if (!tspi->is_clkon_always) { - if (tspi->clk_state) { - pm_runtime_put_sync(&pdev->dev); - tspi->clk_state = 0; + if (!pm_runtime_enabled(&pdev->dev)) { + ret = tegra_spi_runtime_resume(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "runtime resume failed %d", ret); + goto exit_pm_disable; } } + /* Enable clock if it is require to be enable always */ + if (tspi->is_clkon_always) + pm_runtime_get_sync(&pdev->dev); + + master->dev.of_node = pdev->dev.of_node; + ret = spi_register_master(master); if (ret < 0) { dev_err(&pdev->dev, "can not register to master err %d\n", ret); - goto fail_master_register; + goto exit_pm_suspend; } /* create the workqueue for the kbc path */ @@ -1413,42 +1430,32 @@ skip_dma_alloc: if (!tspi->spi_workqueue) { dev_err(&pdev->dev, "Failed to create work queue\n"); ret = -ENODEV; - goto fail_workqueue; + goto exit_master_unregister; } INIT_WORK(&tspi->spi_transfer_work, tegra_spi_transfer_work); return ret; -fail_workqueue: +exit_master_unregister: spi_unregister_master(master); -fail_master_register: - if (tspi->tx_buf) - dma_free_coherent(&pdev->dev, tspi->dma_buf_size, - tspi->tx_buf, tspi->tx_buf_phys); -fail_tx_buf_alloc: - if (tspi->tx_dma) - tegra_dma_free_channel(tspi->tx_dma); -fail_tx_dma_alloc: - if (tspi->rx_buf) - dma_free_coherent(&pdev->dev, tspi->dma_buf_size, - tspi->rx_buf, tspi->rx_buf_phys); -fail_rx_buf_alloc: - if (tspi->rx_dma) - tegra_dma_free_channel(tspi->rx_dma); -fail_rx_dma_alloc: + if (tspi->is_clkon_always) + pm_runtime_put_sync(&pdev->dev); + +exit_pm_suspend: + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_spi_runtime_idle(&pdev->dev); + +exit_pm_disable: pm_runtime_disable(&pdev->dev); - clk_put(tspi->sclk); -fail_sclk_get: - clk_put(tspi->clk); -fail_clk_get: - free_irq(tspi->irq, tspi); -fail_irq_req: - iounmap(tspi->base); -fail_io_map: - release_mem_region(r->start, resource_size(r)); -fail_no_mem: + + spi_tegra_deinit_dma_param(tspi, false); + +exit_rx_dma_free: + spi_tegra_deinit_dma_param(tspi, true); + +exit_free_master: spi_master_put(master); return ret; } @@ -1457,56 +1464,44 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) { struct spi_master *master; struct spi_tegra_data *tspi; - struct resource *r; master = dev_get_drvdata(&pdev->dev); tspi = spi_master_get_devdata(master); spi_unregister_master(master); - if (tspi->tx_buf) - dma_free_coherent(&pdev->dev, tspi->dma_buf_size, - tspi->tx_buf, tspi->tx_buf_phys); + if (tspi->tx_dma) - tegra_dma_free_channel(tspi->tx_dma); - if (tspi->rx_buf) - dma_free_coherent(&pdev->dev, tspi->dma_buf_size, - tspi->rx_buf, tspi->rx_buf_phys); + spi_tegra_deinit_dma_param(tspi, false); + if (tspi->rx_dma) - tegra_dma_free_channel(tspi->rx_dma); + spi_tegra_deinit_dma_param(tspi, true); - if (tspi->is_clkon_always) { + /* Disable clock if it is always enabled */ + if (tspi->is_clkon_always) pm_runtime_put_sync(&pdev->dev); - tspi->clk_state = 0; - } pm_runtime_disable(&pdev->dev); - clk_put(tspi->sclk); - clk_put(tspi->clk); - iounmap(tspi->base); + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_spi_runtime_idle(&pdev->dev); destroy_workqueue(tspi->spi_workqueue); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, resource_size(r)); - return 0; } #ifdef CONFIG_PM -static int spi_tegra_suspend(struct platform_device *pdev, pm_message_t state) +static int spi_tegra_suspend(struct device *dev) { - struct spi_master *master; - struct spi_tegra_data *tspi; - unsigned limit = 50; + struct spi_master *master = dev_get_drvdata(dev); + struct spi_tegra_data *tspi = spi_master_get_devdata(master); + unsigned limit = 50; unsigned long flags; - master = dev_get_drvdata(&pdev->dev); - tspi = spi_master_get_devdata(master); spin_lock_irqsave(&tspi->lock, flags); /* Wait for all transfer completes */ if (!list_empty(&tspi->queue)) - dev_warn(&pdev->dev, "The transfer list is not empty " + dev_warn(dev, "The transfer list is not empty " "Waiting for time %d ms to complete transfer\n", limit * 20); @@ -1520,7 +1515,7 @@ static int spi_tegra_suspend(struct platform_device *pdev, pm_message_t state) tspi->is_suspended = true; if (!list_empty(&tspi->queue)) { limit = 50; - dev_err(&pdev->dev, "All transfer has not completed, " + dev_err(dev, "All transfer has not completed, " "Waiting for %d ms current transfer to complete\n", limit * 20); while (tspi->is_transfer_in_progress && limit--) { @@ -1531,7 +1526,7 @@ static int spi_tegra_suspend(struct platform_device *pdev, pm_message_t state) } if (tspi->is_transfer_in_progress) { - dev_err(&pdev->dev, + dev_err(dev, "Spi transfer is in progress Avoiding suspend\n"); tspi->is_suspended = false; spin_unlock_irqrestore(&tspi->lock, flags); @@ -1539,33 +1534,32 @@ static int spi_tegra_suspend(struct platform_device *pdev, pm_message_t state) } spin_unlock_irqrestore(&tspi->lock, flags); - if (tspi->is_clkon_always) { - pm_runtime_put_sync(&pdev->dev); - tspi->clk_state = 0; - } + + /* Disable clock if it is always enabled */ + if (tspi->is_clkon_always) + pm_runtime_put_sync(dev); + return 0; } -static int spi_tegra_resume(struct platform_device *pdev) +static int spi_tegra_resume(struct device *dev) { - struct spi_master *master; - struct spi_tegra_data *tspi; + struct spi_master *master = dev_get_drvdata(dev); + struct spi_tegra_data *tspi = spi_master_get_devdata(master); struct spi_message *m; struct spi_device *spi; struct spi_transfer *t = NULL; int single_xfer = 0; unsigned long flags; - master = dev_get_drvdata(&pdev->dev); - tspi = spi_master_get_devdata(master); + /* Enable clock if it is always enabled */ + if (tspi->is_clkon_always) + pm_runtime_get_sync(dev); - pm_runtime_get_sync(&pdev->dev); - tspi->clk_state = 1; + pm_runtime_get_sync(dev); spi_tegra_writel(tspi, tspi->command_reg, SLINK_COMMAND); - if (!tspi->is_clkon_always) { - pm_runtime_put_sync(&pdev->dev); - tspi->clk_state = 0; - } + pm_runtime_put_sync(dev); + spin_lock_irqsave(&tspi->lock, flags); tspi->cur_speed = 0; @@ -1587,15 +1581,15 @@ static int spi_tegra_resume(struct platform_device *pdev) } #endif -#if defined(CONFIG_PM_RUNTIME) - static int tegra_spi_runtime_idle(struct device *dev) { - struct spi_master *master; - struct spi_tegra_data *tspi; - master = dev_get_drvdata(dev); - tspi = spi_master_get_devdata(master); + struct spi_master *master = dev_get_drvdata(dev); + struct spi_tegra_data *tspi = spi_master_get_devdata(master); + + /* Flush all write which are in PPSB queue by reading back */ + spi_tegra_readl(tspi, SLINK_MAS_DATA); + tspi->clk_state = 0; clk_disable(tspi->clk); clk_disable(tspi->sclk); return 0; @@ -1603,22 +1597,25 @@ static int tegra_spi_runtime_idle(struct device *dev) static int tegra_spi_runtime_resume(struct device *dev) { - struct spi_master *master; - struct spi_tegra_data *tspi; - master = dev_get_drvdata(dev); - tspi = spi_master_get_devdata(master); + struct spi_master *master = dev_get_drvdata(dev); + struct spi_tegra_data *tspi = spi_master_get_devdata(master); clk_enable(tspi->sclk); clk_enable(tspi->clk); + tspi->clk_state = 1; return 0; } static const struct dev_pm_ops tegra_spi_dev_pm_ops = { +#if defined(CONFIG_PM_RUNTIME) .runtime_idle = tegra_spi_runtime_idle, .runtime_resume = tegra_spi_runtime_resume, -}; - #endif +#ifdef CONFIG_PM + .suspend = spi_tegra_suspend, + .resume = spi_tegra_resume, +#endif +}; MODULE_ALIAS("platform:spi_tegra"); @@ -1636,16 +1633,10 @@ static struct platform_driver spi_tegra_driver = { .driver = { .name = "spi_tegra", .owner = THIS_MODULE, -#if defined(CONFIG_PM_RUNTIME) .pm = &tegra_spi_dev_pm_ops, -#endif .of_match_table = spi_tegra_of_match_table, }, .remove = __devexit_p(spi_tegra_remove), -#ifdef CONFIG_PM - .suspend = spi_tegra_suspend, - .resume = spi_tegra_resume, -#endif }; static int __init spi_tegra_init(void) diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index fedd8eef4ae2..c8c7c687010d 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -1,7 +1,6 @@ # # USB peripheral controller drivers # -GCOV_PROFILE_fsl_tegra_udc.o := y GCOV_PROFILE_tegra_udc.o := y ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index fbafe8a3bca4..4805670cf6e3 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -319,6 +319,13 @@ static int mtp_function_ctrlrequest(struct android_usb_function *f, return mtp_ctrlrequest(cdev, c); } +static int ptp_function_ctrlrequest(struct android_usb_function *f, + struct usb_composite_dev *cdev, + const struct usb_ctrlrequest *c) +{ + return mtp_ctrlrequest(cdev, c); +} + static struct android_usb_function mtp_function = { .name = "mtp", .init = mtp_function_init, @@ -333,6 +340,7 @@ static struct android_usb_function ptp_function = { .init = ptp_function_init, .cleanup = ptp_function_cleanup, .bind_config = ptp_function_bind_config, + .ctrlrequest = ptp_function_ctrlrequest, }; diff --git a/drivers/usb/gadget/fsl_tegra_udc.c b/drivers/usb/gadget/fsl_tegra_udc.c deleted file mode 100644 index 31b476ad2279..000000000000 --- a/drivers/usb/gadget/fsl_tegra_udc.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Description: - * Helper functions to support the tegra USB controller - * - * 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. - */ -#include <linux/fsl_devices.h> -#include <linux/platform_device.h> -#include <linux/err.h> -#include <linux/io.h> -#include <mach/usb_phy.h> - -static struct tegra_usb_phy *phy; -static struct clk *udc_clk; -static struct clk *emc_clk; -static struct clk *sclk_clk; -static void *udc_base; - -int fsl_udc_clk_init(struct platform_device *pdev) -{ - struct resource *res; - int err; - int instance; - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - - - udc_clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(udc_clk)) { - dev_err(&pdev->dev, "Can't get udc clock\n"); - return PTR_ERR(udc_clk); - } - - clk_enable(udc_clk); - - sclk_clk = clk_get(&pdev->dev, "sclk"); - if (IS_ERR(sclk_clk)) { - dev_err(&pdev->dev, "Can't get sclk clock\n"); - err = PTR_ERR(sclk_clk); - goto err_sclk; - } - - clk_set_rate(sclk_clk, 80000000); - clk_enable(sclk_clk); - - emc_clk = clk_get(&pdev->dev, "emc"); - if (IS_ERR(emc_clk)) { - dev_err(&pdev->dev, "Can't get emc clock\n"); - err = PTR_ERR(emc_clk); - goto err_emc; - } - - clk_enable(emc_clk); -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* Set DDR busy hints to 150MHz. For Tegra 2x SOC, DDR rate is half of EMC rate */ - clk_set_rate(emc_clk, 300000000); -#else - /* Set DDR busy hints to 100MHz. For Tegra 3x SOC DDR rate equals to EMC rate */ - clk_set_rate(emc_clk, 100000000); -#endif - - /* we have to remap the registers ourselves as fsl_udc does not - * export them for us. - */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - err = -ENXIO; - goto err0; - } - udc_base = ioremap(res->start, resource_size(res)); - if (!udc_base) { - err = -ENOMEM; - goto err0; - } - - instance = pdev->id; - if (instance == -1) - instance = 0; - - phy = tegra_usb_phy_open(instance, udc_base, pdata->phy_config, - TEGRA_USB_PHY_MODE_DEVICE, pdata->usb_phy_type); - if (IS_ERR(phy)) { - dev_err(&pdev->dev, "Can't open phy\n"); - err = PTR_ERR(phy); - goto err1; - } - tegra_usb_phy_power_on(phy, true); - - return 0; -err1: - iounmap(udc_base); -err0: - clk_disable(emc_clk); - clk_put(emc_clk); -err_emc: - clk_disable(sclk_clk); - clk_put(sclk_clk); -err_sclk: - clk_disable(udc_clk); - clk_put(udc_clk); - return err; -} - -void fsl_udc_clk_finalize(struct platform_device *pdev) -{ -} - -void fsl_udc_clk_release(void) -{ - tegra_usb_phy_close(phy); - - iounmap(udc_base); - - clk_disable(udc_clk); - clk_put(udc_clk); - - clk_disable(sclk_clk); - clk_put(sclk_clk); - - clk_disable(emc_clk); - clk_put(emc_clk); -} - -void fsl_udc_clk_suspend(bool is_dpd) -{ - tegra_usb_phy_power_off(phy, is_dpd); - clk_disable(udc_clk); - clk_disable(sclk_clk); - clk_disable(emc_clk); -} - -void fsl_udc_clk_resume(bool is_dpd) -{ - clk_enable(emc_clk); - clk_enable(sclk_clk); - clk_enable(udc_clk); - tegra_usb_phy_power_on(phy, is_dpd); -} - -void fsl_udc_clk_enable(void) -{ - clk_enable(udc_clk); -} - -void fsl_udc_clk_disable(void) -{ - clk_disable(udc_clk); -} - -bool fsl_udc_charger_detect(void) -{ - return tegra_usb_phy_charger_detect(phy); -} - -void fsl_udc_dtd_prepare(void) -{ - /* When we are programming two DTDs very close to each other, - * the second DTD is being prefetched before it is actually written - * to DDR. To prevent this, we disable prefetcher before programming - * any new DTD and re-enable it before priming endpoint. - */ - tegra_usb_phy_memory_prefetch_off(phy); -} - -void fsl_udc_ep_barrier(void) -{ - tegra_usb_phy_memory_prefetch_on(phy); -} diff --git a/drivers/usb/gadget/tegra_udc.c b/drivers/usb/gadget/tegra_udc.c index 978db7ece1de..f978f0f2d1e7 100644 --- a/drivers/usb/gadget/tegra_udc.c +++ b/drivers/usb/gadget/tegra_udc.c @@ -37,7 +37,6 @@ #include <linux/workqueue.h> #include <linux/err.h> #include <linux/io.h> -#include <linux/fsl_devices.h> /* check this */ #include <asm/byteorder.h> #include <asm/io.h> @@ -50,14 +49,10 @@ #include "tegra_udc.h" -/* #define IS_NEW_PHY_DRIVER 1 */ - -#ifndef IS_NEW_PHY_DRIVER -#include "fsl_tegra_udc.c" -#endif #define DRIVER_DESC "Nvidia Tegra High-Speed USB SOC \ - Device Controller driver" + Device Controller driver" + #define DRIVER_AUTHOR "Venkat Moganty/Rakesh Bodla" #define DRIVER_VERSION "Apr 30, 2012" #define USB1_PREFETCH_ID 6 @@ -73,7 +68,6 @@ & USB_DIR_IN) == USB_DIR_IN) - static const char driver_name[] = "tegra-udc"; static const char driver_desc[] = DRIVER_DESC; @@ -136,7 +130,7 @@ static void done(struct tegra_ep *ep, struct tegra_req *req, int status) unsigned char stopped = ep->stopped; struct ep_td_struct *curr_td, *next_td; int j; - + BUG_ON(!(in_irq() || irqs_disabled())); udc = (struct tegra_udc *)ep->udc; /* Removed the req from tegra_ep->queue */ list_del_init(&req->queue); @@ -186,19 +180,20 @@ static void done(struct tegra_ep *ep, struct tegra_req *req, int status) } #endif - spin_unlock(&ep->udc->lock); /* complete() is from gadget layer, * eg fsg->bulk_in_complete() */ - if (req->req.complete) + if (req->req.complete) { + spin_unlock(&ep->udc->lock); req->req.complete(&ep->ep, &req->req); + spin_lock(&ep->udc->lock); + } - spin_lock(&ep->udc->lock); ep->stopped = stopped; } /* * nuke(): delete all requests related to this ep - * called with spinlock held + * Must be called with spinlock held and interrupt disabled */ static void nuke(struct tegra_ep *ep, int status) { @@ -733,11 +728,7 @@ static void tegra_queue_td(struct tegra_ep *ep, struct tegra_req *req) | EP_QUEUE_HEAD_STATUS_HALT)); dQH->size_ioc_int_sts &= temp; -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_memory_prefetch_on(udc->phy); -#else - fsl_udc_ep_barrier(); -#endif /* Ensure that updates to the QH will occur before priming. */ wmb(); @@ -828,11 +819,7 @@ static int tegra_req_to_dtd(struct tegra_req *req, gfp_t gfp_flags) struct ep_td_struct *last_dtd = NULL, *dtd; dma_addr_t dma; -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_memory_prefetch_off(the_udc->phy); -#else - fsl_udc_dtd_prepare(); -#endif do { dtd = tegra_build_dtd(req, &count, &dma, &is_last, gfp_flags); @@ -1229,20 +1216,20 @@ static int tegra_set_selfpowered(struct usb_gadget *gadget, int is_on) } /** - * Notify controller that VBUS is powered, Called by whatever + * Notify controller that VBUS is powered, called by whatever * detects VBUS sessions */ static int tegra_vbus_session(struct usb_gadget *gadget, int is_active) { struct tegra_udc *udc = container_of(gadget, struct tegra_udc, gadget); - + unsigned long flags; DBG("%s(%d) turn VBUS state from %s to %s", __func__, __LINE__, udc->vbus_active ? "on" : "off", is_active ? "on" : "off"); if (udc->vbus_active && !is_active) { /* If cable disconnected, cancel any delayed work */ cancel_delayed_work(&udc->work); - spin_lock(&udc->lock); + spin_lock_irqsave(&udc->lock, flags); /* reset all internal Queues and inform client driver */ reset_queues(udc); /* stop the controller and turn off the clocks */ @@ -1250,23 +1237,15 @@ static int tegra_vbus_session(struct usb_gadget *gadget, int is_active) dr_controller_reset(udc); udc->vbus_active = 0; udc->usb_state = USB_STATE_DEFAULT; - spin_unlock(&udc->lock); -#ifdef IS_NEW_PHY_DRIVER + spin_unlock_irqrestore(&udc->lock,flags); tegra_usb_phy_power_off(udc->phy); -#else - fsl_udc_clk_suspend(false); -#endif if (udc->vbus_reg) { /* set the current limit to 0mA */ regulator_set_current_limit( udc->vbus_reg, 0, 0); } } else if (!udc->vbus_active && is_active) { -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_power_on(udc->phy); -#else - fsl_udc_clk_resume(false); -#endif /* setup the controller in the device mode */ dr_controller_setup(udc); /* setup EP0 for setup packet */ @@ -1348,12 +1327,7 @@ static void tegra_udc_release(struct device *dev) struct tegra_udc *udc = platform_get_drvdata(pdev); complete(udc->done); -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_close(udc->phy); -#else - fsl_udc_clk_suspend(false); -#endif - kfree(udc); } @@ -2109,15 +2083,18 @@ static void tegra_udc_irq_work(struct work_struct *irq_work) { struct tegra_udc *udc = container_of(irq_work, struct tegra_udc, irq_work); + DBG("%s(%d) BEGIN\n", __func__, __LINE__); /* Check whether cable is connected*/ if (vbus_enabled(udc)) tegra_vbus_session(&udc->gadget, 1); else tegra_vbus_session(&udc->gadget, 0); + + DBG("%s(%d) END\n", __func__, __LINE__); } -/* +/** * If VBUS is detected and setup packet is not received in 100ms then * work thread starts and checks for the USB charger detection. */ @@ -2127,11 +2104,7 @@ static void tegra_udc_charger_detect_work(struct work_struct *work) DBG("%s(%d) BEGIN\n", __func__, __LINE__); /* check for the platform charger detection */ -#ifdef IS_NEW_PHY_DRIVER if (tegra_usb_phy_charger_detected(udc->phy)) { -#else - if (fsl_udc_charger_detect()) { -#endif printk(KERN_INFO "USB compliant charger detected\n"); /* check udc regulator is available for drawing vbus current*/ if (udc->vbus_reg) { @@ -2271,8 +2244,6 @@ static int tegra_udc_start(struct usb_gadget_driver *driver, if (!udc) return -ENODEV; - - if (!driver || (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH) || !bind || !driver->disconnect @@ -2404,7 +2375,7 @@ static int tegra_udc_setup_qh(struct tegra_udc *udc) /* FIXME: tegra_alloc_request() ignores ep argument */ udc->status_req = container_of(tegra_alloc_request(NULL, GFP_KERNEL), struct tegra_req, req); - /* allocate a small amount of memory to get valid address */ + /* Allocate a small amount of memory to get valid address */ udc->status_req->req.buf = dma_alloc_coherent(&udc->pdev->dev, STATUS_BUFFER_SIZE, &udc->status_req->req.dma, GFP_KERNEL); @@ -2552,7 +2523,6 @@ static int __init tegra_udc_probe(struct platform_device *pdev) goto err_iounmap; } -#ifdef IS_NEW_PHY_DRIVER udc->phy = tegra_usb_phy_open(pdev); if (IS_ERR(udc->phy)) { dev_err(&pdev->dev, "failed to open USB phy\n"); @@ -2571,23 +2541,10 @@ static int __init tegra_udc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to init the phy\n"); goto err_phy; } -#else - /* Initialize USB clocks */ - fsl_udc_clk_init(pdev); -#endif spin_lock_init(&udc->lock); udc->stopped = 1; udc->pdev = pdev; -#ifdef IS_NEW_PHY_DRIVER udc->has_hostpc = tegra_usb_phy_has_hostpc(udc->phy) ? 1 : 0; -#else - #ifdef CONFIG_ARCH_TEGRA_2x_SOC - udc->has_hostpc = 0; - #else - udc->has_hostpc = 1; - #endif -#endif - platform_set_drvdata(pdev, udc); /* Initialize the udc structure including QH members */ @@ -2597,7 +2554,7 @@ static int __init tegra_udc_probe(struct platform_device *pdev) goto err_phy; } - /* initialize usb hw reg except for regs for EP, + /* Initialize usb hw reg except for regs for EP, * leave usbintr reg untouched */ err = dr_controller_setup(udc); if (err) { @@ -2617,7 +2574,7 @@ static int __init tegra_udc_probe(struct platform_device *pdev) goto err_unregister; } - /* use dma_pool for TD management */ + /* Use dma_pool for TD management */ udc->td_pool = dma_pool_create("udc_td", &pdev->dev, sizeof(struct ep_td_struct), DTD_ALIGNMENT, UDC_DMA_BOUNDARY); @@ -2638,9 +2595,9 @@ static int __init tegra_udc_probe(struct platform_device *pdev) PM_QOS_DEFAULT_VALUE); #endif - /* create a work for controlling clocks to the phy if otg is disabled */ + /* Create work for controlling clocks to the phy if otg is disabled */ INIT_WORK(&udc->irq_work, tegra_udc_irq_work); - /* create a delayed work for detecting the USB charger */ + /* Create a delayed work for detecting the USB charger */ INIT_DELAYED_WORK(&udc->work, tegra_udc_charger_detect_work); INIT_WORK(&udc->charger_work, tegra_udc_set_current_limit_work); @@ -2654,35 +2611,21 @@ static int __init tegra_udc_probe(struct platform_device *pdev) } #ifdef CONFIG_USB_OTG_UTILS - -#ifdef IS_NEW_PHY_DRIVER if (tegra_usb_phy_otg_supported(udc->phy)) udc->transceiver = otg_get_transceiver(); -#else - udc->transceiver = otg_get_transceiver(); -#endif if (udc->transceiver) { dr_controller_stop(udc); dr_controller_reset(udc); -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_power_off(udc->phy); -#else - fsl_udc_clk_suspend(false); -#endif udc->vbus_active = 0; udc->usb_state = USB_STATE_DEFAULT; otg_set_peripheral(udc->transceiver, &udc->gadget); } #else /* Power down the phy if cable is not connected */ - if (!vbus_enabled()) { -#ifdef IS_NEW_PHY_DRIVER + if (!vbus_enabled()) tegra_usb_phy_power_off(udc->phy); -#else - fsl_udc_clk_suspend(false); -#endif - } #endif DBG("%s(%d) END\n", __func__, __LINE__); @@ -2694,15 +2637,11 @@ err_del_udc: err_unregister: device_unregister(&udc->gadget.dev); -#ifdef IS_NEW_PHY_DRIVER err_phy: tegra_usb_phy_close(udc->phy); err_irq: free_irq(udc->irq, udc); -#else -err_phy: -#endif err_iounmap: iounmap(udc->regs); @@ -2743,9 +2682,6 @@ static int __exit tegra_udc_remove(struct platform_device *pdev) if (udc->transceiver) otg_set_peripheral(udc->transceiver, NULL); -#ifndef IS_NEW_PHY_DRIVER - fsl_udc_clk_release(); -#endif /* Free allocated memory */ dma_free_coherent(&pdev->dev, STATUS_BUFFER_SIZE, @@ -2760,7 +2696,7 @@ static int __exit tegra_udc_remove(struct platform_device *pdev) release_mem_region(res->start, res->end - res->start + 1); device_unregister(&udc->gadget.dev); - /* free udc --wait for the release() finished */ + /* Free udc -- wait for the release() finished */ wait_for_completion(&done); return 0; @@ -2769,30 +2705,27 @@ static int __exit tegra_udc_remove(struct platform_device *pdev) static int tegra_udc_suspend(struct platform_device *pdev, pm_message_t state) { struct tegra_udc *udc = platform_get_drvdata(pdev); + unsigned long flags; DBG("%s(%d) BEGIN\n", __func__, __LINE__); - /* if it controller is in otg mode, return */ + /* If the controller is in otg mode, return */ if (udc->transceiver) return 0; if (udc->vbus_active) { - spin_lock(&udc->lock); + spin_lock_irqsave(&udc->lock, flags); /* Reset all internal Queues and inform client driver */ reset_queues(udc); udc->vbus_active = 0; udc->usb_state = USB_STATE_DEFAULT; - spin_unlock(&udc->lock); + spin_unlock_irqrestore(&udc->lock, flags); } - /* stop the controller and turn off the clocks */ + /* Stop the controller and turn off the clocks */ dr_controller_stop(udc); if (udc->transceiver) udc->transceiver->state = OTG_STATE_UNDEFINED; -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_power_off(udc->phy); -#else - fsl_udc_clk_suspend(true); -#endif DBG("%s(%d) END\n", __func__, __LINE__); return 0; @@ -2803,36 +2736,18 @@ static int tegra_udc_resume(struct platform_device *pdev) struct tegra_udc *udc = platform_get_drvdata(pdev); DBG("%s(%d) BEGIN\n", __func__, __LINE__); -#ifndef IS_NEW_PHY_DRIVER -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* Work around to get UTMIP_OTGPD, UTMIP_BIASPD values correctly */ - fsl_udc_clk_resume(true); - fsl_udc_clk_suspend(true); -#endif -#endif - if (udc->transceiver) return 0; -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_power_on(udc->phy); -#else - fsl_udc_clk_resume(true); - fsl_udc_clk_resume(true); -#endif tegra_udc_restart(udc); /* Power down the phy if cable is not connected */ if (!vbus_enabled(udc)) { udc->vbus_active = 0; -#ifdef IS_NEW_PHY_DRIVER tegra_usb_phy_power_off(udc->phy); -#else - fsl_udc_clk_suspend(true); -#endif } - DBG("%s(%d) END\n", __func__, __LINE__); return 0; } diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 25ed607aab9a..bf171c180987 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -145,7 +145,7 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, spin_lock_irqsave(&ehci->lock, flags); /* clear phy low-power mode before changing wakeup flags */ - if (ehci->has_hostpc) { + if (ehci->has_hostpc && !ehci->broken_hostpc_phcd) { port = HCS_N_PORTS(ehci->hcs_params); while (port--) { u32 __iomem *hostpc_reg; @@ -181,7 +181,7 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, } /* enter phy low-power mode again */ - if (ehci->has_hostpc) { + if (ehci->has_hostpc && !ehci->broken_hostpc_phcd) { port = HCS_N_PORTS(ehci->hcs_params); while (port--) { u32 __iomem *hostpc_reg; @@ -285,7 +285,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) } } #ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (changed && ehci->has_hostpc) { + if (changed && ehci->has_hostpc && !ehci->broken_hostpc_phcd) { spin_unlock_irq(&ehci->lock); msleep(5); /* 5 ms for HCD to enter low-power mode */ spin_lock_irq(&ehci->lock); @@ -389,7 +389,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) spin_lock_irq(&ehci->lock); /* clear phy low-power mode before resume */ - if (ehci->bus_suspended && ehci->has_hostpc) { + if (ehci->bus_suspended && ehci->has_hostpc && !ehci->broken_hostpc_phcd) { i = HCS_N_PORTS(ehci->hcs_params); while (i--) { if (test_bit(i, &ehci->bus_suspended)) { @@ -731,7 +731,7 @@ static int ehci_hub_control ( goto error; /* clear phy low-power mode before resume */ - if (hostpc_reg) { + if (hostpc_reg && !ehci->broken_hostpc_phcd) { temp1 = ehci_readl(ehci, hostpc_reg); ehci_writel(ehci, temp1 & ~HOSTPC_PHCD, hostpc_reg); @@ -979,7 +979,7 @@ static int ehci_hub_control ( temp &= ~PORT_WKCONN_E; temp |= PORT_WKDISC_E | PORT_WKOC_E; ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); - if (hostpc_reg) { + if (hostpc_reg && !ehci->broken_hostpc_phcd) { spin_unlock_irqrestore(&ehci->lock, flags); msleep(5);/* 5ms for HCD enter low pwr mode */ spin_lock_irqsave(&ehci->lock, flags); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 4e7277b2b889..c5fa8160bffe 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -2,7 +2,7 @@ * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs * * Copyright (C) 2010 Google, Inc. - * Copyright (C) 2009 - 2012 NVIDIA Corporation + * Copyright (C) 2009 - 2011 NVIDIA Corporation * * 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 @@ -16,7 +16,6 @@ * */ -#include <linux/clk.h> #include <linux/platform_device.h> #include <linux/platform_data/tegra_usb.h> #include <linux/irq.h> @@ -24,191 +23,157 @@ #include <mach/usb_phy.h> #include <mach/iomap.h> -#define TEGRA_USB_PORTSC_PHCD (1 << 23) - -#define TEGRA_USB_SUSP_CTRL_OFFSET 0x400 -#define TEGRA_USB_SUSP_CLR (1 << 5) -#define TEGRA_USB_PHY_CLK_VALID (1 << 7) -#define TEGRA_USB_SRT (1 << 25) -#define TEGRA_USB_PHY_CLK_VALID_INT_ENB (1 << 9) -#define TEGRA_USB_PHY_CLK_VALID_INT_STS (1 << 8) - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC -#define TEGRA_USB_PORTSC1_OFFSET 0x184 +#if 0 +#define EHCI_DBG(stuff...) pr_info("ehci-tegra: " stuff) #else -#define TEGRA_USB_PORTSC1_OFFSET 0x174 +#define EHCI_DBG(stuff...) do {} while (0) #endif -#define TEGRA_USB_PORTSC1_WKCN (1 << 20) -#define TEGRA_LVL2_CLK_GATE_OVRB 0xfc -#define TEGRA_USB2_CLK_OVR_ON (1 << 10) +static const char driver_name[] = "tegra-ehci"; #define TEGRA_USB_DMA_ALIGN 32 -#define STS_SRI (1<<7) /* SOF Recieved */ - -#define HOSTPC_REG_OFFSET 0x1b4 - -#define HOSTPC1_DEVLC_STS (1 << 28) -#define HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29) - -#define USB1_PREFETCH_ID 6 -#define USB2_PREFETCH_ID 18 -#define USB3_PREFETCH_ID 17 - struct tegra_ehci_hcd { struct ehci_hcd *ehci; struct tegra_usb_phy *phy; - struct clk *clk; - struct clk *emc_clk; - struct clk *sclk_clk; +#ifdef CONFIG_USB_OTG_UTILS struct otg_transceiver *transceiver; - int host_resumed; - int bus_suspended; - int port_resuming; - int power_down_on_bus_suspend; - int default_enable; - enum tegra_usb_phy_port_speed port_speed; - struct work_struct clk_timer_work; - struct timer_list clk_timer; - bool clock_enabled; - bool timer_event; - struct mutex tegra_ehci_hcd_mutex; +#endif + struct mutex sync_lock; + bool port_resuming; unsigned int irq; bool bus_suspended_fail; }; -static void tegra_ehci_power_up(struct usb_hcd *hcd, bool is_dpd) +struct dma_align_buffer { + void *kmalloc_ptr; + void *old_xfer_buffer; + u8 data[0]; +}; + +static void free_align_buffer(struct urb *urb) { - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct dma_align_buffer *temp = container_of(urb->transfer_buffer, + struct dma_align_buffer, data); - if (!tegra->default_enable) - clk_enable(tegra->clk); - tegra_usb_phy_power_on(tegra->phy, is_dpd); - tegra->host_resumed = 1; + if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) + return; + + /* In transaction, DMA from Device */ + if (usb_urb_dir_in(urb)) + memcpy(temp->old_xfer_buffer, temp->data, + urb->transfer_buffer_length); + + urb->transfer_buffer = temp->old_xfer_buffer; + urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; + kfree(temp->kmalloc_ptr); } -static void tegra_ehci_power_down(struct usb_hcd *hcd, bool is_dpd) +static int alloc_align_buffer(struct urb *urb, gfp_t mem_flags) { - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct dma_align_buffer *temp, *kmalloc_ptr; + size_t kmalloc_size; + + if (urb->num_sgs || urb->sg || + urb->transfer_buffer_length == 0 || + !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1))) + return 0; - tegra->host_resumed = 0; - tegra_usb_phy_power_off(tegra->phy, is_dpd); - if (!tegra->default_enable) - clk_disable(tegra->clk); + /* Allocate a buffer with enough padding for alignment */ + kmalloc_size = urb->transfer_buffer_length + + sizeof(struct dma_align_buffer) + TEGRA_USB_DMA_ALIGN - 1; + kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); + + if (!kmalloc_ptr) + return -ENOMEM; + + /* Position our struct dma_align_buffer such that data is aligned */ + temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1; + temp->kmalloc_ptr = kmalloc_ptr; + temp->old_xfer_buffer = urb->transfer_buffer; + /* OUT transaction, DMA to Device */ + if (!usb_urb_dir_in(urb)) + memcpy(temp->data, urb->transfer_buffer, + urb->transfer_buffer_length); + + urb->transfer_buffer = temp->data; + urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; + + return 0; } -static int tegra_ehci_internal_port_reset( - struct ehci_hcd *ehci, - u32 __iomem *portsc_reg -) +static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, + struct urb *urb, gfp_t mem_flags) { - u32 temp; - unsigned long flags; - int retval = 0; - int i, tries; - u32 saved_usbintr; - - spin_lock_irqsave(&ehci->lock, flags); - saved_usbintr = ehci_readl(ehci, &ehci->regs->intr_enable); - /* disable USB interrupt */ - ehci_writel(ehci, 0, &ehci->regs->intr_enable); - spin_unlock_irqrestore(&ehci->lock, flags); - - /* - * Here we have to do Port Reset at most twice for - * Port Enable bit to be set. - */ - for (i = 0; i < 2; i++) { - temp = ehci_readl(ehci, portsc_reg); - temp |= PORT_RESET; - ehci_writel(ehci, temp, portsc_reg); - mdelay(10); - temp &= ~PORT_RESET; - ehci_writel(ehci, temp, portsc_reg); - mdelay(1); - tries = 100; - do { - mdelay(1); - /* - * Up to this point, Port Enable bit is - * expected to be set after 2 ms waiting. - * USB1 usually takes extra 45 ms, for safety, - * we take 100 ms as timeout. - */ - temp = ehci_readl(ehci, portsc_reg); - } while (!(temp & PORT_PE) && tries--); - if (temp & PORT_PE) - break; + int ret; + + ret = alloc_align_buffer(urb, mem_flags); + if (ret) + return ret; + + ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); + + /* Control packets over dma */ + if (urb->setup_dma) + dma_sync_single_for_device(hcd->self.controller, + urb->setup_dma, sizeof(struct usb_ctrlrequest), + DMA_TO_DEVICE); + + /* urb buffers over dma */ + if (urb->transfer_dma) { + enum dma_data_direction dir; + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + dma_sync_single_for_device(hcd->self.controller, + urb->transfer_dma, urb->transfer_buffer_length, dir); } - if (i == 2) - retval = -ETIMEDOUT; - - /* - * Clear Connect Status Change bit if it's set. - * We can't clear PORT_PEC. It will also cause PORT_PE to be cleared. - */ - if (temp & PORT_CSC) - ehci_writel(ehci, PORT_CSC, portsc_reg); - - /* - * Write to clear any interrupt status bits that might be set - * during port reset. - */ - temp = ehci_readl(ehci, &ehci->regs->status); - ehci_writel(ehci, temp, &ehci->regs->status); - - /* restore original interrupt enable bits */ - ehci_writel(ehci, saved_usbintr, &ehci->regs->intr_enable); - return retval; + + if (ret) + free_align_buffer(urb); + + return ret; } -static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) +static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, + struct urb *urb) +{ + usb_hcd_unmap_urb_for_dma(hcd, urb); + free_align_buffer(urb); + + if (urb->transfer_dma) { + enum dma_data_direction dir; + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + if (dir == DMA_FROM_DEVICE) + dma_sync_single_for_cpu(hcd->self.controller, + urb->transfer_dma, urb->transfer_buffer_length, + DMA_FROM_DEVICE); + } +} + +static irqreturn_t tegra_ehci_irq(struct usb_hcd *hcd) { - struct ehci_hcd *ehci = hcd_to_ehci (hcd); - struct ehci_regs __iomem *hw = ehci->regs; struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - u32 val; + struct ehci_hcd *ehci = hcd_to_ehci(hcd); irqreturn_t irq_status; bool pmc_remote_wakeup = false; - /* Fence read for coherency of AHB master intiated writes */ - if (tegra->phy->instance == 0) - readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); - else if (tegra->phy->instance == 1) - readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); - else if (tegra->phy->instance == 2) - readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); - - if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && - (tegra->ehci->has_hostpc)) { - /* check if there is any remote wake event */ - if (tegra_usb_phy_is_remotewake_detected(tegra->phy)) { - pmc_remote_wakeup = true; - spin_lock (&ehci->lock); - usb_hcd_resume_root_hub(hcd); - spin_unlock (&ehci->lock); - } - } - if (tegra->phy->hotplug) { - spin_lock(&ehci->lock); - val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); - if ((val & TEGRA_USB_PHY_CLK_VALID_INT_STS)) { - val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB | - TEGRA_USB_PHY_CLK_VALID_INT_STS; - writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); - - val = readl(&hw->status); - if (!(val & STS_PCD)) { - spin_unlock(&ehci->lock); - return 0; - } - val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET); - val &= ~(TEGRA_USB_PORTSC1_WKCN | PORT_RWC_BITS); - writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); - } + spin_lock(&ehci->lock); + irq_status = tegra_usb_phy_irq(tegra->phy); + if (irq_status == IRQ_NONE) { spin_unlock(&ehci->lock); + return irq_status; + } + if (tegra_usb_phy_remote_wakeup(tegra->phy)) { + ehci_info(ehci, "remote wakeup detected\n"); + pmc_remote_wakeup = true; + usb_hcd_resume_root_hub(hcd); } + spin_unlock(&ehci->lock); + + EHCI_DBG("%s() cmd = 0x%x, int_sts = 0x%x, portsc = 0x%x\n", __func__, + ehci_readl(ehci, &ehci->regs->command), + ehci_readl(ehci, &ehci->regs->status), + ehci_readl(ehci, &ehci->regs->port_status[0])); irq_status = ehci_irq(hcd); @@ -218,61 +183,37 @@ static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) if (ehci->controller_remote_wakeup) { ehci->controller_remote_wakeup = false; - /* disable interrupts */ - ehci_writel(ehci, 0, &ehci->regs->intr_enable); - tegra_usb_phy_preresume(tegra->phy, true); + tegra_usb_phy_pre_resume(tegra->phy, true); tegra->port_resuming = 1; } return irq_status; } + static int tegra_ehci_hub_control( struct usb_hcd *hcd, - u16 typeReq, - u16 wValue, - u16 wIndex, - char *buf, - u16 wLength + u16 typeReq, + u16 wValue, + u16 wIndex, + char *buf, + u16 wLength ) { - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int ports = HCS_N_PORTS(ehci->hcs_params); - u32 temp, status, cmd_run; - u32 __iomem *status_reg; - u32 usbsts_reg; - + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); unsigned long flags; - int retval = 0; - unsigned selector; - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - bool hsic = false; + int retval = 0; + u32 __iomem *status_reg; - mutex_lock(&tegra->tegra_ehci_hcd_mutex); - if (!tegra->host_resumed) { + if (!tegra_usb_phy_hw_accessible(tegra->phy)) { if (buf) - memset (buf, 0, wLength); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); + memset(buf, 0, wLength); return retval; } - hsic = (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC); - - status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; - - spin_lock_irqsave(&ehci->lock, flags); - - /* - * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits - * that are write on clear, by writing back the register read value, so - * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits - */ - if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) { - temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS; - ehci_writel(ehci, temp & ~PORT_PE, status_reg); - goto done; - } else if (typeReq == GetPortStatus) { - temp = ehci_readl(ehci, status_reg); - /* check port is in resume state */ + /* Do tegra phy specific actions based on the type request */ + switch (typeReq) { + case GetPortStatus: if (tegra->port_resuming) { int delay = ehci->reset_done[wIndex-1] - jiffies; /* Sometimes it seems we get called too soon... In that case, wait.*/ @@ -280,501 +221,68 @@ static int tegra_ehci_hub_control( ehci_dbg(ehci, "GetPortStatus called too soon, waiting %dms...\n", delay); mdelay(jiffies_to_msecs(delay)); } + status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; /* Ensure the port PORT_SUSPEND and PORT_RESUME has cleared */ if (handshake(ehci, status_reg, (PORT_SUSPEND | PORT_RESUME), 0, 25000)) { pr_err("%s: timeout waiting for SUSPEND to clear\n", __func__); } + tegra_usb_phy_post_resume(tegra->phy); tegra->port_resuming = 0; - tegra_usb_phy_postresume(tegra->phy, false); - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { + /* If run bit is not set by now enable it */ + if (ehci->command & CMD_RUN) { ehci->command |= CMD_RUN; - cmd_run = ehci_readl(ehci, &ehci->regs->command); - cmd_run |= CMD_RUN; - /* - * ehci run bit is disabled to avoid SOF. - * 2LS WAR is executed by now enable the run bit. - */ - ehci_writel(ehci, cmd_run, &ehci->regs->command); - /* Now we can safely re-enable irqs */ - ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); + ehci_writel(ehci, ehci->command, &ehci->regs->command); } + /* Now we can safely re-enable irqs */ + ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); } - - } else if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { - temp = ehci_readl(ehci, status_reg); - if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { - retval = -EPIPE; - goto done; - } - - temp &= ~PORT_WKCONN_E; - temp |= PORT_WKDISC_E | PORT_WKOC_E; - ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); - - /* Need a 4ms delay before the controller goes to suspend */ - mdelay(4); - - /* - * If a transaction is in progress, there may be a delay in - * suspending the port. Poll until the port is suspended. - */ - if (handshake(ehci, status_reg, PORT_SUSPEND, - PORT_SUSPEND, 5000)) - pr_err("%s: timeout waiting for SUSPEND\n", __func__); - - set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); - /* - * If RUN bit is disabled interrupt is not generated after suspend. - * This change on T20 will allow ASE interrupt generated after suspend - * which will unlink the qheads. - */ -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - /* Disable RUN bit. */ - ehci->command &= ~CMD_RUN; - cmd_run = ehci_readl(ehci, &ehci->regs->command); - cmd_run &= ~CMD_RUN; - ehci_writel(ehci, cmd_run, &ehci->regs->command); - if (handshake (ehci, &ehci->regs->status, - STS_HALT, STS_HALT, 16 * 125)) - pr_err("%s() timeout waiting for STS_HALT\n", __func__); + break; + case ClearPortFeature: + if (wValue == USB_PORT_FEAT_SUSPEND) { + tegra_usb_phy_pre_resume(tegra->phy, false); + tegra->port_resuming = 1; } -#endif - tegra_usb_phy_postsuspend(tegra->phy, false); - - goto done; - } - - /* For USB1 port we need to issue Port Reset twice internally */ - if (tegra->phy->instance == 0 && - (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) { - spin_unlock_irqrestore(&ehci->lock, flags); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return tegra_ehci_internal_port_reset(ehci, status_reg); + break; } - /* - * Tegra host controller will time the resume operation to clear the bit - * when the port control state switches to HS or FS Idle. This behavior - * is different from EHCI where the host controller driver is required - * to set this bit to a zero after the resume duration is timed in the - * driver. - */ - else if (typeReq == ClearPortFeature && - wValue == USB_PORT_FEAT_SUSPEND) { - temp = ehci_readl(ehci, status_reg); - if ((temp & PORT_RESET) || !(temp & PORT_PE)) { - retval = -EPIPE; - goto done; - } - - if (!(temp & PORT_SUSPEND)) - goto done; - - tegra->port_resuming = 1; - - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - /* disable interrupts */ - ehci_writel(ehci, 0, &ehci->regs->intr_enable); - /* Disable RUN bit. */ - ehci->command &= ~CMD_RUN; - cmd_run = ehci_readl(ehci, &ehci->regs->command); - cmd_run &= ~CMD_RUN; - ehci_writel(ehci, cmd_run, &ehci->regs->command); - if (handshake (ehci, &ehci->regs->status, - STS_HALT, STS_HALT, 16 * 125)) - pr_err("%s() timeout waiting for STS_HALT\n", __func__); - } - - /* Disable disconnect detection during port resume */ - tegra_usb_phy_preresume(tegra->phy, false); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - if (tegra->phy->usb_phy_type != TEGRA_USB_PHY_TYPE_UTMIP) { -#endif - ehci_dbg(ehci, "%s:USBSTS = 0x%x", __func__, - ehci_readl(ehci, &ehci->regs->status)); - usbsts_reg = ehci_readl(ehci, &ehci->regs->status); - ehci_writel(ehci, usbsts_reg, &ehci->regs->status); - usbsts_reg = ehci_readl(ehci, &ehci->regs->status); - udelay(20); - - if (handshake(ehci, &ehci->regs->status, STS_SRI, STS_SRI, 2000)) - pr_err("%s: timeout set for STS_SRI\n", __func__); - - usbsts_reg = ehci_readl(ehci, &ehci->regs->status); - ehci_writel(ehci, usbsts_reg, &ehci->regs->status); - - if (handshake(ehci, &ehci->regs->status, STS_SRI, 0, 2000)) - pr_err("%s: timeout clear STS_SRI\n", __func__); - - if (handshake(ehci, &ehci->regs->status, STS_SRI, STS_SRI, 2000)) - pr_err("%s: timeout set STS_SRI\n", __func__); - - udelay(20); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - } -#endif - temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); - /* start resume signaling */ - ehci_writel(ehci, temp | PORT_RESUME, status_reg); - - ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); - /* whoever resumes must GetPortStatus to complete it!! */ - goto done; - } + /* handle ehci hub control request */ + retval = ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); - /* Handle port reset here */ - if ((hsic) && (typeReq == SetPortFeature) && - ((wValue == USB_PORT_FEAT_RESET) || (wValue == USB_PORT_FEAT_POWER))) { - selector = wIndex >> 8; - wIndex &= 0xff; - if (!wIndex || wIndex > ports) { - retval = -EPIPE; - goto done; - } - wIndex--; - status = 0; - temp = ehci_readl(ehci, status_reg); - if (temp & PORT_OWNER) - goto done; - temp &= ~PORT_RWC_BITS; - - switch (wValue) { - case USB_PORT_FEAT_RESET: - { - if (temp & PORT_RESUME) { - retval = -EPIPE; - goto done; - } - /* line status bits may report this as low speed, - * which can be fine if this root hub has a - * transaction translator built in. - */ - if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT - && !ehci_is_TDI(ehci) && PORT_USB11 (temp)) { - ehci_dbg (ehci, "port %d low speed --> companion\n", wIndex + 1); - temp |= PORT_OWNER; - ehci_writel(ehci, temp, status_reg); - } else { - ehci_vdbg(ehci, "port %d reset\n", wIndex + 1); - temp &= ~PORT_PE; - /* - * caller must wait, then call GetPortStatus - * usb 2.0 spec says 50 ms resets on root - */ - ehci->reset_done[wIndex] = jiffies + msecs_to_jiffies(50); - ehci_writel(ehci, temp, status_reg); - if (hsic && (wIndex == 0)) + /* do tegra phy specific actions based on the type request */ + if (!retval) { + switch (typeReq) { + case SetPortFeature: + if (wValue == USB_PORT_FEAT_SUSPEND) { + /* Need a 4ms delay for controller to suspend */ + mdelay(4); + tegra_usb_phy_post_suspend(tegra->phy); + } else if (wValue == USB_PORT_FEAT_RESET) { + if (ehci->reset_done[0] && wIndex == 0) tegra_usb_phy_bus_reset(tegra->phy); + } else if (wValue == USB_PORT_FEAT_POWER) { + if (wIndex == 1) + tegra_usb_phy_port_power(tegra->phy); } - break; } - case USB_PORT_FEAT_POWER: - { - if (HCS_PPC(ehci->hcs_params)) - ehci_writel(ehci, temp | PORT_POWER, status_reg); - if (hsic && (wIndex == 0)) - tegra_usb_phy_bus_connect(tegra->phy); - break; - } - } - goto done; } - spin_unlock_irqrestore(&ehci->lock, flags); - - /* Handle the hub control events here */ - retval = ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return retval; -done: - spin_unlock_irqrestore(&ehci->lock, flags); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); return retval; } -#ifdef CONFIG_PM -static void tegra_ehci_restart(struct usb_hcd *hcd, bool is_dpd) +static void tegra_ehci_shutdown(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - unsigned int temp; - - ehci->controller_resets_phy = 0; - tegra_ehci_pre_reset(tegra->phy, false); - ehci_reset(ehci); - tegra_ehci_post_reset(tegra->phy, false); - - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_NULL_ULPI) - ehci->controller_resets_phy = 1; - - /* setup the frame list and Async q heads */ - ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); - ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); - /* setup the command register and set the controller in RUN mode */ - ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* dont start RS here for HSIC, it will be set by bus_reset */ - if (tegra->phy->usb_phy_type != TEGRA_USB_PHY_TYPE_HSIC) -#endif - ehci->command |= CMD_RUN; - ehci_writel(ehci, ehci->command, &ehci->regs->command); - - /* Enable the root Port Power */ - if (HCS_PPC(ehci->hcs_params)) { - temp = ehci_readl(ehci, &ehci->regs->port_status[0]); - ehci_writel(ehci, temp | PORT_POWER, &ehci->regs->port_status[0]); - } - - down_write(&ehci_cf_port_reset_rwsem); - if(is_dpd) - hcd->state = HC_STATE_SUSPENDED; - else - hcd->state = HC_STATE_RUNNING; - ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); - /* flush posted writes */ - ehci_readl(ehci, &ehci->regs->command); - up_write(&ehci_cf_port_reset_rwsem); - - /* Turn On Interrupts */ - ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); -} - -static int tegra_usb_suspend(struct usb_hcd *hcd, bool is_dpd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - struct ehci_regs __iomem *hw = tegra->ehci->regs; - unsigned long flags; - int hsic = 0; - - hsic = (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC); - - spin_lock_irqsave(&tegra->ehci->lock, flags); - - if (tegra->ehci->has_hostpc) - tegra->port_speed = (readl(hcd->regs + HOSTPC_REG_OFFSET) >> 25) & 0x3; - else - tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; - ehci_halt(tegra->ehci); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - /* - * Ehci run bit is disabled by now read this into command variable - * so that bus resume will not enable run bit immedialty. - * this is required for 2LS WAR on UTMIP interface. - */ - tegra->ehci->command = ehci_readl(tegra->ehci, - &tegra->ehci->regs->command); - } -#endif - - spin_unlock_irqrestore(&tegra->ehci->lock, flags); - - tegra_ehci_power_down(hcd, is_dpd); - return 0; -} - -static int tegra_usb_resume(struct usb_hcd *hcd, bool is_dpd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct ehci_regs __iomem *hw = ehci->regs; - unsigned long val; - bool hsic; - bool null_ulpi; - bool utmip_remote_wakeup = false; - - null_ulpi = (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_NULL_ULPI); - hsic = (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC); - - tegra_ehci_power_up(hcd, is_dpd); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - if ((tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) || (hsic) || - (null_ulpi)) - goto restart; - - /* Force the phy to keep data lines in suspend state */ - tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); - - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - ehci_reset(ehci); - } - - /* Enable host mode */ - tdi_reset(ehci); - - if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && - (tegra->ehci->has_hostpc)) { - val = readl(hcd->regs + HOSTPC_REG_OFFSET); - val &= ~HOSTPC1_DEVLC_PTS(~0); - val |= HOSTPC1_DEVLC_STS; - writel(val, hcd->regs + HOSTPC_REG_OFFSET); - } - - /* Enable Port Power */ - val = readl(&hw->port_status[0]); - val |= PORT_POWER; - writel(val, &hw->port_status[0]); - udelay(10); - - if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && - (tegra->ehci->has_hostpc) && (tegra->phy->remote_wakeup)) { - utmip_remote_wakeup = true; - } - - /* Check if the phy resume from LP0. When the phy resume from LP0 - * USB register will be reset. */ - if (!readl(&hw->async_next)) { -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* Start the controller */ - val = readl(&hw->command); - writel((val | CMD_RUN), &hw->command); -#endif - /* Program the field PTC based on the saved speed mode */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) - val |= PORT_TEST_FORCE; - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) - val |= PORT_TEST(6); - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= PORT_TEST(7); - writel(val, &hw->port_status[0]); - udelay(10); - - /* Disable test mode by setting PTC field to NORMAL_OP */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - writel(val, &hw->port_status[0]); - udelay(10); - } - - /* Poll until CCS is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, - PORT_CONNECT, 2000)) { - pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); - goto restart; - } - - /* Poll until PE is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_PE, - PORT_PE, 2000)) { - pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); - goto restart; - } - - /* Clear the PCI status, to avoid an interrupt taken upon resume */ - val = readl(&hw->status); - val |= STS_PCD; - writel(val, &hw->status); - - /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ - val = readl(&hw->port_status[0]); - if ((val & PORT_POWER) && (val & PORT_PE)) { - val |= PORT_SUSPEND; - writel(val, &hw->port_status[0]); - - /* Need a 4ms delay before the controller goes to suspend */ - mdelay(4); - - /* Wait until port suspend completes */ - if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, - PORT_SUSPEND, 1000)) { - pr_err("%s: timeout waiting for PORT_SUSPEND\n", - __func__); - goto restart; - } - } - - tegra_ehci_phy_restore_end(tegra->phy); - if (utmip_remote_wakeup) { - ehci->command |= CMD_RUN; - ehci_writel(ehci, ehci->command, &ehci->regs->command); - } - return 0; - -restart: - if (null_ulpi) { - bool LP0 = !readl(&hw->async_next); - - if (LP0) { - static int cnt = 1; - - pr_info("LP0 restart %d\n", cnt++); - tegra_ehci_phy_restore_start(tegra->phy, - tegra->port_speed); - } - - val = readl(&hw->port_status[0]); - if (!((val & PORT_POWER) && (val & PORT_PE))) { - tegra_ehci_restart(hcd, is_dpd); - } - - if (LP0) - tegra_ehci_phy_restore_end(tegra->phy); - - return 0; - } - - if ((tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) && (!hsic)) - tegra_ehci_phy_restore_end(tegra->phy); - if (hsic) { - val = readl(&hw->port_status[0]); - if (!((val & PORT_POWER) && (val & PORT_PE))) - tegra_ehci_restart(hcd, false); - - tegra_usb_phy_bus_idle(tegra->phy); - if (!tegra_usb_phy_is_device_connected(tegra->phy)) - pr_err("%s: no hsic device conenction\n", __func__); - } else { - tegra_ehci_restart(hcd, false); - } - - return 0; -} -#endif - -/* - * Disable PHY clock valid interrupts and wait for the interrupt handler to - * finish. - * - * Requires a lock on tegra_ehci_hcd_mutex - * Must not be called with a lock on ehci->lock - */ -static void tegra_ehci_disable_phy_interrupt(struct usb_hcd *hcd) { - struct tegra_ehci_hcd *tegra; - u32 val; - if (hcd->irq >= 0) { - tegra = dev_get_drvdata(hcd->self.controller); - if (tegra->phy->hotplug) { - /* Disable PHY clock valid interrupts */ - val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); - val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB; - writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); - } - /* Wait for the interrupt handler to finish */ - synchronize_irq(hcd->irq); - } -} - -static void tegra_ehci_shutdown(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - - mutex_lock(&tegra->tegra_ehci_hcd_mutex); - tegra_ehci_disable_phy_interrupt(hcd); - /* ehci_shutdown touches the USB controller registers, make sure - * controller has clocks to it */ - if (!tegra->host_resumed) - tegra_ehci_power_up(hcd, false); - - ehci_shutdown(hcd); - - /* we are ready to shut down, powerdown the phy */ - tegra_ehci_power_down(hcd, false); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); + mutex_lock(&tegra->sync_lock); + del_timer_sync(&ehci->watchdog); + del_timer_sync(&ehci->iaa_watchdog); + if (tegra_usb_phy_hw_accessible(tegra->phy)) { + spin_lock_irq(&ehci->lock); + ehci_silence_controller(ehci); + spin_unlock_irq(&ehci->lock); + } + mutex_unlock(&tegra->sync_lock); } static int tegra_ehci_setup(struct usb_hcd *hcd) @@ -786,24 +294,18 @@ static int tegra_ehci_setup(struct usb_hcd *hcd) /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = readl(&ehci->caps->hcs_params); + ehci->has_hostpc = tegra_usb_phy_has_hostpc(tegra->phy) ? 1 : 0; + ehci->broken_hostpc_phcd = true; -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - ehci->has_hostpc = 1; -#endif hcd->has_tt = 1; - if (tegra->phy->usb_phy_type != TEGRA_USB_PHY_TYPE_NULL_ULPI) { - ehci_reset(ehci); - tegra_ehci_post_reset(tegra->phy, false); - } - retval = ehci_halt(ehci); if (retval) return retval; @@ -815,267 +317,49 @@ static int tegra_ehci_setup(struct usb_hcd *hcd) ehci->sbrn = 0x20; ehci->controller_remote_wakeup = false; - - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_NULL_ULPI) { - tegra_ehci_pre_reset(tegra->phy, false); - ehci_reset(ehci); - tegra_ehci_post_reset(tegra->phy, false); - - /* - * Resetting the controller has the side effect of resetting the PHY. - * So, never reset the controller after the calling - * tegra_ehci_reinit API. - */ - ehci->controller_resets_phy = 1; - } + ehci_reset(ehci); + tegra_usb_phy_reset(tegra->phy); ehci_port_power(ehci, 1); return retval; } + #ifdef CONFIG_PM static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - int error_status = 0; - - mutex_lock(&tegra->tegra_ehci_hcd_mutex); + int err = 0; + EHCI_DBG("%s() BEGIN\n", __func__); + mutex_lock(&tegra->sync_lock); tegra->bus_suspended_fail = false; - tegra_ehci_disable_phy_interrupt(hcd); - /* ehci_shutdown touches the USB controller registers, make sure - * controller has clocks to it */ - if (!tegra->host_resumed) - tegra_ehci_power_up(hcd, false); - error_status = ehci_bus_suspend(hcd); - if (error_status) + err = ehci_bus_suspend(hcd); + if (err) tegra->bus_suspended_fail = true; - if (!error_status && tegra->power_down_on_bus_suspend) { - tegra_usb_suspend(hcd, false); - tegra->bus_suspended = 1; - } - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); + else + tegra_usb_phy_suspend(tegra->phy); + mutex_unlock(&tegra->sync_lock); + EHCI_DBG("%s() END\n", __func__); - return error_status; + return err; } static int tegra_ehci_bus_resume(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - int ehci_bus_resumed; + int err = 0; + EHCI_DBG("%s() BEGIN\n", __func__); - mutex_lock(&tegra->tegra_ehci_hcd_mutex); - if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) { - tegra_usb_resume(hcd, false); - tegra->bus_suspended = 0; - } + mutex_lock(&tegra->sync_lock); + tegra_usb_phy_resume(tegra->phy); + err = ehci_bus_resume(hcd); + mutex_unlock(&tegra->sync_lock); + EHCI_DBG("%s() END\n", __func__); - ehci_bus_resumed = ehci_bus_resume(hcd); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return ehci_bus_resumed; + return err; } #endif -struct dma_aligned_buffer { - void *kmalloc_ptr; - void *old_xfer_buffer; - u8 data[0]; -}; - -static void free_dma_aligned_buffer(struct urb *urb) -{ - struct dma_aligned_buffer *temp = container_of(urb->transfer_buffer, - struct dma_aligned_buffer, data); - - if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) - return; - - if(usb_urb_dir_in(urb)) - memcpy(temp->old_xfer_buffer, temp->data, - urb->transfer_buffer_length); - urb->transfer_buffer = temp->old_xfer_buffer; - kfree(temp->kmalloc_ptr); - urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; -} - -static int alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) -{ - struct dma_aligned_buffer *temp, *kmalloc_ptr; - size_t kmalloc_size; - - if (urb->num_sgs || urb->sg || - urb->transfer_buffer_length == 0 || - !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1))) - return 0; - - /* Allocate a buffer with enough padding for alignment */ - kmalloc_size = urb->transfer_buffer_length + - sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1; - - kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); - if (!kmalloc_ptr) - return -ENOMEM; - - /* Position our struct dma_aligned_buffer such that data is aligned */ - temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1; - temp->kmalloc_ptr = kmalloc_ptr; - temp->old_xfer_buffer = urb->transfer_buffer; - if (!usb_urb_dir_in(urb)) - memcpy(temp->data, urb->transfer_buffer, - urb->transfer_buffer_length); - urb->transfer_buffer = temp->data; - urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; - - return 0; -} - -static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - gfp_t mem_flags) -{ - int ret; - - ret = alloc_dma_aligned_buffer(urb, mem_flags); - if (ret) - return ret; - - ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); - - /* control packets over dma */ - if (urb->setup_dma) - dma_sync_single_for_device(hcd->self.controller, - urb->setup_dma, sizeof(struct usb_ctrlrequest), - DMA_TO_DEVICE); - - /* urb buffers over dma */ - if (urb->transfer_dma) { - enum dma_data_direction dir; - dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - - dma_sync_single_for_device(hcd->self.controller, - urb->transfer_dma, urb->transfer_buffer_length, dir); - } - - if (ret) - free_dma_aligned_buffer(urb); - - return ret; -} - -static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - - /* Fence read for coherency of AHB master intiated writes */ - if (tegra->phy->instance == 0) - readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); - else if (tegra->phy->instance == 1) - readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); - else if (tegra->phy->instance == 2) - readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); - - if (urb->transfer_dma) { - enum dma_data_direction dir; - dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - if (dir == DMA_FROM_DEVICE) - dma_sync_single_for_cpu(hcd->self.controller, - urb->transfer_dma, urb->transfer_buffer_length, - DMA_FROM_DEVICE); - } - - usb_hcd_unmap_urb_for_dma(hcd, urb); - free_dma_aligned_buffer(urb); -} - -void clk_timer_callback(unsigned long data) -{ - struct tegra_ehci_hcd *tegra = (struct tegra_ehci_hcd*) data; - unsigned long flags; - - if (!timer_pending(&tegra->clk_timer)) { - spin_lock_irqsave(&tegra->ehci->lock, flags); - tegra->timer_event = 1; - spin_unlock_irqrestore(&tegra->ehci->lock, flags); - schedule_work(&tegra->clk_timer_work); - } -} - -static void clk_timer_work_handler(struct work_struct* clk_timer_work) { - struct tegra_ehci_hcd *tegra = container_of(clk_timer_work, - struct tegra_ehci_hcd, clk_timer_work); - int ret; - unsigned long flags; - bool clock_enabled, timer_event; - - spin_lock_irqsave(&tegra->ehci->lock, flags); - clock_enabled = tegra->clock_enabled; - timer_event = tegra->timer_event; - spin_unlock_irqrestore(&tegra->ehci->lock, flags); - - if (timer_event) { - spin_lock_irqsave(&tegra->ehci->lock, flags); - tegra->clock_enabled = 0; - tegra->timer_event = 0; - spin_unlock_irqrestore(&tegra->ehci->lock, flags); - clk_disable(tegra->emc_clk); - clk_disable(tegra->sclk_clk); - return; - } - - if ((!clock_enabled)) { - ret = mod_timer(&tegra->clk_timer, jiffies + msecs_to_jiffies(2000)); - if (ret) - pr_err("tegra_ehci_urb_enqueue timer modify failed \n"); - clk_enable(tegra->emc_clk); - clk_enable(tegra->sclk_clk); - spin_lock_irqsave(&tegra->ehci->lock, flags); - tegra->clock_enabled = 1; - spin_unlock_irqrestore(&tegra->ehci->lock, flags); - } else { - if (timer_pending(&tegra->clk_timer)) { - mod_timer_pending (&tegra->clk_timer, jiffies - + msecs_to_jiffies(2000)); - } - } -} - -static int tegra_ehci_urb_enqueue ( - struct usb_hcd *hcd, - struct urb *urb, - gfp_t mem_flags) -{ - struct tegra_ehci_hcd *pdata; - int xfertype; - int transfer_buffer_length; - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - unsigned long flags; - pdata = dev_get_drvdata(hcd->self.controller); - - xfertype = usb_endpoint_type(&urb->ep->desc); - transfer_buffer_length = urb->transfer_buffer_length; - spin_lock_irqsave(&ehci->lock,flags); - /* Turn on the USB busy hints */ - switch (xfertype) { - case USB_ENDPOINT_XFER_INT: - if (transfer_buffer_length < 255) { - /* Do nothing for interrupt buffers < 255 */ - } else { - /* signal to set the busy hints */ - schedule_work(&pdata->clk_timer_work); - } - break; - case USB_ENDPOINT_XFER_ISOC: - case USB_ENDPOINT_XFER_BULK: - /* signal to set the busy hints */ - schedule_work(&pdata->clk_timer_work); - break; - case USB_ENDPOINT_XFER_CONTROL: - default: - /* Do nothing special here */ - break; - } - spin_unlock_irqrestore(&ehci->lock,flags); - return ehci_urb_enqueue(hcd, urb, mem_flags); -} - static const struct hc_driver tegra_ehci_hc_driver = { .description = hcd_name, .product_desc = "Tegra EHCI Host Controller", @@ -1085,9 +369,10 @@ static const struct hc_driver tegra_ehci_hc_driver = { /* standard ehci functions */ .start = ehci_run, .stop = ehci_stop, + .urb_enqueue = ehci_urb_enqueue, .urb_dequeue = ehci_urb_dequeue, .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, + .endpoint_reset = ehci_endpoint_reset, .get_frame_number = ehci_get_frame, .hub_status_data = ehci_hub_status_data, .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, @@ -1101,10 +386,9 @@ static const struct hc_driver tegra_ehci_hc_driver = { .map_urb_for_dma = tegra_ehci_map_urb_for_dma, .unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma, .hub_control = tegra_ehci_hub_control, - .urb_enqueue = tegra_ehci_urb_enqueue, #ifdef CONFIG_PM - .bus_suspend = tegra_ehci_bus_suspend, - .bus_resume = tegra_ehci_bus_resume, + .bus_suspend = tegra_ehci_bus_suspend, + .bus_resume = tegra_ehci_bus_resume, #endif }; @@ -1113,76 +397,30 @@ static int tegra_ehci_probe(struct platform_device *pdev) struct resource *res; struct usb_hcd *hcd; struct tegra_ehci_hcd *tegra; - struct tegra_ehci_platform_data *pdata; int err = 0; int irq; - int instance = pdev->id; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "Platform data missing\n"); - return -EINVAL; - } tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL); - if (!tegra) + if (!tegra) { + dev_err(&pdev->dev, "memory alloc failed\n"); return -ENOMEM; + } - mutex_init(&tegra->tegra_ehci_hcd_mutex); + mutex_init(&tegra->sync_lock); hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { - dev_err(&pdev->dev, "Unable to create HCD\n"); + dev_err(&pdev->dev, "unable to create HCD\n"); err = -ENOMEM; goto fail_hcd; } platform_set_drvdata(pdev, tegra); - tegra->default_enable = pdata->default_enable; - - tegra->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(tegra->clk)) { - dev_err(&pdev->dev, "Can't get ehci clock\n"); - err = PTR_ERR(tegra->clk); - goto fail_clk; - } - - err = clk_enable(tegra->clk); - if (err) - goto fail_clken; - - - tegra->sclk_clk = clk_get(&pdev->dev, "sclk"); - if (IS_ERR(tegra->sclk_clk)) { - dev_err(&pdev->dev, "Can't get sclk clock\n"); - err = PTR_ERR(tegra->sclk_clk); - goto fail_sclk_clk; - } - - clk_set_rate(tegra->sclk_clk, 80000000); - - tegra->emc_clk = clk_get(&pdev->dev, "emc"); - if (IS_ERR(tegra->emc_clk)) { - dev_err(&pdev->dev, "Can't get emc clock\n"); - err = PTR_ERR(tegra->emc_clk); - goto fail_emc_clk; - } - init_timer(&tegra->clk_timer); - tegra->clk_timer.function = clk_timer_callback; - tegra->clk_timer.data = (unsigned long) tegra; - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* Set DDR busy hints to 150MHz. For Tegra 2x SOC, DDR rate is half of EMC rate */ - clk_set_rate(tegra->emc_clk, 300000000); -#else - /* Set DDR busy hints to 100MHz. For Tegra 3x SOC DDR rate equals to EMC rate */ - clk_set_rate(tegra->emc_clk, 100000000); -#endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); + dev_err(&pdev->dev, "failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } @@ -1190,179 +428,103 @@ static int tegra_ehci_probe(struct platform_device *pdev) hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(res->start, resource_size(res)); if (!hcd->regs) { - dev_err(&pdev->dev, "Failed to remap I/O memory\n"); + dev_err(&pdev->dev, "failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } - INIT_WORK(&tegra->clk_timer_work, clk_timer_work_handler); + irq = platform_get_irq(pdev, 0); + if (!irq) { + dev_err(&pdev->dev, "failed to get IRQ\n"); + err = -ENODEV; + goto fail_irq; + } + set_irq_flags(irq, IRQF_VALID); + tegra->irq = irq; - tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, - TEGRA_USB_PHY_MODE_HOST, pdata->phy_type); + tegra->phy = tegra_usb_phy_open(pdev); if (IS_ERR(tegra->phy)) { - dev_err(&pdev->dev, "Failed to open USB phy\n"); + dev_err(&pdev->dev, "failed to open USB phy\n"); err = -ENXIO; - goto fail_phy; + goto fail_irq; } - tegra->phy->hotplug = pdata->hotplug; - err = tegra_usb_phy_power_on(tegra->phy, true); + err = tegra_usb_phy_power_on(tegra->phy); if (err) { - dev_err(&pdev->dev, "Failed to power on the phy\n"); - goto fail; - } - - tegra->host_resumed = 1; - tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend; - tegra->ehci = hcd_to_ehci(hcd); - - irq = platform_get_irq(pdev, 0); - if (!irq) { - dev_err(&pdev->dev, "Failed to get IRQ\n"); - err = -ENODEV; - goto fail; + dev_err(&pdev->dev, "failed to power on the phy\n"); + goto fail_phy; } - set_irq_flags(irq, IRQF_VALID); - tegra->irq = irq; -#ifdef CONFIG_USB_OTG_UTILS - if (pdata->operating_mode == TEGRA_USB_OTG) { - tegra->transceiver = otg_get_transceiver(); - if (tegra->transceiver) - otg_set_host(tegra->transceiver, &hcd->self); + err = tegra_usb_phy_init(tegra->phy); + if (err) { + dev_err(&pdev->dev, "failed to init the phy\n"); + goto fail_phy; } -#endif err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (err) { - dev_err(&pdev->dev, "Failed to add USB HCD error = %d\n", err); - goto fail; + dev_err(&pdev->dev, "Failed to add USB HCD, error=%d\n", err); + goto fail_phy; } err = enable_irq_wake(tegra->irq); if (err < 0) { dev_warn(&pdev->dev, - "Couldn't enable USB host mode wakeup, irq=%d, " - "error=%d\n", tegra->irq, err); + "Couldn't enable USB host mode wakeup, irq=%d, " + "error=%d\n", irq, err); err = 0; tegra->irq = 0; } - return err; + tegra->ehci = hcd_to_ehci(hcd); -fail: #ifdef CONFIG_USB_OTG_UTILS - if (tegra->transceiver) { - otg_set_host(tegra->transceiver, NULL); - otg_put_transceiver(tegra->transceiver); + if (tegra_usb_phy_otg_supported(tegra->phy)) { + tegra->transceiver = otg_get_transceiver(); + if (tegra->transceiver) + otg_set_host(tegra->transceiver, &hcd->self); } #endif - tegra_usb_phy_close(tegra->phy); + return err; + fail_phy: + tegra_usb_phy_close(tegra->phy); +fail_irq: iounmap(hcd->regs); fail_io: - clk_disable(tegra->emc_clk); - clk_put(tegra->emc_clk); -fail_emc_clk: - clk_disable(tegra->sclk_clk); - clk_put(tegra->sclk_clk); -fail_sclk_clk: - clk_disable(tegra->clk); -fail_clken: - clk_put(tegra->clk); -fail_clk: usb_put_hcd(hcd); fail_hcd: kfree(tegra); + return err; } + #ifdef CONFIG_PM static int tegra_ehci_resume_noirq(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - mutex_lock(&tegra->tegra_ehci_hcd_mutex); - if ((tegra->bus_suspended) && (tegra->power_down_on_bus_suspend)) { - if (tegra->default_enable) - clk_enable(tegra->clk); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return 0; - } - - if (tegra->default_enable) - clk_enable(tegra->clk); - - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return 0; + return tegra_usb_phy_power_on(tegra->phy); } -static int tegra_ehci_resume(struct device *dev) +static int tegra_ehci_suspend_noirq(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - int ret; - - mutex_lock(&tegra->tegra_ehci_hcd_mutex); - if ((tegra->bus_suspended) && (tegra->power_down_on_bus_suspend)) { - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return 0; - } - ret = tegra_usb_resume(hcd, true); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return ret; -} - -static int tegra_ehci_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - int ret; - u32 val; - - mutex_lock(&tegra->tegra_ehci_hcd_mutex); - /* if bus suspend is failed means there is remote wakeup resume, - then abort the PM suspend */ - if (tegra->bus_suspended_fail) { - tegra->bus_suspended_fail = false; - pr_err("%s: bus suspend failed, aborting driver suspend\n", __func__); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); + /* bus suspend could have failed because of remote wakeup resume */ + if (tegra->bus_suspended_fail) return -EBUSY; - } - if (tegra->phy->hotplug) { - /* Disable PHY clock valid interrupts while going into suspend*/ - val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); - val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB; - writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); - } - - if ((tegra->bus_suspended) && (tegra->power_down_on_bus_suspend)) { - if (tegra->default_enable) - clk_disable(tegra->clk); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return 0; - } - - if (time_before(jiffies, tegra->ehci->next_statechange)) - msleep(10); - - ret = tegra_usb_suspend(hcd, true); - if (tegra->default_enable) - clk_disable(tegra->clk); - mutex_unlock(&tegra->tegra_ehci_hcd_mutex); - return ret; + else + return tegra_usb_phy_power_off(tegra->phy); } static struct dev_pm_ops tegra_ehci_dev_pm_ops = { - .suspend = tegra_ehci_suspend, - .resume = tegra_ehci_resume, - .resume_noirq = tegra_ehci_resume_noirq, + .suspend_noirq = tegra_ehci_suspend_noirq, + .resume_noirq = tegra_ehci_resume_noirq, }; - #endif static int tegra_ehci_remove(struct platform_device *pdev) @@ -1372,9 +534,6 @@ static int tegra_ehci_remove(struct platform_device *pdev) if (tegra == NULL || hcd == NULL) return -EINVAL; - /* make sure controller is on as we will touch its registers */ - if (!tegra->host_resumed) - tegra_ehci_power_up(hcd, true); #ifdef CONFIG_USB_OTG_UTILS if (tegra->transceiver) { @@ -1383,30 +542,15 @@ static int tegra_ehci_remove(struct platform_device *pdev) } #endif - /* Turn Off Interrupts */ - ehci_writel(tegra->ehci, 0, &tegra->ehci->regs->intr_enable); - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); if (tegra->irq) disable_irq_wake(tegra->irq); usb_remove_hcd(hcd); usb_put_hcd(hcd); - tegra_usb_phy_power_off(tegra->phy, true); + tegra_usb_phy_power_off(tegra->phy); tegra_usb_phy_close(tegra->phy); iounmap(hcd->regs); - - del_timer_sync(&tegra->clk_timer); - - clk_disable(tegra->clk); - clk_put(tegra->clk); - - if (tegra->clock_enabled) { - clk_disable(tegra->sclk_clk); - clk_disable(tegra->emc_clk); - } - clk_put(tegra->sclk_clk); - clk_put(tegra->emc_clk); - kfree(tegra); + return 0; } @@ -1421,12 +565,12 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) static struct platform_driver tegra_ehci_driver = { .probe = tegra_ehci_probe, - .remove = tegra_ehci_remove, + .remove = tegra_ehci_remove, .shutdown = tegra_ehci_hcd_shutdown, - .driver = { - .name = "tegra-ehci", + .driver = { + .name = driver_name, #ifdef CONFIG_PM - .pm = &tegra_ehci_dev_pm_ops, + .pm = &tegra_ehci_dev_pm_ops, #endif } }; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 509934ceb4a9..cfbdf32ec0b2 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -143,6 +143,7 @@ struct ehci_hcd { /* one per controller */ #ifdef CONFIG_USB_EHCI_TEGRA unsigned controller_resets_phy:1; unsigned controller_remote_wakeup:1; + unsigned broken_hostpc_phcd:1; #endif /* required for usb32 quirk */ diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c index f72e2225e7c7..4c590076f73e 100644 --- a/drivers/usb/otg/tegra-otg.c +++ b/drivers/usb/otg/tegra-otg.c @@ -24,7 +24,6 @@ #include <linux/usb.h> #include <linux/usb/otg.h> #include <linux/usb/gadget.h> -#include <linux/usb/hcd.h> #include <linux/platform_device.h> #include <linux/platform_data/tegra_usb.h> #include <linux/clk.h> @@ -41,7 +40,6 @@ #define USB_VBUS_INT_EN (1 << 8) #define USB_VBUS_INT_STATUS (1 << 9) #define USB_VBUS_STATUS (1 << 10) -#define USB_INTS (USB_VBUS_INT_STATUS | USB_ID_INT_STATUS) #define USB_INT_EN (USB_VBUS_INT_EN | USB_ID_INT_EN | \ USB_VBUS_WAKEUP_EN | USB_ID_PIN_WAKEUP_EN) @@ -67,9 +65,9 @@ struct tegra_otg_data { bool clk_enabled; callback_t charger_cb; void *charger_cb_data; - bool interrupt_mode; }; + static struct tegra_otg_data *tegra_clone; static inline unsigned long otg_readl(struct tegra_otg_data *tegra, @@ -84,20 +82,6 @@ static inline void otg_writel(struct tegra_otg_data *tegra, unsigned long val, writel(val, tegra->regs + offset); } -static void tegra_otg_enable_clk(void) -{ - if (!tegra_clone->clk_enabled) - clk_enable(tegra_clone->clk); - tegra_clone->clk_enabled = true; -} - -static void tegra_otg_disable_clk(void) -{ - if (tegra_clone->clk_enabled) - clk_disable(tegra_clone->clk); - tegra_clone->clk_enabled = false; -} - static const char *tegra_state_name(enum usb_otg_state state) { switch (state) { @@ -132,78 +116,69 @@ static unsigned long enable_interrupt(struct tegra_otg_data *tegra, bool en) return val; } -static struct platform_device * -tegra_usb_otg_host_register(struct platform_device *ehci_device, - struct tegra_ehci_platform_data *pdata) +static void tegra_start_host(struct tegra_otg_data *tegra) { - struct platform_device *pdev; + struct tegra_usb_otg_data *pdata = tegra->otg.dev->platform_data; + struct platform_device *pdev, *ehci_device = pdata->ehci_device; void *platform_data; int val; + DBG("%s(%d) Begin\n", __func__, __LINE__); + if (tegra->pdev) + return ; + + /* prepare device structure for registering host*/ pdev = platform_device_alloc(ehci_device->name, ehci_device->id); if (!pdev) - return NULL; + return ; val = platform_device_add_resources(pdev, ehci_device->resource, ehci_device->num_resources); if (val) goto error; - pdev->dev.dma_mask = ehci_device->dev.dma_mask; + pdev->dev.dma_mask = ehci_device->dev.dma_mask; pdev->dev.coherent_dma_mask = ehci_device->dev.coherent_dma_mask; - platform_data = kmalloc(sizeof(struct tegra_ehci_platform_data), - GFP_KERNEL); + platform_data = kmalloc(sizeof(struct tegra_usb_platform_data), GFP_KERNEL); if (!platform_data) goto error; - memcpy(platform_data, pdata, sizeof(struct tegra_ehci_platform_data)); + memcpy(platform_data, pdata->ehci_pdata, + sizeof(struct tegra_usb_platform_data)); pdev->dev.platform_data = platform_data; val = platform_device_add(pdev); if (val) goto error_add; - return pdev; + tegra->pdev = pdev; + DBG("%s(%d) End\n", __func__, __LINE__); + return ; error_add: kfree(platform_data); error: pr_err("%s: failed to add the host controller device\n", __func__); platform_device_put(pdev); - return NULL; -} - -static void tegra_usb_otg_host_unregister(struct platform_device *pdev) -{ - kfree(pdev->dev.platform_data); - pdev->dev.platform_data = NULL; - platform_device_unregister(pdev); + tegra->pdev = NULL; } -void tegra_start_host(struct tegra_otg_data *tegra) +static void tegra_stop_host(struct tegra_otg_data *tegra) { - DBG("%s(%d) BEGIN\n", __func__, __LINE__); - - struct tegra_otg_platform_data *pdata = tegra->otg.dev->platform_data; - if (!tegra->pdev) { - tegra->pdev = tegra_usb_otg_host_register(pdata->ehci_device, - pdata->ehci_pdata); - } - - DBG("%s(%d) END\n", __func__, __LINE__); -} + struct platform_device *pdev = tegra->pdev; -void tegra_stop_host(struct tegra_otg_data *tegra) -{ - DBG("%s(%d) BEGIN\n", __func__, __LINE__); + DBG("%s(%d) Begin\n", __func__, __LINE__); - if (tegra->pdev) { - tegra_usb_otg_host_unregister(tegra->pdev); + if (pdev) { + /* unregister host from otg */ + kfree(pdev->dev.platform_data); + pdev->dev.platform_data = NULL; + platform_device_unregister(pdev); tegra->pdev = NULL; } - DBG("%s(%d) END\n", __func__, __LINE__); + DBG("%s(%d) End\n", __func__, __LINE__); } int register_otg_callback(callback_t cb, void *args) @@ -263,10 +238,7 @@ static void irq_work(struct work_struct *work) unsigned long flags; unsigned long status; - clk_enable(tegra->clk); - spin_lock_irqsave(&tegra->lock, flags); - status = tegra->int_status; /* Debug prints */ @@ -299,8 +271,6 @@ static void irq_work(struct work_struct *work) spin_unlock_irqrestore(&tegra->lock, flags); tegra_change_otg_state(tegra, to); - clk_disable(tegra->clk); - tegra_otg_disable_clk(); } static irqreturn_t tegra_otg_irq(int irq, void *data) @@ -310,8 +280,9 @@ static irqreturn_t tegra_otg_irq(int irq, void *data) unsigned long val; spin_lock_irqsave(&tegra->lock, flags); - val = otg_readl(tegra, USB_PHY_WAKEUP); + DBG("%s(%d) interrupt val = 0x%x\n", __func__, __LINE__, val); + if (val & (USB_VBUS_INT_EN | USB_ID_INT_EN)) { DBG("%s(%d) PHY_WAKEUP = 0x%x\n", __func__, __LINE__, val); otg_writel(tegra, val, USB_PHY_WAKEUP); @@ -320,17 +291,11 @@ static irqreturn_t tegra_otg_irq(int irq, void *data) schedule_work(&tegra->work); } } - spin_unlock_irqrestore(&tegra->lock, flags); return IRQ_HANDLED; } -void tegra_otg_check_vbus_detection(void) -{ - tegra_otg_enable_clk(); -} -EXPORT_SYMBOL(tegra_otg_check_vbus_detection); static int tegra_otg_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) @@ -353,7 +318,7 @@ static int tegra_otg_set_peripheral(struct otg_transceiver *otg, if ((val & USB_ID_INT_STATUS) || (val & USB_VBUS_INT_STATUS)) { tegra->int_status = val; - schedule_work (&tegra->work); + schedule_work(&tegra->work); } DBG("%s(%d) END\n", __func__, __LINE__); @@ -373,7 +338,6 @@ static int tegra_otg_set_host(struct otg_transceiver *otg, clk_enable(tegra->clk); val = otg_readl(tegra, USB_PHY_WAKEUP); val &= ~(USB_VBUS_INT_STATUS | USB_ID_INT_STATUS); - val |= (USB_ID_INT_EN | USB_ID_PIN_WAKEUP_EN); otg_writel(tegra, val, USB_PHY_WAKEUP); clk_disable(tegra->clk); @@ -435,8 +399,6 @@ static DEVICE_ATTR(enable_host, 0644, show_host_en, store_host_en); static int tegra_otg_probe(struct platform_device *pdev) { struct tegra_otg_data *tegra; - struct tegra_otg_platform_data *otg_pdata; - struct tegra_ehci_platform_data *ehci_pdata; struct resource *res; int err; @@ -445,8 +407,6 @@ static int tegra_otg_probe(struct platform_device *pdev) return -ENOMEM; tegra->otg.dev = &pdev->dev; - otg_pdata = tegra->otg.dev->platform_data; - ehci_pdata = otg_pdata->ehci_pdata; tegra->otg.label = "tegra-otg"; tegra->otg.state = OTG_STATE_UNDEFINED; tegra->otg.set_host = tegra_otg_set_host; @@ -457,7 +417,6 @@ static int tegra_otg_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tegra); tegra_clone = tegra; - tegra->clk_enabled = false; tegra->interrupt_mode = true; tegra->clk = clk_get(&pdev->dev, NULL); @@ -505,10 +464,8 @@ static int tegra_otg_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to register IRQ\n"); goto err_irq; } - INIT_WORK (&tegra->work, irq_work); + INIT_WORK(&tegra->work, irq_work); - if (!ehci_pdata->default_enable) - clk_disable(tegra->clk); dev_info(&pdev->dev, "otg transceiver registered\n"); err = device_create_file(&pdev->dev, &dev_attr_enable_host); @@ -552,59 +509,57 @@ static int __exit tegra_otg_remove(struct platform_device *pdev) static int tegra_otg_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct tegra_otg_data *tegra_otg = platform_get_drvdata(pdev); - struct otg_transceiver *otg = &tegra_otg->otg; + struct tegra_otg_data *tegra = platform_get_drvdata(pdev); + struct otg_transceiver *otg = &tegra->otg; int val; DBG("%s(%d) BEGIN state : %s\n", __func__, __LINE__, tegra_state_name(otg->state)); - clk_enable(tegra_otg->clk); - val = readl(tegra_otg->regs + USB_PHY_WAKEUP); + clk_enable(tegra->clk); + val = readl(tegra->regs + USB_PHY_WAKEUP); val &= ~USB_INT_EN; - writel(val, tegra_otg->regs + USB_PHY_WAKEUP); - clk_disable(tegra_otg->clk); + writel(val, tegra->regs + USB_PHY_WAKEUP); + clk_disable(tegra->clk); - /* suspend peripheral mode, host mode is taken care by host driver */ + /* Suspend peripheral mode, host mode is taken care by host driver */ if (otg->state == OTG_STATE_B_PERIPHERAL) - tegra_change_otg_state(tegra_otg, OTG_STATE_A_SUSPEND); + tegra_change_otg_state(tegra, OTG_STATE_A_SUSPEND); DBG("%s(%d) END\n", __func__, __LINE__); - tegra_otg_disable_clk(); return 0; } static void tegra_otg_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct tegra_otg_data *tegra_otg = platform_get_drvdata(pdev); - struct otg_transceiver *otg = &tegra_otg->otg; - + struct tegra_otg_data *tegra = platform_get_drvdata(pdev); + struct otg_transceiver *otg = &tegra->otg; int val; unsigned long flags; DBG("%s(%d) BEGIN\n", __func__, __LINE__); /* Clear pending interrupts */ - clk_enable(tegra_otg->clk); - val = readl(tegra_otg->regs + USB_PHY_WAKEUP); - writel(val, tegra_otg->regs + USB_PHY_WAKEUP); + clk_enable(tegra->clk); + val = readl(tegra->regs + USB_PHY_WAKEUP); + writel(val, tegra->regs + USB_PHY_WAKEUP); DBG("%s(%d) PHY WAKEUP register : 0x%x\n", __func__, __LINE__, val); - clk_disable(tegra_otg->clk); + clk_disable(tegra->clk); /* Handle if host cable is replaced with device during suspend state */ if (otg->state == OTG_STATE_A_HOST && (val & USB_ID_STATUS)) - tegra_change_otg_state(tegra_otg, OTG_STATE_A_SUSPEND); + tegra_change_otg_state(tegra, OTG_STATE_A_SUSPEND); /* Enable interrupt and call work to set to appropriate state */ - spin_lock_irqsave(&tegra_otg->lock, flags); - tegra_otg->int_status = (val | USB_INT_EN); - spin_unlock_irqrestore(&tegra_otg->lock, flags); - irq_work(&tegra_otg->work); + spin_lock_irqsave(&tegra->lock, flags); + tegra->int_status = (val | USB_INT_EN); + spin_unlock_irqrestore(&tegra->lock, flags); + irq_work(&tegra->work); - clk_enable(tegra_otg->clk); - val = readl(tegra_otg->regs + USB_PHY_WAKEUP); + clk_enable(tegra->clk); + val = readl(tegra->regs + USB_PHY_WAKEUP); val |= USB_INT_EN; - writel(val, tegra_otg->regs + USB_PHY_WAKEUP); - clk_disable(tegra_otg->clk); + writel(val, tegra->regs + USB_PHY_WAKEUP); + clk_disable(tegra->clk); DBG("%s(%d) END\n", __func__, __LINE__); } diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 55d3fccf56b2..df54578a5b5a 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -583,6 +583,23 @@ static unsigned int tegra_dc_has_multiple_dc(void) return (cnt > 1); } +/* get the stride size of a window. + * return: stride size in bytes for window win. or 0 if unavailble. */ +int tegra_dc_get_stride(struct tegra_dc *dc, unsigned win) +{ + u32 tmp; + u32 stride; + + if (!dc->enabled) + return 0; + BUG_ON(win > DC_N_WINDOWS); + tegra_dc_writel(dc, WINDOW_A_SELECT << win, + DC_CMD_DISPLAY_WINDOW_HEADER); + tmp = tegra_dc_readl(dc, DC_WIN_LINE_STRIDE); + return GET_LINE_STRIDE(tmp); +} +EXPORT_SYMBOL(tegra_dc_get_stride); + struct tegra_dc *tegra_dc_get_dc(unsigned idx) { if (idx < TEGRA_MAX_DC) diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h index ded64de2decc..0b628fc7a14a 100644 --- a/drivers/video/tegra/dc/dc_reg.h +++ b/drivers/video/tegra/dc/dc_reg.h @@ -431,6 +431,8 @@ #define DC_WIN_LINE_STRIDE 0x70a #define LINE_STRIDE(x) (x) #define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16) +#define GET_LINE_STRIDE(x) ((x) & 0xffff) +#define GET_UV_LINE_STRIDE(x) (((x) >> 16) & 0xffff) #define DC_WIN_BUF_STRIDE 0x70b #define DC_WIN_UV_BUF_STRIDE 0x70c #define DC_WIN_BUFFER_ADDR_MODE 0x70d diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c index 69cc60f70f1c..e402c416b779 100644 --- a/drivers/video/tegra/dc/dsi.c +++ b/drivers/video/tegra/dc/dsi.c @@ -1,7 +1,7 @@ /* * drivers/video/tegra/dc/dsi.c * - * Copyright (c) 2011, NVIDIA Corporation. + * Copyright (c) 2011-2012, NVIDIA Corporation. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -31,6 +31,7 @@ #include <mach/dc.h> #include <mach/fb.h> #include <mach/csi.h> +#include <mach/iomap.h> #include <linux/nvhost.h> #include "dc_reg.h" @@ -38,6 +39,9 @@ #include "dsi_regs.h" #include "dsi.h" +#define APB_MISC_GP_MIPI_PAD_CTRL_0 (TEGRA_APB_MISC_BASE + 0x820) +#define DSIB_MODE_ENABLE 0x2 + #define DSI_USE_SYNC_POINTS 1 #define S_TO_MS(x) (1000 * (x)) @@ -1621,6 +1625,15 @@ static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi) tegra_vi_csi_writel(val, CSI_CIL_PAD_CONFIG); } +static void tegra_dsi_panelB_enable() +{ + unsigned int val; + + val = readl(IO_ADDRESS(APB_MISC_GP_MIPI_PAD_CTRL_0)); + val |= DSIB_MODE_ENABLE; + writel(val, (IO_ADDRESS(APB_MISC_GP_MIPI_PAD_CTRL_0))); +} + static int tegra_dsi_init_hw(struct tegra_dc *dc, struct tegra_dc_dsi_data *dsi) { @@ -1634,7 +1647,7 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc, tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz); if (dsi->info.dsi_instance) { - /* TODO:Set the misc register*/ + tegra_dsi_panelB_enable(); } /* TODO: only need to change the timing for bta */ diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c index 50aa9b383059..1193a2eb8c52 100644 --- a/drivers/video/tegra/fb.c +++ b/drivers/video/tegra/fb.c @@ -44,7 +44,7 @@ #include "dc/dc_priv.h" /* Pad pitch to 16-byte boundary. */ -#define TEGRA_LINEAR_PITCH_ALIGNMENT 16 +#define TEGRA_LINEAR_PITCH_ALIGNMENT 32 struct tegra_fb_info { struct tegra_dc_win *win; @@ -527,6 +527,7 @@ struct tegra_fb_info *tegra_fb_register(struct nvhost_device *ndev, unsigned long fb_size = 0; unsigned long fb_phys = 0; int ret = 0; + unsigned stride; win = tegra_dc_get_window(dc, fb_data->win); if (!win) { @@ -560,6 +561,11 @@ struct tegra_fb_info *tegra_fb_register(struct nvhost_device *ndev, tegra_fb->valid = true; } + stride = tegra_dc_get_stride(dc, 0); + if (!stride) /* default to pad the stride to 16-byte boundary. */ + stride = round_up(info->fix.line_length, + TEGRA_LINEAR_PITCH_ALIGNMENT); + info->fbops = &tegra_fb_ops; info->pseudo_palette = pseudo_palette; info->screen_base = fb_base; @@ -574,9 +580,7 @@ struct tegra_fb_info *tegra_fb_register(struct nvhost_device *ndev, info->fix.smem_start = fb_phys; info->fix.smem_len = fb_size; info->fix.line_length = fb_data->xres * fb_data->bits_per_pixel / 8; - /* Pad the stride to 16-byte boundary. */ - info->fix.line_length = round_up(info->fix.line_length, - TEGRA_LINEAR_PITCH_ALIGNMENT); + info->fix.line_length = stride; info->var.xres = fb_data->xres; info->var.yres = fb_data->yres; diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index fd632a6ea9c5..87aa9c64d363 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -141,12 +141,6 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp) priv->clientid = atomic_add_return(1, &nvhost_get_host(ch->dev)->clientid); priv->timeout = MAX_STUCK_CHECK_COUNT * SYNCPT_CHECK_PERIOD; - - priv->job = nvhost_job_alloc(ch, priv->hwctx, &priv->hdr, - NULL, priv->priority, priv->clientid); - if (!priv->job) - goto fail; - return 0; fail: nvhost_channelrelease(inode, filp); @@ -166,7 +160,7 @@ static int set_submit(struct nvhost_channel_userctx *ctx) return -EFAULT; } - ctx->job = nvhost_job_realloc(ctx->job, + ctx->job = nvhost_job_alloc(ctx->ch, ctx->hwctx, &ctx->hdr, ctx->nvmap, @@ -238,17 +232,28 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, cmdbuf.mem, cmdbuf.words, cmdbuf.offset); hdr->num_cmdbufs--; } else if (hdr->num_relocs) { - consumed = sizeof(struct nvhost_reloc); - if (remaining < consumed) + int numrelocs = remaining / sizeof(struct nvhost_reloc); + if (!numrelocs) break; - if (copy_from_user(&job->pinarray[job->num_pins], + numrelocs = min_t(int, numrelocs, priv->hdr.num_relocs); + consumed = numrelocs * sizeof(struct nvhost_reloc); + if (copy_from_user(&job->relocarray[job->num_relocs], buf, consumed)) { err = -EFAULT; break; } - trace_nvhost_channel_write_reloc(chname); - job->num_pins++; - hdr->num_relocs--; + while (numrelocs) { + struct nvhost_reloc *reloc = + &job->relocarray[job->num_relocs]; + trace_nvhost_channel_write_reloc(chname, + reloc->cmdbuf_mem, + reloc->cmdbuf_offset, + reloc->target, + reloc->target_offset); + job->num_relocs++; + hdr->num_relocs--; + numrelocs--; + } } else if (hdr->num_waitchks) { int numwaitchks = (remaining / sizeof(struct nvhost_waitchk)); @@ -269,17 +274,19 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, hdr->num_waitchks -= numwaitchks; } else if (priv->num_relocshifts) { int next_shift = - job->num_pins - priv->num_relocshifts; - consumed = sizeof(struct nvhost_reloc_shift); - if (remaining < consumed) + job->num_relocs - priv->num_relocshifts; + int num = + (remaining / sizeof(struct nvhost_reloc_shift)); + if (!num) break; - if (copy_from_user( - &job->pinarray[next_shift].reloc_shift, + num = min_t(int, num, priv->num_relocshifts); + consumed = num * sizeof(struct nvhost_reloc_shift); + if (copy_from_user(&job->relocshiftarray[next_shift], buf, consumed)) { err = -EFAULT; break; } - priv->num_relocshifts--; + priv->num_relocshifts -= num; } else { err = -EFAULT; break; @@ -302,7 +309,7 @@ static int nvhost_ioctl_channel_flush( struct nvhost_get_param_args *args, int null_kickoff) { - struct device *device = &ctx->ch->dev->dev; + struct nvhost_device *ndev = to_nvhost_device(&ctx->ch->dev->dev); int err; trace_nvhost_ioctl_channel_flush(ctx->ch->dev->name); @@ -312,13 +319,13 @@ static int nvhost_ioctl_channel_flush( ctx->hdr.num_cmdbufs || ctx->hdr.num_waitchks) { reset_submit(ctx); - dev_err(device, "channel submit out of sync\n"); + dev_err(&ndev->dev, "channel submit out of sync\n"); return -EFAULT; } - err = nvhost_job_pin(ctx->job); + err = nvhost_job_pin(ctx->job, &nvhost_get_host(ndev)->syncpt); if (err) { - dev_warn(device, "nvhost_job_pin failed: %d\n", err); + dev_warn(&ndev->dev, "nvhost_job_pin failed: %d\n", err); return err; } @@ -337,6 +344,9 @@ static int nvhost_ioctl_channel_flush( if (err) nvhost_job_unpin(ctx->job); + nvhost_job_put(ctx->job); + ctx->job = NULL; + return err; } diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h index edc5f6a51574..d69e1c4bccb9 100644 --- a/drivers/video/tegra/host/chip_support.h +++ b/drivers/video/tegra/host/chip_support.h @@ -28,10 +28,9 @@ struct output; struct nvhost_master; struct nvhost_intr; struct nvhost_syncpt; -struct nvhost_waitchk; struct nvhost_userctx_timeout; struct nvhost_channel; -struct nvmap_handle; +struct nvmap_handle_ref; struct nvmap_client; struct nvhost_hwctx; struct nvhost_cdma; @@ -77,7 +76,7 @@ struct nvhost_chip_support { void (*destroy)(struct push_buffer *); void (*push_to)(struct push_buffer *, struct nvmap_client *, - struct nvmap_handle *, + struct nvmap_handle_ref *, u32 op1, u32 op2); void (*pop_from)(struct push_buffer *, unsigned int slots); @@ -106,11 +105,8 @@ struct nvhost_chip_support { void (*read_wait_base)(struct nvhost_syncpt *, u32 id); u32 (*update_min)(struct nvhost_syncpt *, u32 id); void (*cpu_incr)(struct nvhost_syncpt *, u32 id); - int (*wait_check)(struct nvhost_syncpt *sp, - struct nvmap_client *nvmap, - u32 waitchk_mask, - struct nvhost_waitchk *wait, - int num_waitchk); + int (*patch_wait)(struct nvhost_syncpt *sp, + void *patch_addr); void (*debug)(struct nvhost_syncpt *); const char * (*name)(struct nvhost_syncpt *, u32 id); int (*mutex_try_lock)(struct nvhost_syncpt *, diff --git a/drivers/video/tegra/host/debug.c b/drivers/video/tegra/host/debug.c index 8a26f92c79f6..820eac85521d 100644 --- a/drivers/video/tegra/host/debug.c +++ b/drivers/video/tegra/host/debug.c @@ -106,13 +106,53 @@ static void show_all(struct nvhost_master *m, struct output *o) nvhost_get_chip_ops()->debug.show_mlocks(m, o); show_syncpts(m, o); nvhost_debug_output(o, "---- channels ----\n"); - bus_for_each_dev(&(nvhost_bus_get())->nvhost_bus_type, NULL, o, show_channels); + bus_for_each_dev(&(nvhost_bus_get())->nvhost_bus_type, NULL, o, + show_channels); nvhost_module_idle(m->dev); } #ifdef CONFIG_DEBUG_FS -static int nvhost_debug_show(struct seq_file *s, void *unused) +static int show_channels_no_fifo(struct device *dev, void *data) +{ + struct nvhost_channel *ch; + struct nvhost_device *nvdev = to_nvhost_device(dev); + struct output *o = data; + struct nvhost_master *m; + + if (nvdev == NULL) + return 0; + + m = nvhost_get_host(nvdev); + ch = nvdev->channel; + if (ch) { + mutex_lock(&ch->reflock); + if (ch->refcount) { + mutex_lock(&ch->cdma.lock); + nvhost_get_chip_ops()->debug.show_channel_cdma(m, + ch, o, nvdev->index); + mutex_unlock(&ch->cdma.lock); + } + mutex_unlock(&ch->reflock); + } + + return 0; +} + +static void show_all_no_fifo(struct nvhost_master *m, struct output *o) +{ + nvhost_module_busy(m->dev); + + nvhost_get_chip_ops()->debug.show_mlocks(m, o); + show_syncpts(m, o); + nvhost_debug_output(o, "---- channels ----\n"); + bus_for_each_dev(&(nvhost_bus_get())->nvhost_bus_type, NULL, o, + show_channels_no_fifo); + + nvhost_module_idle(m->dev); +} + +static int nvhost_debug_show_all(struct seq_file *s, void *unused) { struct output o = { .fn = write_to_seqfile, @@ -121,6 +161,27 @@ static int nvhost_debug_show(struct seq_file *s, void *unused) show_all(s->private, &o); return 0; } +static int nvhost_debug_show(struct seq_file *s, void *unused) +{ + struct output o = { + .fn = write_to_seqfile, + .ctx = s + }; + show_all_no_fifo(s->private, &o); + return 0; +} + +static int nvhost_debug_open_all(struct inode *inode, struct file *file) +{ + return single_open(file, nvhost_debug_show_all, inode->i_private); +} + +static const struct file_operations nvhost_debug_all_fops = { + .open = nvhost_debug_open_all, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; static int nvhost_debug_open(struct inode *inode, struct file *file) { @@ -140,6 +201,8 @@ void nvhost_debug_init(struct nvhost_master *master) debugfs_create_file("status", S_IRUGO, de, master, &nvhost_debug_fops); + debugfs_create_file("status_all", S_IRUGO, de, + master, &nvhost_debug_all_fops); debugfs_create_u32("null_kickoff_pid", S_IRUGO|S_IWUSR, de, &nvhost_debug_null_kickoff_pid); diff --git a/drivers/video/tegra/host/gr3d/gr3d_t20.c b/drivers/video/tegra/host/gr3d/gr3d_t20.c index c0efac03b882..5645f5b2b0c6 100644 --- a/drivers/video/tegra/host/gr3d/gr3d_t20.c +++ b/drivers/video/tegra/host/gr3d/gr3d_t20.c @@ -138,7 +138,7 @@ static void save_push_v0(struct nvhost_hwctx *nctx, struct nvhost_cdma *cdma) nvhost_cdma_push_gather(cdma, nvhost_get_host(nctx->channel->dev)->nvmap, - p->save_buf->handle, + p->save_buf, 0, nvhost_opcode_gather(p->save_size), p->save_phys); diff --git a/drivers/video/tegra/host/gr3d/gr3d_t30.c b/drivers/video/tegra/host/gr3d/gr3d_t30.c index 93d98dfa645c..57f4c779eff8 100644 --- a/drivers/video/tegra/host/gr3d/gr3d_t30.c +++ b/drivers/video/tegra/host/gr3d/gr3d_t30.c @@ -145,7 +145,7 @@ static void save_push_v1(struct nvhost_hwctx *nctx, struct nvhost_cdma *cdma) /* gather the save buffer */ nvhost_cdma_push_gather(cdma, nvhost_get_host(nctx->channel->dev)->nvmap, - p->save_buf->handle, + p->save_buf, 0, nvhost_opcode_gather(p->save_size), p->save_phys); diff --git a/drivers/video/tegra/host/host1x/host1x_cdma.c b/drivers/video/tegra/host/host1x/host1x_cdma.c index fcb1f05f0025..4569c3d62494 100644 --- a/drivers/video/tegra/host/host1x/host1x_cdma.c +++ b/drivers/video/tegra/host/host1x/host1x_cdma.c @@ -137,7 +137,7 @@ static void push_buffer_destroy(struct push_buffer *pb) */ static void push_buffer_push_to(struct push_buffer *pb, struct nvmap_client *client, - struct nvmap_handle *handle, u32 op1, u32 op2) + struct nvmap_handle_ref *handle, u32 op1, u32 op2) { u32 cur = pb->cur; u32 *p = (u32 *)((u32)pb->mapped + cur); diff --git a/drivers/video/tegra/host/host1x/host1x_channel.c b/drivers/video/tegra/host/host1x/host1x_channel.c index 8c4a7a5c74ad..c72e6478b806 100644 --- a/drivers/video/tegra/host/host1x/host1x_channel.c +++ b/drivers/video/tegra/host/host1x/host1x_channel.c @@ -143,7 +143,7 @@ static void submit_ctxrestore(struct nvhost_job *job) /* Send restore buffer to channel */ nvhost_cdma_push_gather(&ch->cdma, host->nvmap, - nvmap_ref_to_handle(ctx->restore), + ctx->restore, 0, nvhost_opcode_gather(ctx->restore_size), ctx->restore_phys); @@ -188,7 +188,7 @@ void submit_gathers(struct nvhost_job *job) u32 op2 = job->gathers[i].mem; nvhost_cdma_push_gather(&job->ch->cdma, job->nvmap, - nvmap_id_to_handle(job->gathers[i].mem_id), + job->gathers[i].ref, job->gathers[i].offset, op1, op2); } @@ -242,22 +242,6 @@ int host1x_channel_submit(struct nvhost_job *job) goto error; } - /* remove stale waits */ - if (job->num_waitchk) { - err = nvhost_syncpt_wait_check(sp, - job->nvmap, - job->waitchk_mask, - job->waitchk, - job->num_waitchk); - if (err) { - dev_warn(&ch->dev->dev, - "nvhost_syncpt_wait_check failed: %d\n", err); - mutex_unlock(&ch->submitlock); - nvhost_module_idle(ch->dev); - goto error; - } - } - /* begin a CDMA submit */ err = nvhost_cdma_begin(&ch->cdma, job); if (err) { diff --git a/drivers/video/tegra/host/host1x/host1x_debug.c b/drivers/video/tegra/host/host1x/host1x_debug.c index 76483d82528b..7de342298c4d 100644 --- a/drivers/video/tegra/host/host1x/host1x_debug.c +++ b/drivers/video/tegra/host/host1x/host1x_debug.c @@ -28,8 +28,8 @@ #include "host1x_hardware.h" #include "nvhost_cdma.h" #include "nvhost_channel.h" -#include "../../nvmap/nvmap.h" #include "host1x_cdma.h" +#include "nvhost_job.h" #define NVHOST_DEBUG_MAX_PAGE_OFFSET 102400 @@ -160,6 +160,34 @@ static void show_channel_word(struct output *o, int *state, int *count, } } +static void do_show_channel_gather(struct output *o, + phys_addr_t phys_addr, + u32 words, struct nvhost_cdma *cdma, + phys_addr_t pin_addr, u32 *map_addr) +{ + /* Map dmaget cursor to corresponding nvmap_handle */ + u32 offset; + int state, count, i; + + offset = phys_addr - pin_addr; + /* + * Sometimes we're given different hardware address to the same + * page - in these cases the offset will get an invalid number and + * we just have to bail out. + */ + if (offset > NVHOST_DEBUG_MAX_PAGE_OFFSET) { + nvhost_debug_output(o, "[address mismatch]\n"); + } else { + /* GATHER buffer starts always with commands */ + state = NVHOST_DBG_STATE_CMD; + for (i = 0; i < words; i++) + show_channel_word(o, &state, &count, + phys_addr + i * 4, + *(map_addr + offset/4 + i), + cdma); + } +} + static void show_channel_gather(struct output *o, u32 addr, phys_addr_t phys_addr, u32 words, struct nvhost_cdma *cdma) @@ -169,81 +197,36 @@ static void show_channel_gather(struct output *o, u32 addr, struct push_buffer *pb = &cdma->push_buffer; u32 cur = addr - pb->phys; struct nvmap_client_handle *nvmap = &pb->nvmap[cur/8]; - struct nvmap_handle_ref ref; u32 *map_addr, offset; phys_addr_t pin_addr; - int state, count, i; - if (!nvmap->handle || !nvmap->client - || atomic_read(&nvmap->handle->ref) < 1) { + if (!nvmap || !nvmap->handle || !nvmap->client) { nvhost_debug_output(o, "[already deallocated]\n"); return; } - /* Create a fake nvmap_handle_ref - nvmap requires it - * but accesses only the first field - nvmap_handle */ - ref.handle = nvmap->handle; - - map_addr = nvmap_mmap(&ref); + map_addr = nvmap_mmap(nvmap->handle); if (!map_addr) { nvhost_debug_output(o, "[could not mmap]\n"); return; } /* Get base address from nvmap */ - pin_addr = nvmap_pin(nvmap->client, &ref); + pin_addr = nvmap_pin(nvmap->client, nvmap->handle); if (IS_ERR_VALUE(pin_addr)) { nvhost_debug_output(o, "[couldn't pin]\n"); - nvmap_munmap(&ref, map_addr); + nvmap_munmap(nvmap->handle, map_addr); return; } offset = phys_addr - pin_addr; - /* - * Sometimes we're given different hardware address to the same - * page - in these cases the offset will get an invalid number and - * we just have to bail out. - */ - if (offset > NVHOST_DEBUG_MAX_PAGE_OFFSET) { - nvhost_debug_output(o, "[address mismatch]\n"); - } else { - /* GATHER buffer starts always with commands */ - state = NVHOST_DBG_STATE_CMD; - for (i = 0; i < words; i++) - show_channel_word(o, &state, &count, - phys_addr + i * 4, - *(map_addr + offset/4 + i), - cdma); - } - nvmap_unpin(nvmap->client, &ref); - nvmap_munmap(&ref, map_addr); + do_show_channel_gather(o, phys_addr, words, cdma, + pin_addr, map_addr); + nvmap_unpin(nvmap->client, nvmap->handle); + nvmap_munmap(nvmap->handle, map_addr); #endif } -static void show_channel_pair(struct output *o, u32 addr, - u32 w0, u32 w1, struct nvhost_cdma *cdma) -{ - int state = NVHOST_DBG_STATE_CMD; - int count; - - show_channel_word(o, &state, &count, addr, w0, cdma); - show_channel_word(o, &state, &count, addr+4, w1, cdma); -} - -/** - * Retrieve the op pair at a slot offset from a DMA address - */ -static void cdma_peek(struct nvhost_cdma *cdma, - u32 dmaget, int slot, u32 *out) -{ - u32 offset = dmaget - cdma->push_buffer.phys; - u32 *p = cdma->push_buffer.mapped; - - offset = ((offset + slot * 8) & (PUSH_BUFFER_SIZE - 1)) >> 2; - out[0] = p[offset]; - out[1] = p[offset + 1]; -} - u32 previous_oppair(struct nvhost_cdma *cdma, u32 cur) { u32 pb = cdma->push_buffer.phys; @@ -253,6 +236,42 @@ u32 previous_oppair(struct nvhost_cdma *cdma, u32 cur) return prev; } +void show_channel_gathers(struct output *o, struct nvhost_cdma *cdma) +{ + struct nvhost_job *job; + + list_for_each_entry(job, &cdma->sync_queue, list) { + int i; + nvhost_debug_output(o, "\n%p: JOB, syncpt_id=%d, syncpt_val=%d," + " first_get=%08x, timeout=%d, ctx=%p," + " num_slots=%d, num_handles=%d\n", + job, + job->syncpt_id, + job->syncpt_end, + job->first_get, + job->timeout, + job->hwctx, + job->num_slots, + job->num_unpins); + + for (i = 0; i < job->num_gathers; i++) { + struct nvhost_job_gather *g = &job->gathers[i]; + u32 *mapped = nvmap_mmap(g->ref); + if (!mapped) { + nvhost_debug_output(o, "[could not mmap]\n"); + continue; + } + + nvhost_debug_output(o, " GATHER at %08x, %d words\n", + g->mem, g->words); + + do_show_channel_gather(o, g->mem + g->offset, + g->words, cdma, g->mem, mapped); + nvmap_munmap(g->ref, mapped); + } + } +} + static void t20_debug_show_channel_cdma(struct nvhost_master *m, struct nvhost_channel *ch, struct output *o, int chid) { @@ -261,7 +280,6 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m, u32 dmaput, dmaget, dmactrl; u32 cbstat, cbread; u32 val, base, baseval; - u32 pbw[2]; dmaput = readl(channel->aperture + HOST1X_CHANNEL_DMAPUT); dmaget = readl(channel->aperture + HOST1X_CHANNEL_DMAGET); @@ -310,9 +328,7 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m, dmaput, dmaget, dmactrl); nvhost_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat); - cdma_peek(cdma, dmaget, -1, pbw); - show_channel_pair(o, previous_oppair(cdma, dmaget), - pbw[0], pbw[1], &channel->cdma); + show_channel_gathers(o, cdma); nvhost_debug_output(o, "\n"); } diff --git a/drivers/video/tegra/host/host1x/host1x_syncpt.c b/drivers/video/tegra/host/host1x/host1x_syncpt.c index b7d6587acc61..4cc8e9e212fa 100644 --- a/drivers/video/tegra/host/host1x/host1x_syncpt.c +++ b/drivers/video/tegra/host/host1x/host1x_syncpt.c @@ -103,62 +103,14 @@ static void t20_syncpt_cpu_incr(struct nvhost_syncpt *sp, u32 id) wmb(); } -/* check for old WAITs to be removed (avoiding a wrap) */ -static int t20_syncpt_wait_check(struct nvhost_syncpt *sp, - struct nvmap_client *nvmap, - u32 waitchk_mask, - struct nvhost_waitchk *wait, - int num_waitchk) +/* remove a wait pointed to by patch_addr */ +static int host1x_syncpt_patch_wait(struct nvhost_syncpt *sp, + void *patch_addr) { - u32 idx; - int err = 0; - - /* get current syncpt values */ - for (idx = 0; idx < NV_HOST1X_SYNCPT_NB_PTS; idx++) { - if (BIT(idx) & waitchk_mask) - nvhost_syncpt_update_min(sp, idx); - } - - BUG_ON(!wait && !num_waitchk); - - /* compare syncpt vs wait threshold */ - while (num_waitchk) { - u32 override; - - BUG_ON(wait->syncpt_id >= NV_HOST1X_SYNCPT_NB_PTS); - trace_nvhost_syncpt_wait_check(wait->mem, wait->offset, - wait->syncpt_id, wait->thresh); - if (nvhost_syncpt_is_expired(sp, - wait->syncpt_id, wait->thresh)) { - /* - * NULL an already satisfied WAIT_SYNCPT host method, - * by patching its args in the command stream. The - * method data is changed to reference a reserved - * (never given out or incr) NVSYNCPT_GRAPHICS_HOST - * syncpt with a matching threshold value of 0, so - * is guaranteed to be popped by the host HW. - */ - dev_dbg(&syncpt_to_dev(sp)->dev->dev, - "drop WAIT id %d (%s) thresh 0x%x, min 0x%x\n", - wait->syncpt_id, - syncpt_op().name(sp, wait->syncpt_id), - wait->thresh, - nvhost_syncpt_read_min(sp, wait->syncpt_id)); - - /* patch the wait */ - override = nvhost_class_host_wait_syncpt( - NVSYNCPT_GRAPHICS_HOST, 0); - err = nvmap_patch_word(nvmap, - (struct nvmap_handle *)wait->mem, - wait->offset, override); - if (err) - break; - } - - wait++; - num_waitchk--; - } - return err; + u32 override = nvhost_class_host_wait_syncpt( + NVSYNCPT_GRAPHICS_HOST, 0); + __raw_writel(override, patch_addr); + return 0; } @@ -241,7 +193,7 @@ int host1x_init_syncpt_support(struct nvhost_master *host, op->syncpt.read_wait_base = t20_syncpt_read_wait_base; op->syncpt.update_min = t20_syncpt_update_min; op->syncpt.cpu_incr = t20_syncpt_cpu_incr; - op->syncpt.wait_check = t20_syncpt_wait_check; + op->syncpt.patch_wait = host1x_syncpt_patch_wait; op->syncpt.debug = t20_syncpt_debug; op->syncpt.name = t20_syncpt_name; op->syncpt.mutex_try_lock = syncpt_mutex_try_lock; diff --git a/drivers/video/tegra/host/mpe/mpe.c b/drivers/video/tegra/host/mpe/mpe.c index d8c9da7e9a76..3fe2fcd8bb50 100644 --- a/drivers/video/tegra/host/mpe/mpe.c +++ b/drivers/video/tegra/host/mpe/mpe.c @@ -502,7 +502,7 @@ static void ctxmpe_save_push(struct nvhost_hwctx *nctx, struct host1x_hwctx_handler *h = host1x_hwctx_handler(ctx); nvhost_cdma_push_gather(cdma, nvhost_get_host(nctx->channel->dev)->nvmap, - h->save_buf->handle, + h->save_buf, 0, nvhost_opcode_gather(h->save_size), h->save_phys); diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c index a72e18f16ac7..c87415bf5ac2 100644 --- a/drivers/video/tegra/host/nvhost_cdma.c +++ b/drivers/video/tegra/host/nvhost_cdma.c @@ -53,6 +53,18 @@ static void add_to_sync_queue(struct nvhost_cdma *cdma, job->num_slots = nr_slots; nvhost_job_get(job); list_add_tail(&job->list, &cdma->sync_queue); + + switch (job->priority) { + case NVHOST_PRIORITY_HIGH: + cdma->high_prio_count++; + break; + case NVHOST_PRIORITY_MEDIUM: + cdma->med_prio_count++; + break; + case NVHOST_PRIORITY_LOW: + cdma->low_prio_count++; + break; + } } /** @@ -200,6 +212,19 @@ static void update_cdma_locked(struct nvhost_cdma *cdma) } list_del(&job->list); + + switch (job->priority) { + case NVHOST_PRIORITY_HIGH: + cdma->high_prio_count--; + break; + case NVHOST_PRIORITY_MEDIUM: + cdma->med_prio_count--; + break; + case NVHOST_PRIORITY_LOW: + cdma->low_prio_count--; + break; + } + nvhost_job_put(job); } @@ -371,15 +396,13 @@ int nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job) } static void trace_write_gather(struct nvhost_cdma *cdma, - struct nvmap_handle *handle, + struct nvmap_handle_ref *ref, u32 offset, u32 words) { - struct nvmap_handle_ref ref; void *mem = NULL; if (nvhost_debug_trace_cmdbuf) { - ref.handle = handle; - mem = nvmap_mmap(&ref); + mem = nvmap_mmap(ref); if (IS_ERR_OR_NULL(mem)) mem = NULL; }; @@ -393,12 +416,12 @@ static void trace_write_gather(struct nvhost_cdma *cdma, for (i = 0; i < words; i += TRACE_MAX_LENGTH) { trace_nvhost_cdma_push_gather( cdma_to_channel(cdma)->dev->name, - (u32)handle, + (u32)ref->handle, min(words - i, TRACE_MAX_LENGTH), offset + i * sizeof(u32), mem); } - nvmap_munmap(&ref, mem); + nvmap_munmap(ref, mem); } } @@ -421,7 +444,7 @@ void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2) */ void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, struct nvmap_client *client, - struct nvmap_handle *handle, + struct nvmap_handle_ref *handle, u32 offset, u32 op1, u32 op2) { u32 slots_free = cdma->slots_free; @@ -468,6 +491,12 @@ void nvhost_cdma_end(struct nvhost_cdma *cdma, if (job->timeout && was_idle) cdma_start_timer_locked(cdma, job); + trace_nvhost_cdma_end(job->ch->dev->name, + job->priority, + job->ch->cdma.high_prio_count, + job->ch->cdma.med_prio_count, + job->ch->cdma.low_prio_count); + mutex_unlock(&cdma->lock); } @@ -492,6 +521,8 @@ int nvhost_cdma_flush(struct nvhost_cdma *cdma, int timeout) unsigned int space, err = 0; unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); + trace_nvhost_cdma_flush(cdma_to_channel(cdma)->dev->name, timeout); + /* * Wait for at most timeout ms. Recalculate timeout at each iteration * to better keep within given timeout. diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h index e6f51179150f..2056774a7bc7 100644 --- a/drivers/video/tegra/host/nvhost_cdma.h +++ b/drivers/video/tegra/host/nvhost_cdma.h @@ -48,7 +48,7 @@ struct nvhost_job; struct nvmap_client_handle { struct nvmap_client *client; - struct nvmap_handle *handle; + struct nvmap_handle_ref *handle; }; struct push_buffer { @@ -99,6 +99,9 @@ struct nvhost_cdma { struct buffer_timeout timeout; /* channel's timeout state/wq */ bool running; bool torndown; + int high_prio_count; + int med_prio_count; + int low_prio_count; }; #define cdma_to_channel(cdma) container_of(cdma, struct nvhost_channel, cdma) @@ -113,7 +116,7 @@ int nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job); void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2); void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, struct nvmap_client *client, - struct nvmap_handle *handle, u32 offset, u32 op1, u32 op2); + struct nvmap_handle_ref *handle, u32 offset, u32 op1, u32 op2); void nvhost_cdma_end(struct nvhost_cdma *cdma, struct nvhost_job *job); void nvhost_cdma_update(struct nvhost_cdma *cdma); diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c index ef8886fe4652..ad303cf0a22d 100644 --- a/drivers/video/tegra/host/nvhost_channel.c +++ b/drivers/video/tegra/host/nvhost_channel.c @@ -51,10 +51,26 @@ int nvhost_channel_init(struct nvhost_channel *ch, int nvhost_channel_submit(struct nvhost_job *job) { - /* Low priority submits wait until sync queue is empty. Ignores result - * from nvhost_cdma_flush, as we submit either when push buffer is - * empty or when we reach the timeout. */ - if (job->priority < NVHOST_PRIORITY_MEDIUM) + /* + * Check if queue has higher priority jobs running. If so, wait until + * queue is empty. Ignores result from nvhost_cdma_flush, as we submit + * either when push buffer is empty or when we reach the timeout. + */ + int higher_count = 0; + + switch (job->priority) { + case NVHOST_PRIORITY_HIGH: + higher_count = 0; + break; + case NVHOST_PRIORITY_MEDIUM: + higher_count = job->ch->cdma.high_prio_count; + break; + case NVHOST_PRIORITY_LOW: + higher_count = job->ch->cdma.high_prio_count + + job->ch->cdma.med_prio_count; + break; + } + if (higher_count > 0) (void)nvhost_cdma_flush(&job->ch->cdma, NVHOST_CHANNEL_LOW_PRIO_MAX_WAIT); diff --git a/drivers/video/tegra/host/nvhost_channel.h b/drivers/video/tegra/host/nvhost_channel.h index eac51731547b..b3a904d5a3ee 100644 --- a/drivers/video/tegra/host/nvhost_channel.h +++ b/drivers/video/tegra/host/nvhost_channel.h @@ -31,18 +31,10 @@ #define NVHOST_MAX_POWERGATE_IDS 2 struct nvhost_master; -struct nvhost_waitchk; struct nvhost_device; struct nvhost_channel; struct nvhost_hwctx; -struct nvhost_channel_gather { - u32 words; - phys_addr_t mem; - u32 mem_id; - int offset; -}; - struct nvhost_channel { int refcount; int chid; diff --git a/drivers/video/tegra/host/nvhost_intr.c b/drivers/video/tegra/host/nvhost_intr.c index ba821f694cb4..af2e3ad1bdb5 100644 --- a/drivers/video/tegra/host/nvhost_intr.c +++ b/drivers/video/tegra/host/nvhost_intr.c @@ -128,12 +128,16 @@ static void action_submit_complete(struct nvhost_waitlist *waiter) struct nvhost_channel *channel = waiter->data; int nr_completed = waiter->count; + nvhost_cdma_update(&channel->cdma); + nvhost_module_idle_mult(channel->dev, nr_completed); + /* Add nr_completed to trace */ trace_nvhost_channel_submit_complete(channel->dev->name, - nr_completed, waiter->thresh); + nr_completed, waiter->thresh, + channel->cdma.high_prio_count, + channel->cdma.med_prio_count, + channel->cdma.low_prio_count); - nvhost_cdma_update(&channel->cdma); - nvhost_module_idle_mult(channel->dev, nr_completed); } static void action_ctxsave(struct nvhost_waitlist *waiter) diff --git a/drivers/video/tegra/host/nvhost_job.c b/drivers/video/tegra/host/nvhost_job.c index 71f2ab0e751f..e029449b6184 100644 --- a/drivers/video/tegra/host/nvhost_job.c +++ b/drivers/video/tegra/host/nvhost_job.c @@ -23,9 +23,11 @@ #include <linux/err.h> #include <linux/vmalloc.h> #include <linux/nvmap.h> +#include <trace/events/nvhost.h> #include "nvhost_channel.h" #include "nvhost_job.h" #include "nvhost_hwctx.h" +#include "nvhost_syncpt.h" #include "dev.h" /* Magic to use to fill freed handle slots */ @@ -33,128 +35,44 @@ static int job_size(struct nvhost_submit_hdr_ext *hdr) { - int num_pins = hdr ? (hdr->num_relocs + hdr->num_cmdbufs)*2 : 0; + int num_relocs = hdr ? hdr->num_relocs : 0; int num_waitchks = hdr ? hdr->num_waitchks : 0; + int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0; + int num_unpins = num_cmdbufs + num_relocs; return sizeof(struct nvhost_job) - + num_pins * sizeof(struct nvmap_pinarray_elem) - + num_pins * sizeof(struct nvmap_handle *) - + num_waitchks * sizeof(struct nvhost_waitchk); -} - -static int gather_size(int num_cmdbufs) -{ - return num_cmdbufs * sizeof(struct nvhost_channel_gather); -} - -static void free_gathers(struct nvhost_job *job) -{ - if (job->gathers) { - nvmap_munmap(job->gather_mem, job->gathers); - job->gathers = NULL; - } - if (job->gather_mem) { - nvmap_free(job->nvmap, job->gather_mem); - job->gather_mem = NULL; - } -} - -static int alloc_gathers(struct nvhost_job *job, - int num_cmdbufs) -{ - int err = 0; - - job->gather_mem = NULL; - job->gathers = NULL; - job->gather_mem_size = 0; - - if (num_cmdbufs) { - /* Allocate memory */ - job->gather_mem = nvmap_alloc(job->nvmap, - gather_size(num_cmdbufs), - 32, NVMAP_HANDLE_CACHEABLE, 0); - if (IS_ERR_OR_NULL(job->gather_mem)) { - err = job->gather_mem ? PTR_ERR(job->gather_mem) : -ENOMEM; - job->gather_mem = NULL; - goto error; - } - job->gather_mem_size = gather_size(num_cmdbufs); - - /* Map memory to kernel */ - job->gathers = nvmap_mmap(job->gather_mem); - if (IS_ERR_OR_NULL(job->gathers)) { - err = job->gathers ? PTR_ERR(job->gathers) : -ENOMEM; - job->gathers = NULL; - goto error; - } - } - - return 0; - -error: - free_gathers(job); - return err; -} - -static int realloc_gathers(struct nvhost_job *oldjob, - struct nvhost_job *newjob, - int num_cmdbufs) -{ - int err = 0; - - /* Check if we can reuse gather buffer */ - if (oldjob->gather_mem_size < gather_size(num_cmdbufs) - || oldjob->nvmap != newjob->nvmap) { - free_gathers(oldjob); - err = alloc_gathers(newjob, num_cmdbufs); - } else { - newjob->gather_mem = oldjob->gather_mem; - newjob->gathers = oldjob->gathers; - newjob->gather_mem_size = oldjob->gather_mem_size; - - oldjob->gather_mem = NULL; - oldjob->gathers = NULL; - oldjob->gather_mem_size = 0; - } - return err; + + num_relocs * sizeof(struct nvhost_reloc) + + num_relocs * sizeof(struct nvhost_reloc_shift) + + num_unpins * sizeof(struct nvmap_handle_ref *) + + num_waitchks * sizeof(struct nvhost_waitchk) + + num_cmdbufs * sizeof(struct nvhost_job_gather); } static void init_fields(struct nvhost_job *job, struct nvhost_submit_hdr_ext *hdr, int priority, int clientid) { - int num_pins = hdr ? (hdr->num_relocs + hdr->num_cmdbufs)*2 : 0; + int num_relocs = hdr ? hdr->num_relocs : 0; int num_waitchks = hdr ? hdr->num_waitchks : 0; + int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0; + int num_unpins = num_cmdbufs + num_relocs; void *mem = job; /* First init state to zero */ - job->num_gathers = 0; - job->num_pins = 0; - job->num_unpins = 0; - job->num_waitchk = 0; - job->waitchk_mask = 0; - job->syncpt_id = 0; - job->syncpt_incrs = 0; - job->syncpt_end = 0; job->priority = priority; job->clientid = clientid; - job->null_kickoff = false; - job->first_get = 0; - job->num_slots = 0; /* Redistribute memory to the structs */ mem += sizeof(struct nvhost_job); - if (num_pins) { - job->pinarray = mem; - mem += num_pins * sizeof(struct nvmap_pinarray_elem); - job->unpins = mem; - mem += num_pins * sizeof(struct nvmap_handle *); - } else { - job->pinarray = NULL; - job->unpins = NULL; - } - + job->relocarray = num_relocs ? mem : NULL; + mem += num_relocs * sizeof(struct nvhost_reloc); + job->relocshiftarray = num_relocs ? mem : NULL; + mem += num_relocs * sizeof(struct nvhost_reloc_shift); + job->unpins = num_unpins ? mem : NULL; + mem += num_unpins * sizeof(struct nvmap_handle_ref *); job->waitchk = num_waitchks ? mem : NULL; + mem += num_waitchks * sizeof(struct nvhost_waitchk); + job->gathers = num_cmdbufs ? mem : NULL; /* Copy information from header */ if (hdr) { @@ -172,8 +90,6 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch, int clientid) { struct nvhost_job *job = NULL; - int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0; - int err = 0; job = vzalloc(job_size(hdr)); if (!job) @@ -186,10 +102,6 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch, hwctx->h->get(hwctx); job->nvmap = nvmap ? nvmap_client_get(nvmap) : NULL; - err = alloc_gathers(job, num_cmdbufs); - if (err) - goto error; - init_fields(job, hdr, priority, clientid); return job; @@ -200,46 +112,6 @@ error: return NULL; } -struct nvhost_job *nvhost_job_realloc( - struct nvhost_job *oldjob, - struct nvhost_hwctx *hwctx, - struct nvhost_submit_hdr_ext *hdr, - struct nvmap_client *nvmap, - int priority, int clientid) -{ - struct nvhost_job *newjob = NULL; - int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0; - int err = 0; - - newjob = vzalloc(job_size(hdr)); - if (!newjob) - goto error; - kref_init(&newjob->ref); - newjob->ch = oldjob->ch; - newjob->hwctx = hwctx; - if (hwctx) - newjob->hwctx->h->get(newjob->hwctx); - newjob->timeout = oldjob->timeout; - newjob->nvmap = nvmap ? nvmap_client_get(nvmap) : NULL; - - err = realloc_gathers(oldjob, newjob, num_cmdbufs); - if (err) - goto error; - - nvhost_job_put(oldjob); - - init_fields(newjob, hdr, priority, clientid); - - return newjob; - -error: - if (newjob) - nvhost_job_put(newjob); - if (oldjob) - nvhost_job_put(oldjob); - return NULL; -} - void nvhost_job_get(struct nvhost_job *job) { kref_get(&job->ref); @@ -253,10 +125,6 @@ static void job_free(struct kref *ref) job->hwctxref->h->put(job->hwctxref); if (job->hwctx) job->hwctx->h->put(job->hwctx); - if (job->gathers) - nvmap_munmap(job->gather_mem, job->gathers); - if (job->gather_mem) - nvmap_free(job->nvmap, job->gather_mem); if (job->nvmap) nvmap_client_put(job->nvmap); vfree(job); @@ -280,42 +148,177 @@ void nvhost_job_put(struct nvhost_job *job) void nvhost_job_add_gather(struct nvhost_job *job, u32 mem_id, u32 words, u32 offset) { - struct nvmap_pinarray_elem *pin; - struct nvhost_channel_gather *cur_gather = + struct nvhost_job_gather *cur_gather = &job->gathers[job->num_gathers]; - pin = &job->pinarray[job->num_pins++]; - pin->patch_mem = (u32)nvmap_ref_to_handle(job->gather_mem); - pin->patch_offset = (void *)&(cur_gather->mem) - (void *)job->gathers; - pin->pin_mem = nvmap_convert_handle_u2k(mem_id); - pin->pin_offset = offset; cur_gather->words = words; cur_gather->mem_id = mem_id; cur_gather->offset = offset; job->num_gathers += 1; } -int nvhost_job_pin(struct nvhost_job *job) +static int do_relocs(struct nvhost_job *job, u32 cmdbuf_mem, void *cmdbuf_addr) { - int err = 0; + phys_addr_t target_phys; + int i; + u32 mem_id = 0; + struct nvmap_handle_ref *target_ref = NULL; + + /* pin & patch the relocs for one gather */ + for (i = 0; i < job->num_relocs; i++) { + struct nvhost_reloc *reloc = &job->relocarray[i]; + struct nvhost_reloc_shift *shift = &job->relocshiftarray[i]; + + /* skip all other gathers */ + if (cmdbuf_mem != reloc->cmdbuf_mem) + continue; + + /* check if pin-mem is same as previous */ + if (reloc->target != mem_id) { + target_ref = nvmap_duplicate_handle_id(job->nvmap, + reloc->target); + if (IS_ERR(target_ref)) + return PTR_ERR(target_ref); + + target_phys = nvmap_pin(job->nvmap, target_ref); + if (IS_ERR((void *)target_phys)) { + nvmap_free(job->nvmap, target_ref); + return target_phys; + } + + mem_id = reloc->target; + job->unpins[job->num_unpins++] = target_ref; + } - /* pin mem handles and patch physical addresses */ - job->num_unpins = nvmap_pin_array(job->nvmap, - nvmap_ref_to_handle(job->gather_mem), - job->pinarray, job->num_pins, - job->unpins); - if (job->num_unpins < 0) - err = job->num_unpins; + __raw_writel( + (target_phys + reloc->target_offset) >> shift->shift, + (cmdbuf_addr + reloc->cmdbuf_offset)); + + /* Different gathers might have same mem_id. This ensures we + * perform reloc only once per gather memid. */ + reloc->cmdbuf_mem = 0; + } + + return 0; +} + +/* + * Check driver supplied waitchk structs for syncpt thresholds + * that have already been satisfied and NULL the comparison (to + * avoid a wrap condition in the HW). + */ +static int do_waitchks(struct nvhost_job *job, struct nvhost_syncpt *sp, + u32 patch_mem, void *patch_addr) +{ + int i; + + /* compare syncpt vs wait threshold */ + for (i = 0; i < job->num_waitchk; i++) { + struct nvhost_waitchk *wait = &job->waitchk[i]; + + /* skip all other gathers */ + if (patch_mem != wait->mem) + continue; + + trace_nvhost_syncpt_wait_check(wait->mem, wait->offset, + wait->syncpt_id, wait->thresh, + nvhost_syncpt_read(sp, wait->syncpt_id)); + if (nvhost_syncpt_is_expired(sp, + wait->syncpt_id, wait->thresh)) { + /* + * NULL an already satisfied WAIT_SYNCPT host method, + * by patching its args in the command stream. The + * method data is changed to reference a reserved + * (never given out or incr) NVSYNCPT_GRAPHICS_HOST + * syncpt with a matching threshold value of 0, so + * is guaranteed to be popped by the host HW. + */ + dev_dbg(&syncpt_to_dev(sp)->dev->dev, + "drop WAIT id %d (%s) thresh 0x%x, min 0x%x\n", + wait->syncpt_id, + syncpt_op().name(sp, wait->syncpt_id), + wait->thresh, + nvhost_syncpt_read_min(sp, wait->syncpt_id)); + + /* patch the wait */ + nvhost_syncpt_patch_wait(sp, + (patch_addr + wait->offset)); + } + + wait->mem = 0; + } + return 0; +} + +int nvhost_job_pin(struct nvhost_job *job, struct nvhost_syncpt *sp) +{ + int err = 0, i = 0; + phys_addr_t gather_phys = 0; + void *gather_addr = NULL; + unsigned long waitchk_mask = job->waitchk_mask; + + /* get current syncpt values for waitchk */ + for_each_set_bit(i, &waitchk_mask, sizeof(job->waitchk_mask)) + nvhost_syncpt_update_min(sp, i); + + /* pin gathers */ + for (i = 0; i < job->num_gathers; i++) { + struct nvhost_job_gather *g = &job->gathers[i]; + + /* process each gather mem only once */ + if (!g->ref) { + g->ref = nvmap_duplicate_handle_id(job->nvmap, + job->gathers[i].mem_id); + if (IS_ERR(g->ref)) { + err = PTR_ERR(g->ref); + g->ref = NULL; + break; + } + + gather_phys = nvmap_pin(job->nvmap, g->ref); + if (IS_ERR((void *)gather_phys)) { + nvmap_free(job->nvmap, g->ref); + err = gather_phys; + break; + } + + /* store the gather ref into unpin array */ + job->unpins[job->num_unpins++] = g->ref; + + gather_addr = nvmap_mmap(g->ref); + if (!gather_addr) { + err = -ENOMEM; + break; + } + + err = do_relocs(job, g->mem_id, gather_addr); + if (!err) + err = do_waitchks(job, sp, + g->mem_id, gather_addr); + nvmap_munmap(g->ref, gather_addr); + + if (err) + break; + } + g->mem = gather_phys + g->offset; + } + wmb(); return err; } void nvhost_job_unpin(struct nvhost_job *job) { - nvmap_unpin_handles(job->nvmap, job->unpins, - job->num_unpins); + int i; + + for (i = 0; i < job->num_unpins; i++) { + nvmap_unpin(job->nvmap, job->unpins[i]); + nvmap_free(job->nvmap, job->unpins[i]); + } + memset(job->unpins, BAD_MAGIC, - job->num_unpins * sizeof(struct nvmap_handle *)); + job->num_unpins * sizeof(struct nvmap_handle_ref *)); + job->num_unpins = 0; } /** diff --git a/drivers/video/tegra/host/nvhost_job.h b/drivers/video/tegra/host/nvhost_job.h index ad9d1af60da1..ec1366337279 100644 --- a/drivers/video/tegra/host/nvhost_job.h +++ b/drivers/video/tegra/host/nvhost_job.h @@ -27,7 +27,15 @@ struct nvhost_channel; struct nvhost_hwctx; struct nvmap_client; struct nvhost_waitchk; -struct nvmap_handle; +struct nvhost_syncpt; + +struct nvhost_job_gather { + u32 words; + phys_addr_t mem; + u32 mem_id; + int offset; + struct nvmap_handle_ref *ref; +}; /* * Each submit is tracked as a nvhost_job. @@ -50,10 +58,8 @@ struct nvhost_job { struct nvmap_client *nvmap; /* Gathers and their memory */ - struct nvmap_handle_ref *gather_mem; - struct nvhost_channel_gather *gathers; + struct nvhost_job_gather *gathers; int num_gathers; - int gather_mem_size; /* Wait checks to be processed at submit time */ struct nvhost_waitchk *waitchk; @@ -61,9 +67,10 @@ struct nvhost_job { u32 waitchk_mask; /* Array of handles to be pinned & unpinned */ - struct nvmap_pinarray_elem *pinarray; - int num_pins; - struct nvmap_handle **unpins; + struct nvhost_reloc *relocarray; + struct nvhost_reloc_shift *relocshiftarray; + int num_relocs; + struct nvmap_handle_ref **unpins; int num_unpins; /* Sync point id, number of increments and end related to the submit */ @@ -99,17 +106,6 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch, int priority, int clientid); /* - * Allocate memory for a job. Just enough memory will be allocated to - * accomodate the submit announced in submit header. Gather memory from - * oldjob will be reused, and nvhost_job_put() will be called to it. - */ -struct nvhost_job *nvhost_job_realloc(struct nvhost_job *oldjob, - struct nvhost_hwctx *hwctx, - struct nvhost_submit_hdr_ext *hdr, - struct nvmap_client *nvmap, - int priority, int clientid); - -/* * Add a gather to a job. */ void nvhost_job_add_gather(struct nvhost_job *job, @@ -134,8 +130,11 @@ void nvhost_job_put(struct nvhost_job *job); * Pin memory related to job. This handles relocation of addresses to the * host1x address space. Handles both the gather memory and any other memory * referred to from the gather buffers. + * + * Handles also patching out host waits that would wait for an expired sync + * point value. */ -int nvhost_job_pin(struct nvhost_job *job); +int nvhost_job_pin(struct nvhost_job *job, struct nvhost_syncpt *sp); /* * Unpin memory related to job. diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c index 4835d22881b8..7550512b0214 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.c +++ b/drivers/video/tegra/host/nvhost_syncpt.c @@ -74,7 +74,7 @@ u32 nvhost_syncpt_update_min(struct nvhost_syncpt *sp, u32 id) BUG_ON(!syncpt_op().update_min); - return syncpt_op().update_min(sp, id); + val = syncpt_op().update_min(sp, id); trace_nvhost_syncpt_update_min(id, val); return val; @@ -130,6 +130,19 @@ void nvhost_syncpt_incr(struct nvhost_syncpt *sp, u32 id) } /** + * Updated sync point form hardware, and returns true if syncpoint is expired, + * false if we may need to wait + */ +static bool syncpt_update_min_is_expired( + struct nvhost_syncpt *sp, + u32 id, + u32 thresh) +{ + syncpt_op().update_min(sp, id); + return nvhost_syncpt_is_expired(sp, id, thresh); +} + +/** * Main entrypoint for syncpoint value waits. */ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, @@ -190,9 +203,9 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, while (timeout) { u32 check = min_t(u32, SYNCPT_CHECK_PERIOD, timeout); int remain = wait_event_interruptible_timeout(wq, - nvhost_syncpt_is_expired(sp, id, thresh), + syncpt_update_min_is_expired(sp, id, thresh), check); - if (remain > 0) { + if (remain > 0 || nvhost_syncpt_is_expired(sp, id, thresh)) { if (value) *value = nvhost_syncpt_read_min(sp, id); err = 0; @@ -317,15 +330,10 @@ void nvhost_mutex_unlock(struct nvhost_syncpt *sp, int idx) atomic_dec(&sp->lock_counts[idx]); } -/* check for old WAITs to be removed (avoiding a wrap) */ -int nvhost_syncpt_wait_check(struct nvhost_syncpt *sp, - struct nvmap_client *nvmap, - u32 waitchk_mask, - struct nvhost_waitchk *wait, - int num_waitchk) +/* remove a wait pointed to by patch_addr */ +int nvhost_syncpt_patch_wait(struct nvhost_syncpt *sp, void *patch_addr) { - return syncpt_op().wait_check(sp, nvmap, - waitchk_mask, wait, num_waitchk); + return syncpt_op().patch_wait(sp, patch_addr); } /* Displays the current value of the sync point via sysfs */ diff --git a/drivers/video/tegra/host/nvhost_syncpt.h b/drivers/video/tegra/host/nvhost_syncpt.h index b770ed91c76c..b58921bffa9c 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.h +++ b/drivers/video/tegra/host/nvhost_syncpt.h @@ -136,23 +136,7 @@ static inline int nvhost_syncpt_wait(struct nvhost_syncpt *sp, u32 id, u32 thres MAX_SCHEDULE_TIMEOUT, NULL); } -/* - * Check driver supplied waitchk structs for syncpt thresholds - * that have already been satisfied and NULL the comparison (to - * avoid a wrap condition in the HW). - * - * @param: sp - global shadowed syncpt struct - * @param: nvmap - needed to access command buffer - * @param: mask - bit mask of syncpt IDs referenced in WAITs - * @param: wait - start of filled in array of waitchk structs - * @param: waitend - end ptr (one beyond last valid waitchk) - */ -struct nvhost_waitchk; -int nvhost_syncpt_wait_check(struct nvhost_syncpt *sp, - struct nvmap_client *nvmap, - u32 mask, - struct nvhost_waitchk *wait, - int num_waitchk); +int nvhost_syncpt_patch_wait(struct nvhost_syncpt *sp, void *patch_addr); void nvhost_syncpt_debug(struct nvhost_syncpt *sp); diff --git a/drivers/video/tegra/host/t30/t30.c b/drivers/video/tegra/host/t30/t30.c index 257ba0849277..b2768741546a 100644 --- a/drivers/video/tegra/host/t30/t30.c +++ b/drivers/video/tegra/host/t30/t30.c @@ -95,7 +95,7 @@ struct nvhost_device t30_devices[] = { .waitbases = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1), .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) | BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B), - .clocks = { {"gr2d", UINT_MAX}, + .clocks = { {"gr2d", 0}, {"epp", 0}, {"emc", 300000000} }, NVHOST_MODULE_NO_POWERGATE_IDS, diff --git a/drivers/video/tegra/nvmap/nvmap.c b/drivers/video/tegra/nvmap/nvmap.c index a0c4156668e5..b7fd695d04ee 100644 --- a/drivers/video/tegra/nvmap/nvmap.c +++ b/drivers/video/tegra/nvmap/nvmap.c @@ -352,225 +352,6 @@ static phys_addr_t handle_phys(struct nvmap_handle *h) return addr; } -/* stores the physical address (+offset) of each handle relocation entry - * into its output location. see nvmap_pin_array for more details. - * - * each entry in arr (i.e., each relocation request) specifies two handles: - * the handle to pin (pin), and the handle where the address of pin should be - * written (patch). in pseudocode, this loop basically looks like: - * - * for (i = 0; i < nr; i++) { - * (pin, pin_offset, patch, patch_offset) = arr[i]; - * patch[patch_offset] = address_of(pin) + pin_offset; - * } - */ -static int nvmap_reloc_pin_array(struct nvmap_client *client, - const struct nvmap_pinarray_elem *arr, - int nr, struct nvmap_handle *gather) -{ - struct nvmap_handle *last_patch = NULL; - unsigned int last_pfn = 0; - pte_t **pte; - void *addr; - int i; - - pte = nvmap_alloc_pte(client->dev, &addr); - if (IS_ERR(pte)) - return PTR_ERR(pte); - - for (i = 0; i < nr; i++) { - struct nvmap_handle *patch; - struct nvmap_handle *pin; - phys_addr_t reloc_addr; - phys_addr_t phys; - unsigned int pfn; - - /* all of the handles are validated and get'ted prior to - * calling this function, so casting is safe here */ - pin = (struct nvmap_handle *)arr[i].pin_mem; - - if (arr[i].patch_mem == (unsigned long)last_patch) { - patch = last_patch; - } else if (arr[i].patch_mem == (unsigned long)gather) { - patch = gather; - } else { - if (last_patch) - nvmap_handle_put(last_patch); - - patch = nvmap_get_handle_id(client, arr[i].patch_mem); - if (!patch) { - nvmap_free_pte(client->dev, pte); - return -EPERM; - } - last_patch = patch; - } - - if (patch->heap_pgalloc) { - unsigned int page = arr[i].patch_offset >> PAGE_SHIFT; - phys = page_to_phys(patch->pgalloc.pages[page]); - phys += (arr[i].patch_offset & ~PAGE_MASK); - } else { - phys = patch->carveout->base + arr[i].patch_offset; - } - - pfn = __phys_to_pfn(phys); - if (pfn != last_pfn) { - pgprot_t prot = nvmap_pgprot(patch, pgprot_kernel); - phys_addr_t kaddr = (phys_addr_t)addr; - set_pte_at(&init_mm, kaddr, *pte, pfn_pte(pfn, prot)); - flush_tlb_kernel_page(kaddr); - last_pfn = pfn; - } - - reloc_addr = handle_phys(pin) + arr[i].pin_offset; - reloc_addr >>= arr[i].reloc_shift; - __raw_writel(reloc_addr, addr + (phys & ~PAGE_MASK)); - } - - nvmap_free_pte(client->dev, pte); - - if (last_patch) - nvmap_handle_put(last_patch); - - wmb(); - - return 0; -} - -static int nvmap_validate_get_pin_array(struct nvmap_client *client, - const struct nvmap_pinarray_elem *arr, - int nr, struct nvmap_handle **h) -{ - int i; - int ret = 0; - int count = 0; - - nvmap_ref_lock(client); - - for (i = 0; i < nr; i++) { - struct nvmap_handle_ref *ref; - - if (need_resched()) { - nvmap_ref_unlock(client); - schedule(); - nvmap_ref_lock(client); - } - - ref = _nvmap_validate_id_locked(client, arr[i].pin_mem); - - if (!ref) - nvmap_warn(client, "falied to validate id\n"); - else if (!ref->handle) - nvmap_warn(client, "id had no associated handle\n"); - else if (!ref->handle->alloc) - nvmap_warn(client, "handle had no allocation\n"); - - if (!ref || !ref->handle || !ref->handle->alloc) { - ret = -EPERM; - break; - } - - /* a handle may be referenced multiple times in arr, but - * it will only be pinned once; this ensures that the - * minimum number of sync-queue slots in the host driver - * are dedicated to storing unpin lists, which allows - * for greater parallelism between the CPU and graphics - * processor */ - if (ref->handle->flags & NVMAP_HANDLE_VISITED) - continue; - - ref->handle->flags |= NVMAP_HANDLE_VISITED; - - h[count] = nvmap_handle_get(ref->handle); - BUG_ON(!h[count]); - count++; - } - - nvmap_ref_unlock(client); - - if (ret) { - for (i = 0; i < count; i++) { - h[i]->flags &= ~NVMAP_HANDLE_VISITED; - nvmap_handle_put(h[i]); - } - } - - return ret ?: count; -} - -/* a typical mechanism host1x clients use for using the Tegra graphics - * processor is to build a command buffer which contains relocatable - * memory handle commands, and rely on the kernel to convert these in-place - * to addresses which are understood by the GPU hardware. - * - * this is implemented by having clients provide a sideband array - * of relocatable handles (+ offsets) and the location in the command - * buffer handle to patch with the GPU address when the client submits - * its command buffer to the host1x driver. - * - * the host driver also uses this relocation mechanism internally to - * relocate the client's (unpinned) command buffers into host-addressable - * memory. - * - * @client: nvmap_client which should be used for validation; should be - * owned by the process which is submitting command buffers - * @gather: special handle for relocated command buffer outputs used - * internally by the host driver. if this handle is encountered - * as an output handle in the relocation array, it is assumed - * to be a known-good output and is not validated. - * @arr: array of ((relocatable handle, offset), (output handle, offset)) - * tuples. - * @nr: number of entries in arr - * @unique_arr: list of nvmap_handle objects which were pinned by - * nvmap_pin_array. must be unpinned by the caller after the - * command buffers referenced in gather have completed. - */ -int nvmap_pin_array(struct nvmap_client *client, struct nvmap_handle *gather, - const struct nvmap_pinarray_elem *arr, int nr, - struct nvmap_handle **unique_arr) -{ - int count = 0; - int ret = 0; - int i; - - if (mutex_lock_interruptible(&client->share->pin_lock)) { - nvmap_warn(client, "%s interrupted when acquiring pin lock\n", - current->group_leader->comm); - return -EINTR; - } - - count = nvmap_validate_get_pin_array(client, arr, nr, unique_arr); - if (count < 0) { - mutex_unlock(&client->share->pin_lock); - nvmap_warn(client, "failed to validate pin array\n"); - return count; - } - - for (i = 0; i < count; i++) - unique_arr[i]->flags &= ~NVMAP_HANDLE_VISITED; - - ret = wait_pin_array_locked(client, unique_arr, count); - - mutex_unlock(&client->share->pin_lock); - - if (!ret) - ret = nvmap_reloc_pin_array(client, arr, nr, gather); - - if (WARN_ON(ret)) { - for (i = 0; i < count; i++) - nvmap_handle_put(unique_arr[i]); - return ret; - } else { - for (i = 0; i < count; i++) { - if (unique_arr[i]->heap_pgalloc && - unique_arr[i]->pgalloc.dirty) - map_iovmm_area(unique_arr[i]); - } - } - - return count; -} - phys_addr_t nvmap_pin(struct nvmap_client *client, struct nvmap_handle_ref *ref) { @@ -820,52 +601,3 @@ void nvmap_free(struct nvmap_client *client, struct nvmap_handle_ref *r) nvmap_free_handle_id(client, nvmap_ref_to_id(r)); } - -/* - * create a mapping to the user's buffer and write it - * (uses similar logic from nvmap_reloc_pin_array to map the cmdbuf) - */ -int nvmap_patch_word(struct nvmap_client *client, - struct nvmap_handle *patch, - u32 patch_offset, u32 patch_value) -{ - phys_addr_t phys; - unsigned long kaddr; - unsigned int pfn; - void *addr; - pte_t **pte; - pgprot_t prot; - - if (patch_offset >= patch->size) { - nvmap_warn(client, "read/write outside of handle\n"); - return -EFAULT; - } - - pte = nvmap_alloc_pte(client->dev, &addr); - if (IS_ERR(pte)) - return PTR_ERR(pte); - - /* derive physaddr of cmdbuf WAIT to patch */ - if (patch->heap_pgalloc) { - unsigned int page = patch_offset >> PAGE_SHIFT; - phys = page_to_phys(patch->pgalloc.pages[page]); - phys += (patch_offset & ~PAGE_MASK); - } else { - phys = patch->carveout->base + patch_offset; - } - - pfn = __phys_to_pfn(phys); - prot = nvmap_pgprot(patch, pgprot_kernel); - kaddr = (unsigned long)addr; - - /* write PTE, so addr points to cmdbuf PFN */ - set_pte_at(&init_mm, kaddr, *pte, pfn_pte(pfn, prot)); - flush_tlb_kernel_page(kaddr); - - /* write patch_value to addr + page offset */ - __raw_writel(patch_value, addr + (phys & ~PAGE_MASK)); - - nvmap_free_pte(client->dev, pte); - wmb(); - return 0; -} diff --git a/drivers/video/tegra/nvmap/nvmap.h b/drivers/video/tegra/nvmap/nvmap.h index b0fb70f64a5c..25403f5e7098 100644 --- a/drivers/video/tegra/nvmap/nvmap.h +++ b/drivers/video/tegra/nvmap/nvmap.h @@ -37,6 +37,8 @@ struct nvmap_device; struct page; struct tegra_iovmm_area; +void _nvmap_handle_free(struct nvmap_handle *h); + #if defined(CONFIG_TEGRA_NVMAP) #define nvmap_err(_client, _fmt, ...) \ dev_err(nvmap_client_to_device(_client), \ @@ -162,7 +164,46 @@ static inline void nvmap_ref_unlock(struct nvmap_client *priv) { mutex_unlock(&priv->ref_lock); } -#endif /* CONFIG_TEGRA_NVMAP */ + +static inline struct nvmap_handle *nvmap_handle_get(struct nvmap_handle *h) +{ + if (unlikely(atomic_inc_return(&h->ref) <= 1)) { + pr_err("%s: %s getting a freed handle\n", + __func__, current->group_leader->comm); + if (atomic_read(&h->ref) <= 0) + return NULL; + } + return h; +} + +static inline void nvmap_handle_put(struct nvmap_handle *h) +{ + int cnt = atomic_dec_return(&h->ref); + + if (WARN_ON(cnt < 0)) { + pr_err("%s: %s put to negative references\n", + __func__, current->comm); + } else if (cnt == 0) + _nvmap_handle_free(h); +} + +static inline pgprot_t nvmap_pgprot(struct nvmap_handle *h, pgprot_t prot) +{ + if (h->flags == NVMAP_HANDLE_UNCACHEABLE) + return pgprot_noncached(prot); + else if (h->flags == NVMAP_HANDLE_WRITE_COMBINE) + return pgprot_writecombine(prot); + else if (h->flags == NVMAP_HANDLE_INNER_CACHEABLE) + return pgprot_inner_writeback(prot); + return prot; +} + +#else /* CONFIG_TEGRA_NVMAP */ +struct nvmap_handle *nvmap_handle_get(struct nvmap_handle *h); +void nvmap_handle_put(struct nvmap_handle *h); +pgprot_t nvmap_pgprot(struct nvmap_handle *h, pgprot_t prot); + +#endif /* !CONFIG_TEGRA_NVMAP */ struct device *nvmap_client_to_device(struct nvmap_client *client); @@ -216,51 +257,10 @@ int nvmap_pin_ids(struct nvmap_client *client, void nvmap_unpin_ids(struct nvmap_client *priv, unsigned int nr, const unsigned long *ids); -void _nvmap_handle_free(struct nvmap_handle *h); - int nvmap_handle_remove(struct nvmap_device *dev, struct nvmap_handle *h); void nvmap_handle_add(struct nvmap_device *dev, struct nvmap_handle *h); -#if defined(CONFIG_TEGRA_NVMAP) -static inline struct nvmap_handle *nvmap_handle_get(struct nvmap_handle *h) -{ - if (unlikely(atomic_inc_return(&h->ref) <= 1)) { - pr_err("%s: %s getting a freed handle\n", - __func__, current->group_leader->comm); - if (atomic_read(&h->ref) <= 0) - return NULL; - } - return h; -} - -static inline void nvmap_handle_put(struct nvmap_handle *h) -{ - int cnt = atomic_dec_return(&h->ref); - - if (WARN_ON(cnt < 0)) { - pr_err("%s: %s put to negative references\n", - __func__, current->comm); - } else if (cnt == 0) - _nvmap_handle_free(h); -} - -static inline pgprot_t nvmap_pgprot(struct nvmap_handle *h, pgprot_t prot) -{ - if (h->flags == NVMAP_HANDLE_UNCACHEABLE) - return pgprot_noncached(prot); - else if (h->flags == NVMAP_HANDLE_WRITE_COMBINE) - return pgprot_writecombine(prot); - else if (h->flags == NVMAP_HANDLE_INNER_CACHEABLE) - return pgprot_inner_writeback(prot); - return prot; -} -#else /* CONFIG_TEGRA_NVMAP */ -struct nvmap_handle *nvmap_handle_get(struct nvmap_handle *h); -void nvmap_handle_put(struct nvmap_handle *h); -pgprot_t nvmap_pgprot(struct nvmap_handle *h, pgprot_t prot); -#endif /* !CONFIG_TEGRA_NVMAP */ - int is_nvmap_vma(struct vm_area_struct *vma); struct nvmap_handle_ref *nvmap_alloc_iovm(struct nvmap_client *client, @@ -268,4 +268,4 @@ struct nvmap_handle_ref *nvmap_alloc_iovm(struct nvmap_client *client, void nvmap_free_iovm(struct nvmap_client *client, struct nvmap_handle_ref *r); -#endif +#endif /* __VIDEO_TEGRA_NVMAP_NVMAP_H */ diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c index c78818711f74..9ecce7eeeb17 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev.c +++ b/drivers/video/tegra/nvmap/nvmap_dev.c @@ -973,20 +973,17 @@ static void client_stringify(struct nvmap_client *client, struct seq_file *s) } static void allocations_stringify(struct nvmap_client *client, - struct seq_file *s) + struct seq_file *s, bool iovmm) { - unsigned long base = 0; struct rb_node *n = rb_first(&client->handle_refs); for (; n != NULL; n = rb_next(n)) { struct nvmap_handle_ref *ref = rb_entry(n, struct nvmap_handle_ref, node); struct nvmap_handle *handle = ref->handle; - if (handle->alloc && !handle->heap_pgalloc) { - seq_printf(s, "%-18s %-18s %8lx %10u %8x\n", "", "", - (unsigned long)(handle->carveout->base), - handle->size, handle->userflags); - } else if (handle->alloc && handle->heap_pgalloc) { + if (handle->alloc && handle->heap_pgalloc == iovmm) { + unsigned long base = iovmm ? 0: + (unsigned long)(handle->carveout->base); seq_printf(s, "%-18s %-18s %8lx %10u %8x\n", "", "", base, handle->size, handle->userflags); } @@ -1010,7 +1007,7 @@ static int nvmap_debug_allocations_show(struct seq_file *s, void *unused) get_client_from_carveout_commit(node, commit); client_stringify(client, s); seq_printf(s, " %10u\n", commit->commit); - allocations_stringify(client, s); + allocations_stringify(client, s, false); seq_printf(s, "\n"); total += commit->commit; } @@ -1111,14 +1108,14 @@ static int nvmap_debug_iovmm_allocations_show(struct seq_file *s, void *unused) struct nvmap_device *dev = s->private; spin_lock_irqsave(&dev->clients_lock, flags); - seq_printf(s, "%-18s %18s %8s %10s\n", "CLIENT", "PROCESS", "PID", - "SIZE"); + seq_printf(s, "%-18s %18s %8s %10s %8s\n", "CLIENT", "PROCESS", "PID", + "SIZE", "FLAGS"); seq_printf(s, "%-18s %18s %8s %10s\n", "", "", "BASE", "SIZE"); list_for_each_entry(client, &dev->clients, list) { client_stringify(client, s); seq_printf(s, " %10u\n", atomic_read(&client->iovm_commit)); - allocations_stringify(client, s); + allocations_stringify(client, s, true); seq_printf(s, "\n"); total += atomic_read(&client->iovm_commit); } diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c index 2f24ba515862..56e2dab1820c 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.c +++ b/drivers/video/tegra/nvmap/nvmap_handle.c @@ -38,22 +38,12 @@ #include <mach/iovmm.h> #include <linux/nvmap.h> -#include <linux/vmstat.h> -#include <linux/swap.h> #include <linux/shrinker.h> #include <linux/moduleparam.h> - #include "nvmap.h" #include "nvmap_mru.h" #include "nvmap_common.h" -#define PRINT_CARVEOUT_CONVERSION 0 -#if PRINT_CARVEOUT_CONVERSION -#define PR_INFO pr_info -#else -#define PR_INFO(...) -#endif - #define NVMAP_SECURE_HEAPS (NVMAP_HEAP_CARVEOUT_IRAM | NVMAP_HEAP_IOVMM | \ NVMAP_HEAP_CARVEOUT_VPR) #ifdef CONFIG_NVMAP_HIGHMEM_ONLY @@ -646,36 +636,19 @@ fail: static void alloc_handle(struct nvmap_client *client, struct nvmap_handle *h, unsigned int type) { + unsigned int carveout_mask = NVMAP_HEAP_CARVEOUT_MASK; + unsigned int iovmm_mask = NVMAP_HEAP_IOVMM; + BUG_ON(type & (type - 1)); #ifdef CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM -#define __NVMAP_HEAP_CARVEOUT (NVMAP_HEAP_CARVEOUT_IRAM | NVMAP_HEAP_CARVEOUT_VPR) -#define __NVMAP_HEAP_IOVMM (NVMAP_HEAP_IOVMM | NVMAP_HEAP_CARVEOUT_GENERIC) - if (type & NVMAP_HEAP_CARVEOUT_GENERIC) { -#ifdef CONFIG_NVMAP_ALLOW_SYSMEM - if (h->size <= PAGE_SIZE) { - PR_INFO("###CARVEOUT CONVERTED TO SYSMEM " - "0x%x bytes %s(%d)###\n", - h->size, current->comm, current->pid); - goto sysheap; - } -#endif - PR_INFO("###CARVEOUT CONVERTED TO IOVM " - "0x%x bytes %s(%d)###\n", - h->size, current->comm, current->pid); - } -#else -#define __NVMAP_HEAP_CARVEOUT NVMAP_HEAP_CARVEOUT_MASK -#define __NVMAP_HEAP_IOVMM NVMAP_HEAP_IOVMM + /* Convert generic carveout requests to iovmm requests. */ + carveout_mask &= ~NVMAP_HEAP_CARVEOUT_GENERIC; + iovmm_mask |= NVMAP_HEAP_CARVEOUT_GENERIC; #endif - if (type & __NVMAP_HEAP_CARVEOUT) { + if (type & carveout_mask) { struct nvmap_heap_block *b; -#ifdef CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM - PR_INFO("###IRAM REQUEST RETAINED " - "0x%x bytes %s(%d)###\n", - h->size, current->comm, current->pid); -#endif /* Protect handle from relocation */ nvmap_usecount_inc(h); @@ -689,7 +662,7 @@ static void alloc_handle(struct nvmap_client *client, } nvmap_usecount_dec(h); - } else if (type & __NVMAP_HEAP_IOVMM) { + } else if (type & iovmm_mask) { size_t reserved = PAGE_ALIGN(h->size); int commit = 0; int ret; @@ -713,10 +686,6 @@ static void alloc_handle(struct nvmap_client *client, } } else if (type & NVMAP_HEAP_SYSMEM) { -#if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM) && \ - defined(CONFIG_NVMAP_ALLOW_SYSMEM) -sysheap: -#endif if (handle_page_alloc(client, h, true) == 0) { BUG_ON(!h->pgalloc.contig); h->heap_pgalloc = true; @@ -751,10 +720,6 @@ static const unsigned int heap_policy_large[] = { 0, }; -/* Do not override single page policy if there is not much space to -avoid invoking system oom killer. */ -#define NVMAP_SMALL_POLICY_SYSMEM_THRESHOLD 50000000 - int nvmap_alloc_handle_id(struct nvmap_client *client, unsigned long id, unsigned int heap_mask, size_t align, unsigned int flags) @@ -779,32 +744,22 @@ int nvmap_alloc_handle_id(struct nvmap_client *client, h->align = max_t(size_t, align, L1_CACHE_BYTES); #ifndef CONFIG_TEGRA_IOVMM + /* convert iovmm requests to generic carveout. */ if (heap_mask & NVMAP_HEAP_IOVMM) { - heap_mask &= NVMAP_HEAP_IOVMM; - heap_mask |= NVMAP_HEAP_CARVEOUT_GENERIC; + heap_mask = heap_mask & ~NVMAP_HEAP_IOVMM | + NVMAP_HEAP_CARVEOUT_GENERIC; } #endif -#ifndef CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM #ifdef CONFIG_NVMAP_ALLOW_SYSMEM /* Allow single pages allocations in system memory to save * carveout space and avoid extra iovm mappings */ if (nr_page == 1) { - if (heap_mask & NVMAP_HEAP_IOVMM) + if (heap_mask & + (NVMAP_HEAP_IOVMM | NVMAP_HEAP_CARVEOUT_GENERIC)) heap_mask |= NVMAP_HEAP_SYSMEM; - else if (heap_mask & NVMAP_HEAP_CARVEOUT_GENERIC) { - /* Calculate size of free physical pages - * managed by kernel */ - unsigned long freeMem = - (global_page_state(NR_FREE_PAGES) + - global_page_state(NR_FILE_PAGES) - - total_swapcache_pages) << PAGE_SHIFT; - - if (freeMem > NVMAP_SMALL_POLICY_SYSMEM_THRESHOLD) - heap_mask |= NVMAP_HEAP_SYSMEM; - } } #endif - +#ifndef CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM /* This restriction is deprecated as alignments greater than PAGE_SIZE are now correctly handled, but it is retained for AP20 compatibility. */ diff --git a/include/linux/nvmap.h b/include/linux/nvmap.h index bea59694ad27..553a7bd01a6d 100644 --- a/include/linux/nvmap.h +++ b/include/linux/nvmap.h @@ -28,8 +28,8 @@ #define __user #endif -#ifndef __NVMAP_H -#define __NVMAP_H +#ifndef _LINUX_NVMAP_H +#define _LINUX_NVMAP_H #define NVMAP_HEAP_SYSMEM (1ul<<31) #define NVMAP_HEAP_IOVMM (1ul<<30) @@ -50,20 +50,31 @@ #define NVMAP_HANDLE_SECURE (0x1ul << 2) - #if defined(__KERNEL__) #if defined(CONFIG_TEGRA_NVMAP) struct nvmap_handle; struct nvmap_client; struct nvmap_device; + #define nvmap_ref_to_handle(_ref) (*(struct nvmap_handle **)(_ref)) /* Convert User space handle to Kernel. */ #define nvmap_convert_handle_u2k(h) (h) + +/* handle_ref objects are client-local references to an nvmap_handle; + * they are distinct objects so that handles can be unpinned and + * unreferenced the correct number of times when a client abnormally + * terminates */ +struct nvmap_handle_ref { + struct nvmap_handle *handle; + struct rb_node node; + atomic_t dupes; /* number of times to free on file close */ + atomic_t pin; /* number of times to unpin on free */ +}; + #elif defined(CONFIG_ION_TEGRA) /* For Ion Mem Manager support through nvmap_* API's. */ #include "../../../../../drivers/gpu/ion/ion_priv.h" - #define nvmap_client ion_client #define nvmap_device ion_device #define nvmap_handle ion_handle @@ -76,31 +87,10 @@ struct nvmap_device; BUG(); \ } \ (*((u32 *)h)); }) -#endif - -#define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id)) +#endif /* CONFIG_ION_TEGRA */ -struct nvmap_pinarray_elem { - __u32 patch_mem; - __u32 patch_offset; - __u32 pin_mem; - __u32 pin_offset; - __u32 reloc_shift; -}; - -#if defined(CONFIG_TEGRA_NVMAP) -/* handle_ref objects are client-local references to an nvmap_handle; - * they are distinct objects so that handles can be unpinned and - * unreferenced the correct number of times when a client abnormally - * terminates */ -struct nvmap_handle_ref { - struct nvmap_handle *handle; - struct rb_node node; - atomic_t dupes; /* number of times to free on file close */ - atomic_t pin; /* number of times to unpin on free */ -}; -#endif +#define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id)) struct nvmap_client *nvmap_create_client(struct nvmap_device *dev, const char *name); @@ -127,17 +117,9 @@ phys_addr_t nvmap_handle_address(struct nvmap_client *c, unsigned long id); void nvmap_unpin(struct nvmap_client *client, struct nvmap_handle_ref *r); -int nvmap_pin_array(struct nvmap_client *client, struct nvmap_handle *gather, - const struct nvmap_pinarray_elem *arr, int nr, - struct nvmap_handle **unique); - void nvmap_unpin_handles(struct nvmap_client *client, struct nvmap_handle **h, int nr); -int nvmap_patch_word(struct nvmap_client *client, - struct nvmap_handle *patch, - u32 patch_offset, u32 patch_value); - struct nvmap_handle_ref *nvmap_duplicate_handle_id(struct nvmap_client *client, unsigned long id); @@ -156,6 +138,6 @@ struct nvmap_platform_data { extern struct nvmap_device *nvmap_dev; -#endif +#endif /* __KERNEL__ */ -#endif +#endif /* _LINUX_NVMAP_H */ diff --git a/include/linux/platform_data/tegra_usb.h b/include/linux/platform_data/tegra_usb.h index e6377c379b48..911175086977 100644 --- a/include/linux/platform_data/tegra_usb.h +++ b/include/linux/platform_data/tegra_usb.h @@ -16,33 +16,132 @@ #ifndef _TEGRA_USB_H_ #define _TEGRA_USB_H_ -enum tegra_usb_operating_modes { - TEGRA_USB_DEVICE, - TEGRA_USB_HOST, - TEGRA_USB_OTG, +/** + * defines operation mode of the USB controller + */ +enum tegra_usb_operation_mode { + TEGRA_USB_OPMODE_DEVICE, + TEGRA_USB_OPMODE_HOST, }; -enum tegra_usb_phy_type { - TEGRA_USB_PHY_TYPE_UTMIP = 0, - TEGRA_USB_PHY_TYPE_LINK_ULPI = 1, - TEGRA_USB_PHY_TYPE_NULL_ULPI = 2, - TEGRA_USB_PHY_TYPE_HSIC = 3, - TEGRA_USB_PHY_TYPE_ICUSB = 4, +/** + * defines the various phy interface mode supported by controller + */ +enum tegra_usb_phy_interface { + TEGRA_USB_PHY_INTF_UTMI = 0, + TEGRA_USB_PHY_INTF_ULPI_LINK = 1, + TEGRA_USB_PHY_INTF_ULPI_NULL = 2, + TEGRA_USB_PHY_INTF_HSIC = 3, + TEGRA_USB_PHY_INTF_ICUSB = 4, }; -struct tegra_ehci_platform_data { - enum tegra_usb_operating_modes operating_mode; - /* power down the phy on bus suspend */ - int power_down_on_bus_suspend; - int hotplug; - int default_enable; - void *phy_config; - enum tegra_usb_phy_type phy_type; +/** + * configuration structure for setting up utmi phy + */ +struct tegra_utmi_config { + u8 hssync_start_delay; + u8 elastic_limit; + u8 idle_wait_delay; + u8 term_range_adj; + u8 xcvr_setup; + u8 xcvr_lsfslew; + u8 xcvr_lsrslew; + signed char xcvr_setup_offset; + u8 xcvr_use_fuses; }; -struct tegra_otg_platform_data { +/** + * configuration structure for setting up ulpi phy + */ +struct tegra_ulpi_config { + u8 shadow_clk_delay; + u8 clock_out_delay; + u8 data_trimmer; + u8 stpdirnxt_trimmer; + u8 dir_trimmer; + const char *clk; +}; + +/** + * configuration structure for setting up hsic phy + */ +struct tegra_hsic_config { + u8 sync_start_delay; + u8 idle_wait_delay; + u8 term_range_adj; + u8 elastic_underrun_limit; + u8 elastic_overrun_limit; +}; + +/** + * Platform specific operations that will be controlled + * during the phy operations. + */ +struct tegra_usb_phy_platform_ops { + void (*open)(void); + void (*init)(void); + void (*pre_suspend)(void); + void (*post_suspend)(void); + void (*pre_resume)(void); + void (*post_resume)(void); + void (*pre_phy_off)(void); + void (*post_phy_off)(void); + void (*pre_phy_on)(void); + void (*post_phy_on)(void); + void (*port_power)(void); + void (*close)(void); +}; + +/** + * defines structure for platform dependent device parameters + */ +struct tegra_usb_dev_mode_data { + int vbus_pmu_irq; + int vbus_gpio; + bool charging_supported; + bool remote_wakeup_supported; +}; + +/** + * defines structure for platform dependent host parameters + */ +struct tegra_usb_host_mode_data { + int vbus_gpio; + const char *vbus_reg; + bool hot_plug; + bool remote_wakeup_supported; + bool power_off_on_suspend; +}; + +/** + * defines structure for usb platform data + */ +struct tegra_usb_platform_data { + bool port_otg; + bool has_hostpc; + enum tegra_usb_phy_interface phy_intf; + enum tegra_usb_operation_mode op_mode; + + union { + struct tegra_usb_dev_mode_data dev; + struct tegra_usb_host_mode_data host; + } u_data; + + union { + struct tegra_utmi_config utmi; + struct tegra_ulpi_config ulpi; + struct tegra_hsic_config hsic; + } u_cfg; + + struct tegra_usb_phy_platform_ops *ops; +}; + +/** + * defines structure for platform dependent OTG parameters + */ +struct tegra_usb_otg_data { struct platform_device *ehci_device; - struct tegra_ehci_platform_data *ehci_pdata; + struct tegra_usb_platform_data *ehci_pdata; }; #endif /* _TEGRA_USB_H_ */ diff --git a/include/media/ad5816.h b/include/media/ad5816.h new file mode 100644 index 000000000000..bfea25ffaddf --- /dev/null +++ b/include/media/ad5816.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2011-2012 NVIDIA Corporation. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#ifndef __AD5816_H__ +#define __AD5816_H__ + +#include <media/nvc_focus.h> +#include <media/nvc.h> + +typedef enum ad5816_vreg +{ + AD5816_VREG_VDD = 0, + AD5816_VREG_VDD_AF, + AD5816_VREG_VDD_I2C +}; + +typedef enum ad5816_gpio_types +{ + AD5816_GPIO_RESET = 0, + AD5816_GPIO_I2CMUX, + AD5816_GPIO_GP1, + AD5816_GPIO_GP2, + AD5816_GPIO_GP3 +}; + + +struct ad5816_platform_data { + int cfg; + int num; + int sync; + const char *dev_name; + struct nvc_focus_nvc (*nvc); + struct nvc_focus_cap (*cap); + struct ad5816_pdata_info (*info); + int gpio_count; + struct nvc_gpio_pdata *gpio; +}; + +struct ad5816_pdata_info { + float focal_length; + float fnumber; + __u32 settle_time; + __s16 pos_low; + __s16 pos_high; + __s16 limit_low; + __s16 limit_high; + int move_timeoutms; + __u32 focus_hyper_ratio; + __u32 focus_hyper_div; +}; + +// Register Definitions + +#define IC_INFO 0x00 +#define IC_VERSION 0x01 +#define CONTROL 0x02 +#define VCM_CODE_MSB 0x03 +#define VCM_CODE_LSB 0x04 +#define STATUS 0x05 +#define MODE 0x06 +#define VCM_FREQ 0x07 +#define VCM_THRESHOLD 0x08 + + +#endif +/* __AD5816_H__ */
\ No newline at end of file diff --git a/include/trace/events/nvhost.h b/include/trace/events/nvhost.h index 4bb79e30fc19..6506af44e576 100644 --- a/include/trace/events/nvhost.h +++ b/include/trace/events/nvhost.h @@ -138,6 +138,52 @@ TRACE_EVENT(nvhost_channel_write_cmdbuf, __entry->words, __entry->offset) ); +TRACE_EVENT(nvhost_cdma_end, + TP_PROTO(const char *name, int prio, + int hi_count, int med_count, int low_count), + + TP_ARGS(name, prio, hi_count, med_count, low_count), + + TP_STRUCT__entry( + __field(const char *, name) + __field(int, prio) + __field(int, hi_count) + __field(int, med_count) + __field(int, low_count) + ), + + TP_fast_assign( + __entry->name = name; + __entry->prio = prio; + __entry->hi_count = hi_count; + __entry->med_count = med_count; + __entry->low_count = low_count; + ), + + TP_printk("name=%s, prio=%d, hi=%d, med=%d, low=%d", + __entry->name, __entry->prio, + __entry->hi_count, __entry->med_count, __entry->low_count) +); + +TRACE_EVENT(nvhost_cdma_flush, + TP_PROTO(const char *name, int timeout), + + TP_ARGS(name, timeout), + + TP_STRUCT__entry( + __field(const char *, name) + __field(int, timeout) + ), + + TP_fast_assign( + __entry->name = name; + __entry->timeout = timeout; + ), + + TP_printk("name=%s, timeout=%d", + __entry->name, __entry->timeout) +); + TRACE_EVENT(nvhost_cdma_push, TP_PROTO(const char *name, u32 op1, u32 op2), @@ -194,20 +240,30 @@ TRACE_EVENT(nvhost_cdma_push_gather, ); TRACE_EVENT(nvhost_channel_write_reloc, - TP_PROTO(const char *name), + TP_PROTO(const char *name, u32 cmdbuf_mem, u32 cmdbuf_offset, + u32 target, u32 target_offset), - TP_ARGS(name), + TP_ARGS(name, cmdbuf_mem, cmdbuf_offset, target, target_offset), TP_STRUCT__entry( __field(const char *, name) + __field(u32, cmdbuf_mem) + __field(u32, cmdbuf_offset) + __field(u32, target) + __field(u32, target_offset) ), TP_fast_assign( __entry->name = name; + __entry->cmdbuf_mem = cmdbuf_mem; + __entry->cmdbuf_offset = cmdbuf_offset; + __entry->target = target; + __entry->target_offset = target_offset; ), - TP_printk("name=%s", - __entry->name) + TP_printk("name=%s, cmdbuf_mem=%08x, cmdbuf_offset=%04x, target=%08x, target_offset=%04x", + __entry->name, __entry->cmdbuf_mem, __entry->cmdbuf_offset, + __entry->target, __entry->target_offset) ); TRACE_EVENT(nvhost_channel_write_waitchks, @@ -415,24 +471,32 @@ TRACE_EVENT(nvhost_channel_submitted, ); TRACE_EVENT(nvhost_channel_submit_complete, - TP_PROTO(const char *name, int count, u32 thresh), + TP_PROTO(const char *name, int count, u32 thresh, + int hi_count, int med_count, int low_count), - TP_ARGS(name, count, thresh), + TP_ARGS(name, count, thresh, hi_count, med_count, low_count), TP_STRUCT__entry( __field(const char *, name) __field(int, count) __field(u32, thresh) + __field(int, hi_count) + __field(int, med_count) + __field(int, low_count) ), TP_fast_assign( __entry->name = name; __entry->count = count; __entry->thresh = thresh; + __entry->hi_count = hi_count; + __entry->med_count = med_count; + __entry->low_count = low_count; ), - TP_printk("name=%s, count=%d, thresh=%d", - __entry->name, __entry->count, __entry->thresh) + TP_printk("name=%s, count=%d, thresh=%d, hi=%d, med=%d, low=%d", + __entry->name, __entry->count, __entry->thresh, + __entry->hi_count, __entry->med_count, __entry->low_count) ); TRACE_EVENT(nvhost_wait_cdma, @@ -472,27 +536,30 @@ TRACE_EVENT(nvhost_syncpt_update_min, ); TRACE_EVENT(nvhost_syncpt_wait_check, - TP_PROTO(u32 mem_id, u32 offset, u32 syncpt_id, u32 val), + TP_PROTO(u32 mem_id, u32 offset, u32 syncpt_id, u32 thresh, u32 min), - TP_ARGS(mem_id, offset, syncpt_id, val), + TP_ARGS(mem_id, offset, syncpt_id, thresh, min), TP_STRUCT__entry( __field(u32, mem_id) __field(u32, offset) __field(u32, syncpt_id) - __field(u32, val) + __field(u32, thresh) + __field(u32, min) ), TP_fast_assign( __entry->mem_id = mem_id; __entry->offset = offset; __entry->syncpt_id = syncpt_id; - __entry->val = val; + __entry->thresh = thresh; + __entry->min = min; ), - TP_printk("mem_id=%08x, offset=%05x, id=%d, val=%d", + TP_printk("mem_id=%08x, offset=%05x, id=%d, thresh=%d, current=%d", __entry->mem_id, __entry->offset, - __entry->syncpt_id, __entry->val) + __entry->syncpt_id, __entry->thresh, + __entry->min) ); #endif /* _TRACE_NVHOST_H */ diff --git a/security/tf_driver/Makefile b/security/tf_driver/Makefile index dfadb7d97406..5c48f626f5d8 100644 --- a/security/tf_driver/Makefile +++ b/security/tf_driver/Makefile @@ -21,7 +21,7 @@ # debug options #EXTRA_CFLAGS += -O0 -DDEBUG -D_DEBUG -DCONFIG_TF_DRIVER_DEBUG_SUPPORT EXTRA_CFLAGS += -DNDEBUG -EXTRA_CFLAGS += -DLINUX -DCONFIG_TF_TRUSTZONE -DCONFIG_TFN +EXTRA_CFLAGS += -DLINUX -DCONFIG_TF_TRUSTZONE -DCONFIG_TFN -DCONFIG_SECURE_TRACES ifdef S_VERSION_BUILD EXTRA_CFLAGS += -DS_VERSION_BUILD=$(S_VERSION_BUILD) diff --git a/security/tf_driver/s_version.h b/security/tf_driver/s_version.h index ba4d48c6f417..d812cdca75df 100644 --- a/security/tf_driver/s_version.h +++ b/security/tf_driver/s_version.h @@ -33,12 +33,12 @@ */ #define S_VERSION_OS "A" /* "A" for all Android */ -#define S_VERSION_PLATFORM "A" /* "A" for Tegra2 */ +#define S_VERSION_PLATFORM "B" /* "B" for Tegra3 */ /* * This version number must be updated for each new release */ -#define S_VERSION_MAIN "01.07" +#define S_VERSION_MAIN "01.08" /* * If this is a patch or engineering version use the following diff --git a/security/tf_driver/tf_comm_tz.c b/security/tf_driver/tf_comm_tz.c index 4c89de84accf..4628f24f3cf2 100644 --- a/security/tf_driver/tf_comm_tz.c +++ b/security/tf_driver/tf_comm_tz.c @@ -194,6 +194,20 @@ static inline void tf_smc_nyield(void) tf_smc_generic_call(&generic_smc); } +#ifdef CONFIG_SECURE_TRACES +static void tf_print_secure_traces(struct tf_comm *comm) +{ + spin_lock(&(comm->lock)); + if (comm->l1_buffer->traces_status != 0) { + if (comm->l1_buffer->traces_status > 1) + pr_info("TF : traces lost...\n"); + pr_info("TF : %s", comm->l1_buffer->traces_buffer); + comm->l1_buffer->traces_status = 0; + } + spin_unlock(&(comm->lock)); +} +#endif + /* Yields the Secure World */ int tf_schedule_secure_world(struct tf_comm *comm) { @@ -202,6 +216,10 @@ int tf_schedule_secure_world(struct tf_comm *comm) /* yield to the Secure World */ tf_smc_nyield(); +#ifdef CONFIG_SECURE_TRACES + tf_print_secure_traces(comm); +#endif + return 0; } diff --git a/security/tf_driver/tf_protocol.h b/security/tf_driver/tf_protocol.h index 403df8ec8ef5..b264f04c4454 100644 --- a/security/tf_driver/tf_protocol.h +++ b/security/tf_driver/tf_protocol.h @@ -659,6 +659,10 @@ struct tf_l1_shared_buffer { #ifdef CONFIG_TF_ZEBRA u8 rpc_trace_buffer[140]; u8 rpc_cus_buffer[180]; + #elif CONFIG_SECURE_TRACES + u32 traces_status; + u8 traces_buffer[140]; + u8 reserved3[176]; #else u8 reserved3[320]; #endif diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 9c4346aa265c..7af02a69b8ae 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -1,5 +1,7 @@ GCOV_PROFILE := y +subdir-ccflags-y := -Werror + # Tegra platform Support snd-soc-tegra-pcm-objs := tegra_pcm.o snd-soc-tegra-tdm-pcm-objs := tegra_tdm_pcm.o diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index 0774d360399a..29c4582cfa79 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -50,7 +50,7 @@ static inline u32 tegra20_das_read(u32 reg) } #ifdef CONFIG_PM -int tegra20_das_resume() +int tegra20_das_resume(void) { int i, reg; @@ -67,7 +67,7 @@ int tegra20_das_resume() } #endif -int tegra20_das_set_tristate(int dap_id, int is_tristate) +void tegra20_das_set_tristate(int dap_id, int is_tristate) { enum tegra_pingroup pin; enum tegra_tristate tristate; @@ -86,7 +86,7 @@ int tegra20_das_set_tristate(int dap_id, int is_tristate) pin = TEGRA_PINGROUP_DAP4; break; default: - return -EINVAL; + return; } if (is_tristate) diff --git a/sound/soc/tegra/tegra20_das.h b/sound/soc/tegra/tegra20_das.h index 0d58c7d1bc3f..5cd2d07d43b8 100644 --- a/sound/soc/tegra/tegra20_das.h +++ b/sound/soc/tegra/tegra20_das.h @@ -98,7 +98,7 @@ struct tegra20_das { #ifdef CONFIG_PM /* Restores the das registers from cache */ -extern int tegra20_das_resume(); +extern int tegra20_das_resume(void); #endif /* * Terminology: @@ -143,6 +143,6 @@ extern int tegra20_das_connect_dap_to_dap(int dap_id, int other_dap_sel, */ extern int tegra20_das_connect_dac_to_dap(int dac_id, int dap_sel); -extern int tegra20_das_set_tristate(int dap_id, int is_tristate); +extern void tegra20_das_set_tristate(int dap_id, int is_tristate); #endif diff --git a/sound/soc/tegra/tegra_aic326x.c b/sound/soc/tegra/tegra_aic326x.c index a5c6fc0aecb7..4cacb6758eb8 100644 --- a/sound/soc/tegra/tegra_aic326x.c +++ b/sound/soc/tegra/tegra_aic326x.c @@ -1062,6 +1062,10 @@ static int tegra_aic326x_init(struct snd_soc_pcm_runtime *rtd) if (ret < 0) return ret; + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS_EXT ON"); snd_soc_dapm_force_enable_pin(dapm,"MICBIAS_INT ON"); snd_soc_dapm_sync(dapm); diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index b134f0808afa..6ab5b2d46a1f 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -27,11 +27,14 @@ #include <mach/clk.h> +#include <sound/soc.h> + +#include "tegra_pcm.h" #include "tegra_asoc_utils.h" int g_is_call_mode; -bool tegra_is_voice_call_active() +bool tegra_is_voice_call_active(void) { if (g_is_call_mode) return true; @@ -40,6 +43,115 @@ bool tegra_is_voice_call_active() } EXPORT_SYMBOL_GPL(tegra_is_voice_call_active); +static int tegra_get_avp_device(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = data->avp_device_id; + return 0; +} + +static int tegra_set_avp_device(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + struct snd_soc_card *card = data->card; + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + struct tegra_runtime_data *prtd; + int id, old_id = data->avp_device_id; + + id = ucontrol->value.integer.value[0]; + if ((id >= card->num_rtd) || (id < 0)) + id = -1; + + if (old_id >= 0) { + rtd = &card->rtd[old_id]; + substream = + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (substream && substream->runtime) { + prtd = substream->runtime->private_data; + if (prtd->running) + return -EBUSY; + if (prtd) + prtd->disable_intr = false; + } + } + + if (id >= 0) { + rtd = &card->rtd[id]; + substream = + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (substream && substream->runtime) { + prtd = substream->runtime->private_data; + if (prtd->running) + return -EBUSY; + if (prtd) + prtd->disable_intr = true; + } + } + data->avp_device_id = id; + return 1; +} + +static int tegra_get_dma_ch_id(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + struct snd_soc_card *card = data->card; + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + struct tegra_runtime_data *prtd; + + ucontrol->value.integer.value[0] = -1; + if (data->avp_device_id < 0) + return 0; + + rtd = &card->rtd[data->avp_device_id]; + substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream || !substream->runtime) + return 0; + + prtd = substream->runtime->private_data; + if (!prtd || !prtd->dma_chan) + return 0; + + ucontrol->value.integer.value[0] = + tegra_dma_get_channel_id(prtd->dma_chan); + return 0; +} + +static int tegra_get_dma_addr(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + struct snd_soc_card *card = data->card; + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + + ucontrol->value.integer.value[0] = 0; + if (data->avp_device_id < 0) + return 0; + + rtd = &card->rtd[data->avp_device_id]; + substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream || !substream->runtime) + return 0; + + ucontrol->value.integer.value[0] = substream->runtime->dma_addr; + return 0; +} + +struct snd_kcontrol_new tegra_avp_controls[] = { + SOC_SINGLE_EXT("AVP alsa device select", 0, 0, TEGRA_ALSA_MAX_DEVICES, \ + 0, tegra_get_avp_device, tegra_set_avp_device), + SOC_SINGLE_EXT("AVP DMA channel id", 0, 0, TEGRA_DMA_MAX_CHANNELS, \ + 0, tegra_get_dma_ch_id, NULL), + SOC_SINGLE_EXT("AVP DMA address", 0, 0, 0xFFFFFFFF, \ + 0, tegra_get_dma_addr, NULL), +}; + int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, int mclk) { @@ -152,6 +264,26 @@ int tegra_asoc_utils_clk_disable(struct tegra_asoc_utils_data *data) } EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_disable); +int tegra_asoc_utils_register_ctls(struct tegra_asoc_utils_data *data) +{ + int i; + int ret = 0; + + /* Add AVP related alsa controls */ + data->avp_device_id = -1; + for (i = 0; i < ARRAY_SIZE(tegra_avp_controls); i++) { + ret = snd_ctl_add(data->card->snd_card, + snd_ctl_new1(&tegra_avp_controls[i], data)); + if (ret < 0) { + dev_err(data->dev, "Can't add avp alsa controls"); + return ret; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(tegra_asoc_utils_register_ctls); + int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev, struct snd_soc_card *card) { @@ -276,6 +408,10 @@ void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data) clk_put(data->clk_out1); clk_put(data->clk_cdev1); + /* Just to make sure that clk_cdev1 should turn off in case if it is + * switched on by some codec whose hw switch is not registered.*/ + if (tegra_is_clk_enabled(data->clk_cdev1)) + clk_disable(data->clk_cdev1); if (!IS_ERR(data->clk_pll_a_out0)) clk_put(data->clk_pll_a_out0); diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 512df0d54eb1..0423f02b76cc 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h @@ -25,6 +25,8 @@ #define TEGRA30_I2S_MASTER_PLAYBACK 1 +#define TEGRA_ALSA_MAX_DEVICES 6 +#define TEGRA_DMA_MAX_CHANNELS 32 struct clk; struct device; @@ -41,6 +43,7 @@ struct tegra_asoc_utils_data { int set_baseclock; int set_mclk; int lock_count; + int avp_device_id; }; int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, @@ -52,6 +55,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); int tegra_asoc_utils_clk_enable(struct tegra_asoc_utils_data *data); int tegra_asoc_utils_clk_disable(struct tegra_asoc_utils_data *data); +int tegra_asoc_utils_register_ctls(struct tegra_asoc_utils_data *data); #endif diff --git a/sound/soc/tegra/tegra_max98088.c b/sound/soc/tegra/tegra_max98088.c index 8c0e3935ad02..82c2b930a39e 100644 --- a/sound/soc/tegra/tegra_max98088.c +++ b/sound/soc/tegra/tegra_max98088.c @@ -1009,6 +1009,10 @@ static int tegra_max98088_init(struct snd_soc_pcm_runtime *rtd) if (ret < 0) return ret; + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_nc_pin(dapm, "INA1"); snd_soc_dapm_nc_pin(dapm, "INA2"); snd_soc_dapm_nc_pin(dapm, "INB1"); diff --git a/sound/soc/tegra/tegra_max98095.c b/sound/soc/tegra/tegra_max98095.c index 95295ef4151e..b3bed37ac715 100644 --- a/sound/soc/tegra/tegra_max98095.c +++ b/sound/soc/tegra/tegra_max98095.c @@ -542,6 +542,10 @@ static int tegra_max98095_init(struct snd_soc_pcm_runtime *rtd) tegra_max98095_hp_jack_pins); #endif + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + /* max98095_headset_detect(codec, &tegra_max98095_hp_jack, SND_JACK_HEADSET); */ diff --git a/sound/soc/tegra/tegra_p1852.c b/sound/soc/tegra/tegra_p1852.c index 9506a1c842df..85b4cee30c5f 100644 --- a/sound/soc/tegra/tegra_p1852.c +++ b/sound/soc/tegra/tegra_p1852.c @@ -49,7 +49,8 @@ struct tegra_p1852 { }; static int tegra_p1852_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params, + int codec_id) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; @@ -61,7 +62,6 @@ static int tegra_p1852_hw_params(struct snd_pcm_substream *substream, int i2s_daifmt = 0; int err; struct tegra_p1852_platform_data *pdata; - int codec_id = codec_dai->id; pdata = machine->pdata; @@ -120,15 +120,39 @@ static int tegra_p1852_hw_params(struct snd_pcm_substream *substream, dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } - err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) dev_info(card->dev, "codec_dai clock not set\n"); + if (pdata->codec_info[codec_id].i2s_format == + format_tdm) { + err = snd_soc_dai_set_tdm_slot(cpu_dai, + pdata->codec_info[codec_id].rx_mask, + pdata->codec_info[codec_id].tx_mask, + pdata->codec_info[codec_id].num_slots, + pdata->codec_info[codec_id].slot_width); + if (err < 0) + dev_err(card->dev, "cpu_dai tdm mode setting not done\n"); + } + return 0; } +static int tegra_p1852_hw_params_controller1( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + return tegra_p1852_hw_params(substream, params, 0); +} + +static int tegra_p1852_hw_params_controller2( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + return tegra_p1852_hw_params(substream, params, 1); +} + static int tegra_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -139,8 +163,12 @@ static int tegra_hw_free(struct snd_pcm_substream *substream) return 0; } -static struct snd_soc_ops tegra_p1852_ops = { - .hw_params = tegra_p1852_hw_params, +static struct snd_soc_ops tegra_p1852_ops_controller1 = { + .hw_params = tegra_p1852_hw_params_controller1, + .hw_free = tegra_hw_free, +}; +static struct snd_soc_ops tegra_p1852_ops_controller2 = { + .hw_params = tegra_p1852_hw_params_controller2, .hw_free = tegra_hw_free, }; @@ -149,13 +177,13 @@ static struct snd_soc_dai_link tegra_p1852_dai_link[] = { .name = "I2S-TDM-1", .stream_name = "TEGRA PCM", .platform_name = "tegra-pcm-audio", - .ops = &tegra_p1852_ops, + .ops = &tegra_p1852_ops_controller1, }, { .name = "I2S-TDM-2", .stream_name = "TEGRA PCM", .platform_name = "tegra-pcm-audio", - .ops = &tegra_p1852_ops, + .ops = &tegra_p1852_ops_controller2, } }; diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 1b4b949841aa..f471fafff2ac 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -52,8 +52,8 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = { .channels_min = 1, .channels_max = 2, .period_bytes_min = 128, - .period_bytes_max = PAGE_SIZE, - .periods_min = 2, + .period_bytes_max = PAGE_SIZE * 2, + .periods_min = 1, .periods_max = 8, .buffer_bytes_max = PAGE_SIZE * 8, .fifo_size = 4, @@ -272,6 +272,15 @@ int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) prtd->dma_pos_end = frames_to_bytes(runtime, runtime->periods * runtime->period_size); prtd->period_index = 0; prtd->dma_req_idx = 0; + if (prtd->disable_intr) { + prtd->dma_req_count = 1; + prtd->dma_req[0].complete = NULL; + } else if (!prtd->dma_req[0].complete) { + prtd->dma_req[0].complete = dma_complete_callback; + prtd->dma_req_count = + (MAX_DMA_REQ_COUNT <= runtime->periods) ? + MAX_DMA_REQ_COUNT : runtime->periods; + } /* Fall-through */ case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: @@ -289,8 +298,9 @@ int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) spin_unlock_irqrestore(&prtd->lock, flags); tegra_dma_cancel(prtd->dma_chan); for (i = 0; i < prtd->dma_req_count; i++) { - if (prtd->dma_req[i].status == - -TEGRA_DMA_REQ_ERROR_ABORTED) + if (prtd->dma_req[i].complete && + (prtd->dma_req[i].status == + -TEGRA_DMA_REQ_ERROR_ABORTED)) prtd->dma_req[i].complete(&prtd->dma_req[i]); } break; diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h index 7fe22788004b..b63de32023e8 100644 --- a/sound/soc/tegra/tegra_pcm.h +++ b/sound/soc/tegra/tegra_pcm.h @@ -53,6 +53,7 @@ struct tegra_runtime_data { struct tegra_dma_req dma_req[MAX_DMA_REQ_COUNT]; struct tegra_dma_channel *dma_chan; int dma_req_count; + int disable_intr; }; int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd); diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index 231b0ee61308..765eb59fabae 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -547,6 +547,11 @@ static int tegra_rt5640_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_add_routes(dapm, cardhu_audio_map, ARRAY_SIZE(cardhu_audio_map)); + + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + /* FIXME: Calculate automatically based on DAPM routes? */ snd_soc_dapm_nc_pin(dapm, "LOUTL"); snd_soc_dapm_nc_pin(dapm, "LOUTR"); diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 795356875ba4..f7c7a4c6b5a1 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -379,7 +379,6 @@ static int tegra_bt_call_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); @@ -783,6 +782,10 @@ static int tegra_wm8753_init(struct snd_soc_pcm_runtime *rtd) if (ret < 0) return ret; + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_nc_pin(dapm, "ACIN"); snd_soc_dapm_nc_pin(dapm, "ACOP"); snd_soc_dapm_nc_pin(dapm, "OUT3"); diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index ce608b007bef..147546575233 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -660,6 +660,10 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, machine_is_cardhu() ? SND_JACK_MICROPHONE : 0); + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); /* FIXME: Calculate automatically based on DAPM routes? */ |