From 2c45b9ceabce36f6873f227c09bedc2be9b3ca00 Mon Sep 17 00:00:00 2001 From: Kirill Artamonov Date: Mon, 30 Jan 2012 23:08:37 +0200 Subject: video: tegra: remove free memory check Used free memory check in allocation policy is not working, because it doesn't calculate available physical memory size in same way as android oom killer. It also breaks kernel build if swapping is enabled. Remove free memory check from allocation policy. Change-Id: I214d1829451f313dbace967e87ed4111e688865d Reviewed-on: http://git-master/r/85227 Reviewed-by: Simone Willett Tested-by: Simone Willett --- drivers/video/tegra/nvmap/nvmap_handle.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c index 2f24ba515862..2e2b8b3d46a1 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.c +++ b/drivers/video/tegra/nvmap/nvmap_handle.c @@ -38,11 +38,8 @@ #include #include -#include -#include #include #include - #include "nvmap.h" #include "nvmap_mru.h" #include "nvmap_common.h" @@ -751,10 +748,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) @@ -792,15 +785,7 @@ int nvmap_alloc_handle_id(struct nvmap_client *client, if (heap_mask & NVMAP_HEAP_IOVMM) 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; + heap_mask |= NVMAP_HEAP_SYSMEM; } } #endif -- cgit v1.2.3 From 5abc30ce92eee652cdadc3f88f1496d6941affe6 Mon Sep 17 00:00:00 2001 From: Preetham Chandru Date: Mon, 16 Apr 2012 13:18:57 +0530 Subject: video: tegra: dsi: enable dsi panel B Enable dsi panel B by setting the first bit in APB_MISC_GP_MIPI_PAD_CTRL_0 register. Bug 935764 Signed-off-by: Preetham Chandru R Change-Id: I9e958e0c9d9e934edf77688fd6a987b5e863392b Reviewed-on: http://git-master/r/96672 Reviewed-by: Shashank Sharma Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Kiran Adduri Reviewed-by: Animesh Kishore Reviewed-by: Laxman Dewangan --- drivers/video/tegra/dc/dsi.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 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 #include #include +#include #include #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 */ -- cgit v1.2.3 From a9f373a2b8d3ee1186e94ea7ed89f77e5b33179f Mon Sep 17 00:00:00 2001 From: Preetham Chandru Date: Mon, 16 Apr 2012 15:31:56 +0530 Subject: arm: tegra: cardhu: add TEGRA_CARDHU_DUAL_DSI_PANEL config option add TEGRA_CARDHU_DUAL_DSI_PANEL config option to enable or disable dual dsi panel in cardhu Bug 935764 Signed-off-by: Preetham Chandru R Change-Id: I9a93386c046f5845a3dcf55c575de6b8e67f188d Reviewed-on: http://git-master/r/96706 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 1aa448c44fcd..cb585d97c3b4 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -259,6 +259,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 -- cgit v1.2.3 From 2f8a84dcc28dfb3fc9638dadc6692b8f96c5bb77 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 23 May 2012 13:00:01 +0530 Subject: spi: tegra: cleanup in runtime_pm implementation. Cleaning up runtime pm implementation for the driver. There is lots of duplicate code which is not require as it is handled in the runtime framework. Change-Id: I4494cdd3518cbcb90f24fb3387f38c9859b4f957 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/102206 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas --- drivers/spi/spi-tegra.c | 158 ++++++++++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 86 deletions(-) diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 4901114f746c..0a0a72f3437f 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c @@ -247,6 +247,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) { @@ -731,12 +734,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); @@ -848,6 +846,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 +855,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 +1000,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 */ @@ -1391,17 +1373,20 @@ static int __init spi_tegra_probe(struct platform_device *pdev) 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 err_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; @@ -1424,6 +1409,15 @@ fail_workqueue: spi_unregister_master(master); fail_master_register: + if (tspi->is_clkon_always) + pm_runtime_put_sync(&pdev->dev); + + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_spi_runtime_idle(&pdev->dev); + +err_pm_disable: + pm_runtime_disable(&pdev->dev); + if (tspi->tx_buf) dma_free_coherent(&pdev->dev, tspi->dma_buf_size, tspi->tx_buf, tspi->tx_buf_phys); @@ -1438,7 +1432,6 @@ fail_rx_buf_alloc: if (tspi->rx_dma) tegra_dma_free_channel(tspi->rx_dma); fail_rx_dma_alloc: - pm_runtime_disable(&pdev->dev); clk_put(tspi->sclk); fail_sclk_get: clk_put(tspi->clk); @@ -1474,12 +1467,14 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) if (tspi->rx_dma) tegra_dma_free_channel(tspi->rx_dma); - 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); + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_spi_runtime_idle(&pdev->dev); + clk_put(tspi->sclk); clk_put(tspi->clk); iounmap(tspi->base); @@ -1493,20 +1488,18 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) } #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 +1513,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 +1524,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 +1532,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 +1579,12 @@ 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); + tspi->clk_state = 0; clk_disable(tspi->clk); clk_disable(tspi->sclk); return 0; @@ -1603,22 +1592,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 +1628,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) -- cgit v1.2.3 From 9ef3e8ecc0f1c9a3bfad7c9f4d6a496c4a67924c Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 23 May 2012 19:08:23 +0530 Subject: spi: tegra: synchronize PPSB late write When any write is made to PPSB register, it take time to actual happen in the register due to ARM-PPSB design. Delay or readback is required to make sure that write is completed. There is no worst case guaranteed delay and hence doing the register read to make write completes actually. Change-Id: Iefd25115e1a9f02c64e83f11a4e249ad9d086d16 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/102207 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas --- drivers/spi/spi-tegra.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 0a0a72f3437f..070cc1581efd 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c @@ -264,6 +264,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, @@ -1584,6 +1587,9 @@ static int tegra_spi_runtime_idle(struct device *dev) 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); -- cgit v1.2.3 From 4e88128f3c4c40bf3b6cd1146dffe6a5156fef04 Mon Sep 17 00:00:00 2001 From: Nitin Pai Date: Tue, 22 May 2012 12:04:15 +0530 Subject: asoc: tegra: P1852 machine: Add TDM mode settings Pass TDM mode variables for CPU dai. Codec Id is not passed properly, hence use dual instances of the dai_link operations. Bug 948478 Change-Id: I13188d5001b8f9c2f2f67ee7a9d3bec89311037d Signed-off-by: Bob Johnston Reviewed-on: http://git-master/r/103793 Reviewed-by: Nitin Pai Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra_p1852.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) 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, } }; -- cgit v1.2.3 From 1953361f8e492ea6ec5de23a5321a8eaf000563e Mon Sep 17 00:00:00 2001 From: Jon Mayo Date: Tue, 22 May 2012 17:24:27 -0700 Subject: video: tegra: detect fbmem alignment on probe Detect the stride size used by the bootloader. If DC is not enabled, fallback to a default stride size. Bug 973111 Change-Id: If04647ddf04a44987cd841062ff30e03fa4d6a02 Signed-off-by: Jon Mayo Reviewed-on: http://git-master/r/104031 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/include/mach/dc.h | 1 + drivers/video/tegra/dc/dc.c | 17 +++++++++++++++++ drivers/video/tegra/dc/dc_reg.h | 2 ++ drivers/video/tegra/fb.c | 12 ++++++++---- 4 files changed, 28 insertions(+), 4 deletions(-) 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/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index fb171549f78d..935f18bc8cfd 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 8b84bff45eb3..5eac27adfbf8 100644 --- a/drivers/video/tegra/dc/dc_reg.h +++ b/drivers/video/tegra/dc/dc_reg.h @@ -430,6 +430,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/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; -- cgit v1.2.3 From 3a8779385b7d191287f2e6e81fcc2dbcc1188869 Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Wed, 7 Mar 2012 18:11:54 -0800 Subject: net: wireless: bcm4329: Fix GCC 4.6 warning This module has -Werror turned on, so this was causing the build to break on GCC 4.6: drivers/net/wireless/bcm4329/wl_iw.c: In function 'wl_iw_set_pmksa': drivers/net/wireless/bcm4329/wl_iw.c:5149:5: error: array subscript is above array bounds [-Werror=array-bounds] drivers/net/wireless/bcm4329/wl_iw.c:5152:5: error: array subscript is above array bounds [-Werror=array-bounds] It's a partial 'backport' of a change made to the bcmdhd driver: commit 09a8dc7361d0e603d9935ec7f736fabaa2e6dc7a net: wireless: bcmdhd: Combined P2P fix Change-Id: Ie62ad82f884c213553772ac91eaf85e17a807503 Signed-off-by: Dan Willemsen Reviewed-on: http://git-master/r/88694 GVS: Gerrit_Virtual_Submit Reviewed-by: Stephen Warren --- drivers/net/wireless/bcm4329/wl_iw.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) 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")); -- cgit v1.2.3 From b0071ef15e639e9e4cc6d6e857cd20215f6498c8 Mon Sep 17 00:00:00 2001 From: Krishna Reddy Date: Tue, 22 May 2012 11:19:37 -0700 Subject: nvmap: Use linux conventions. Avoid multiple CONFIG_TEGRA_NVMAP ifdefs. Change-Id: Ic186a8203d8b2291d3d39ce8b612b33bee16f531 Signed-off-by: Krishna Reddy Reviewed-on: http://git-master/r/103937 Reviewed-by: Simone Willett Tested-by: Simone Willett --- include/linux/nvmap.h | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/include/linux/nvmap.h b/include/linux/nvmap.h index bea59694ad27..60ccdc192df5 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,10 +87,10 @@ struct nvmap_device; BUG(); \ } \ (*((u32 *)h)); }) -#endif -#define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id)) +#endif /* CONFIG_ION_TEGRA */ +#define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id)) struct nvmap_pinarray_elem { __u32 patch_mem; @@ -89,19 +100,6 @@ struct nvmap_pinarray_elem { __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 - struct nvmap_client *nvmap_create_client(struct nvmap_device *dev, const char *name); @@ -156,6 +154,6 @@ struct nvmap_platform_data { extern struct nvmap_device *nvmap_dev; -#endif +#endif /* __KERNEL__ */ -#endif +#endif /* _LINUX_NVMAP_H */ -- cgit v1.2.3 From 8ac57e09a6db0eee177b1d923d802b26e197497d Mon Sep 17 00:00:00 2001 From: Krishna Reddy Date: Wed, 23 May 2012 10:00:51 -0700 Subject: arm: tegra: Enable arm errata 764369 Enable arm errata 764369 for TEGRA_2x and 3x. Bug 981223 Bug 885467 Change-Id: Ie013dc1ed4f1417a72dda72ea2d079a6534c3933 Signed-off-by: Krishna Reddy Reviewed-on: http://git-master/r/104181 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index cb585d97c3b4..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 -- cgit v1.2.3 From 64bcd65388b34c8832125b44c0f9b95b0ca755a0 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Fri, 18 May 2012 14:00:51 -0700 Subject: mfd: tps80031: turn on backup battery charger circuit The backup battery for the RTC circuit needs to be manually turned on. This change turns it on when the driver is first probed, off during LP0 to prevent excess power draw, and back on again upon resume. Bug 986402 Change-Id: Id4768929d6a73546662806f04d98d714997174b0 Signed-off-by: Tom Cherry Reviewed-on: http://git-master/r/103425 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Laxman Dewangan --- drivers/mfd/tps80031.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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; -- cgit v1.2.3 From 8e9dc6ce7d8cafba0e65123b2f76320309e8388c Mon Sep 17 00:00:00 2001 From: Ankit Gupta Date: Wed, 23 May 2012 11:55:13 +0530 Subject: asoc: tegra: utils: fix for multiple instances of extern1 clock. The extern1 codec clock was not getting switched off whenever codec goes below BIAS_OFF level. Moreover, there were two instances of extern1 clock whenever codec was on. Reason behind this was that, those codecs for which probe function was called and were not present on board, turned on their extern1 clock, but clean up routine (for switch device register failure) was not able to turn off the clock. With this change, a conditional check is put to turn off the clock. (Bug 984678) Signed-off-by: Ankit Gupta Change-Id: I585ecf73c0cabca856592dcd84e67588dfe13beb Reviewed-on: http://git-master/r/104073 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Ankit Gupta (Engrg-SW) Reviewed-by: Prashant Gaikwad Reviewed-by: Bharat Nihalani --- sound/soc/tegra/tegra_asoc_utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index b134f0808afa..dfbafa061993 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -276,6 +276,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); -- cgit v1.2.3 From dfa3030e767dca384f5d159c6993d5ee25b416d7 Mon Sep 17 00:00:00 2001 From: Mayuresh Kulkarni Date: Mon, 9 Apr 2012 12:21:24 +0530 Subject: video: tegra: host: rewrite nvhost_job_pin/unpin APIs - remove usage of custom interface of nvmap to patch the relocs and and pin the gathers/relocs - convert code that references nvmap_handle to nvmap_handle_ref - add logic to pin and map only unique gathers and relocs - rename nvhost_channel_gather to nvhost_job_gather, because it's used in nvhost_job code only Bug 965206 Change-Id: Iaa7fbac9e4a7b08c0a7c1e184b8dd3566e1edfe2 Signed-off-by: Mayuresh Kulkarni Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/95299 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Juha Tukkinen --- drivers/video/tegra/host/bus_client.c | 17 +- drivers/video/tegra/host/chip_support.h | 4 +- drivers/video/tegra/host/gr3d/gr3d_t20.c | 2 +- drivers/video/tegra/host/gr3d/gr3d_t30.c | 2 +- drivers/video/tegra/host/host1x/host1x_cdma.c | 2 +- drivers/video/tegra/host/host1x/host1x_channel.c | 4 +- drivers/video/tegra/host/host1x/host1x_debug.c | 17 +- drivers/video/tegra/host/mpe/mpe.c | 2 +- drivers/video/tegra/host/nvhost_cdma.c | 12 +- drivers/video/tegra/host/nvhost_cdma.h | 4 +- drivers/video/tegra/host/nvhost_channel.h | 7 - drivers/video/tegra/host/nvhost_job.c | 285 +++++++++-------------- drivers/video/tegra/host/nvhost_job.h | 27 +-- include/trace/events/nvhost.h | 18 +- 14 files changed, 171 insertions(+), 232 deletions(-) diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index fd632a6ea9c5..822f8f3a456d 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -166,7 +166,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, @@ -241,13 +241,17 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, consumed = sizeof(struct nvhost_reloc); if (remaining < consumed) break; - if (copy_from_user(&job->pinarray[job->num_pins], + if (copy_from_user(&job->pinarray[job->num_relocs], buf, consumed)) { err = -EFAULT; break; } - trace_nvhost_channel_write_reloc(chname); - job->num_pins++; + trace_nvhost_channel_write_reloc(chname, + job->pinarray[job->num_relocs].patch_mem, + job->pinarray[job->num_relocs].patch_offset, + job->pinarray[job->num_relocs].pin_mem, + job->pinarray[job->num_relocs].pin_offset); + job->num_relocs++; hdr->num_relocs--; } else if (hdr->num_waitchks) { int numwaitchks = @@ -269,7 +273,7 @@ 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; + job->num_relocs - priv->num_relocshifts; consumed = sizeof(struct nvhost_reloc_shift); if (remaining < consumed) break; @@ -337,6 +341,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..173a36065458 100644 --- a/drivers/video/tegra/host/chip_support.h +++ b/drivers/video/tegra/host/chip_support.h @@ -31,7 +31,7 @@ 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 +77,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); 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..0b4d07cb9e47 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); } diff --git a/drivers/video/tegra/host/host1x/host1x_debug.c b/drivers/video/tegra/host/host1x/host1x_debug.c index 76483d82528b..a5574a0fb60a 100644 --- a/drivers/video/tegra/host/host1x/host1x_debug.c +++ b/drivers/video/tegra/host/host1x/host1x_debug.c @@ -169,32 +169,27 @@ 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) { + || atomic_read(&nvmap->handle->handle->ref) < 1) { 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; } @@ -215,8 +210,8 @@ static void show_channel_gather(struct output *o, u32 addr, *(map_addr + offset/4 + i), cdma); } - nvmap_unpin(nvmap->client, &ref); - nvmap_munmap(&ref, map_addr); + nvmap_unpin(nvmap->client, nvmap->handle); + nvmap_munmap(nvmap->handle, map_addr); #endif } 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..b1f138317cc1 100644 --- a/drivers/video/tegra/host/nvhost_cdma.c +++ b/drivers/video/tegra/host/nvhost_cdma.c @@ -371,15 +371,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 +391,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 +419,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; diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h index e6f51179150f..98393f0cc765 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 { @@ -113,7 +113,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.h b/drivers/video/tegra/host/nvhost_channel.h index eac51731547b..a8f16f0c5abc 100644 --- a/drivers/video/tegra/host/nvhost_channel.h +++ b/drivers/video/tegra/host/nvhost_channel.h @@ -36,13 +36,6 @@ 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_job.c b/drivers/video/tegra/host/nvhost_job.c index 71f2ab0e751f..11d65964e2c9 100644 --- a/drivers/video/tegra/host/nvhost_job.c +++ b/drivers/video/tegra/host/nvhost_job.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "nvhost_channel.h" #include "nvhost_job.h" #include "nvhost_hwctx.h" @@ -33,128 +34,41 @@ 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 nvmap_pinarray_elem) + + 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->pinarray = num_relocs ? mem : NULL; + mem += num_relocs * sizeof(struct nvmap_pinarray_elem); + 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 +86,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 +98,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 +108,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 +121,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 +144,119 @@ 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 patch_mem, void *patch_addr) { - int err = 0; + phys_addr_t pin_phys; + int i; + u32 mem_id = 0; + struct nvmap_handle_ref *pin_ref = NULL; + + /* pin & patch the relocs for one gather */ + for (i = 0; i < job->num_relocs; i++) { + struct nvmap_pinarray_elem *pin = &job->pinarray[i]; + + /* skip all other gathers */ + if (patch_mem != pin->patch_mem) + continue; + + /* check if pin-mem is same as previous */ + if (pin->pin_mem != mem_id) { + pin_ref = nvmap_duplicate_handle_id(job->nvmap, + pin->pin_mem); + if (IS_ERR(pin_ref)) + return PTR_ERR(pin_ref); + + pin_phys = nvmap_pin(job->nvmap, pin_ref); + if (IS_ERR((void *)pin_phys)) { + nvmap_free(job->nvmap, pin_ref); + return pin_phys; + } + + mem_id = pin->pin_mem; + job->unpins[job->num_unpins++] = pin_ref; + } + + __raw_writel((pin_phys + pin->pin_offset) >> pin->reloc_shift, + (patch_addr + pin->patch_offset)); + + /* Different gathers might have same mem_id. This ensures we + * perform reloc only once per gather memid. */ + pin->patch_mem = 0; + } + + return 0; +} - /* 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; +int nvhost_job_pin(struct nvhost_job *job) +{ + int err = 0, i = 0; + phys_addr_t gather_phys = 0; + void *gather_addr = NULL; + + /* 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); + 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..48555a231412 100644 --- a/drivers/video/tegra/host/nvhost_job.h +++ b/drivers/video/tegra/host/nvhost_job.h @@ -29,6 +29,14 @@ struct nvmap_client; struct nvhost_waitchk; struct nvmap_handle; +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; @@ -62,8 +68,8 @@ struct nvhost_job { /* Array of handles to be pinned & unpinned */ struct nvmap_pinarray_elem *pinarray; - int num_pins; - struct nvmap_handle **unpins; + int num_relocs; + struct nvmap_handle_ref **unpins; int num_unpins; /* Sync point id, number of increments and end related to the submit */ @@ -98,17 +104,6 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch, struct nvmap_client *nvmap, 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. */ diff --git a/include/trace/events/nvhost.h b/include/trace/events/nvhost.h index 4bb79e30fc19..6358fedf4482 100644 --- a/include/trace/events/nvhost.h +++ b/include/trace/events/nvhost.h @@ -194,20 +194,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, -- cgit v1.2.3 From ee8c9ce26661e83584f4cb5931b0815d38b2843a Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Wed, 16 May 2012 19:32:28 +0530 Subject: usb: gadget: android: add the handler for ptp class requests Adding the handler for control requests of ptp function driver. Bug 980195 Change-Id: I3ddfc44d7ec4a98d29c7358be1f1d34799f92be9 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/103007 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Venkat Moganty --- drivers/usb/gadget/android.c | 8 ++++++++ 1 file changed, 8 insertions(+) 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, }; -- cgit v1.2.3 From be1e69e5163ba61068d6a6a61e33778f7cf90b42 Mon Sep 17 00:00:00 2001 From: Sudhir Vyas Date: Thu, 17 May 2012 18:51:37 +0530 Subject: media: video: tegra: Add ad5816 focuser driver - Implement new focuser ad5816 driver. - Complies to latest NVC framework. Bug 947792 Change-Id: I1661de027062d2a9b4112fd24dc255d810c7afa0 Signed-off-by: Sudhir Vyas Reviewed-on: http://git-master/r/103131 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Sachin Nikam --- drivers/media/video/tegra/Kconfig | 7 + drivers/media/video/tegra/Makefile | 1 + drivers/media/video/tegra/ad5816.c | 1204 ++++++++++++++++++++++++++++++++++++ include/media/ad5816.h | 81 +++ 4 files changed, 1293 insertions(+) create mode 100644 drivers/media/video/tegra/ad5816.c create mode 100644 include/media/ad5816.h 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 _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 _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 _vregs table in this driver uses the nvc_regulator_init + * structure to define the regulator ID strings that go with the regulators + * defined with _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 _vregs regulator ID strings must match. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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/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 +#include + +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 -- cgit v1.2.3 From 2285ec5a2c09d0f3e0469a65291ffe983918d112 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Tue, 22 May 2012 11:28:12 +0300 Subject: video: tegra: host: Improve timing of syncpt wait nvhost_syncpt_wait_timeout() relies on sync point interrupt to signal reaching the sync point value. With low timeout values, the resolution is not good enough and an error is returned even when the value is reached. Update syncpoint value from hardware when doing a sync point wait and do an explicit check for reaching the value even if wait returns a timeout. bug 984166 bug 986788 bug 987597 Change-Id: I640e32cdcdfa66b8977eac273dd32f62bd72abd6 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/103827 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mayuresh Kulkarni Reviewed-by: Juha Tukkinen --- drivers/video/tegra/host/nvhost_syncpt.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c index 4835d22881b8..1458a7cb5acc 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.c +++ b/drivers/video/tegra/host/nvhost_syncpt.c @@ -129,6 +129,19 @@ void nvhost_syncpt_incr(struct nvhost_syncpt *sp, u32 id) nvhost_module_idle(syncpt_to_dev(sp)->dev); } +/** + * 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. */ @@ -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; -- cgit v1.2.3 From d85b5e5703ef0113cbf10d4c5177a942c9b092ba Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Thu, 24 May 2012 14:59:02 +0530 Subject: usb: tegra: modify USB platform data structures Modify USB structures of platform data. Based on the new platform data structures modifying the initialization in board files. Bug 887361 Change-Id: Ie6347a078c9a596a4debe21a353e127ddde35220 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/103597 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Rohan Somvanshi --- arch/arm/mach-tegra/baseband-xmm-power.c | 1 + arch/arm/mach-tegra/board-cardhu.c | 365 ++++++++++++++++-------- arch/arm/mach-tegra/board-enterprise-baseband.c | 62 ++-- arch/arm/mach-tegra/board-enterprise.c | 260 ++++++++--------- arch/arm/mach-tegra/board-harmony.c | 94 +++--- arch/arm/mach-tegra/board-kai.c | 138 +++++---- arch/arm/mach-tegra/board-p1852.c | 139 +++++---- arch/arm/mach-tegra/board-ventana.c | 207 ++++++++------ arch/arm/mach-tegra/board-whistler-baseband.c | 62 ++-- arch/arm/mach-tegra/board-whistler.c | 138 ++++----- arch/arm/mach-tegra/devices.c | 31 -- arch/arm/mach-tegra/p852/board-p852.c | 140 ++++++--- drivers/misc/tegra-baseband/bb-m7400.c | 15 +- include/linux/platform_data/tegra_usb.h | 139 +++++++-- 14 files changed, 1024 insertions(+), 767 deletions(-) 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 #include #include +#include #include "board.h" #include "board-enterprise.h" #include "devices.h" diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c index 9083828b8352..b57bec4dbf7d 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", @@ -869,135 +832,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 = 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_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); } 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.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 #include #include +#include +#include #include @@ -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..7d3bb90e99f4 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 = { @@ -695,47 +659,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 = true, + .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..1065afe05cca 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}, @@ -349,56 +313,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, - }, - [1] = { - .instance = 1, - .vbus_gpio = -1, +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, }, - [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, }, - [1] = { - .phy_config = &utmi_phy_config[1], - .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 = 15, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, }, - [2] = { - .phy_config = &utmi_phy_config[2], - .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, + }, + .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-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.c b/arch/arm/mach-tegra/board-whistler.c index ede0d0b11104..39ed3eab29ec 100644 --- a/arch/arm/mach-tegra/board-whistler.c +++ b/arch/arm/mach-tegra/board-whistler.c @@ -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,95 @@ 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, +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, }, - [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 = -1, +}; + +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_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_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 whistler_gps_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PU4); - return 0; -} - +#define SERIAL_NUMBER_LENGTH 20 +static char usb_serial_num[SERIAL_NUMBER_LENGTH]; 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/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/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/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 #include #include +#include #include #include #include #include + #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/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_ */ -- cgit v1.2.3 From eeb3cd3b539cf11d998f0a656b64bd8728de0656 Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Thu, 24 May 2012 14:59:34 +0530 Subject: arm: tegra: usb_phy: add common phy interface Refactored the phy interface to scale multiple usb phy hardware versions and for ease of maintenance. Bug 887361 Change-Id: I08ea9e728f760ca123af7777d3ffabbd71a1aa99 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/103598 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venkat Moganty --- arch/arm/mach-tegra/Makefile | 2 + arch/arm/mach-tegra/include/mach/usb_phy.h | 238 +- arch/arm/mach-tegra/tegra2_usb_phy.c | 1598 +++++++++++++ arch/arm/mach-tegra/tegra3_usb_phy.c | 2346 +++++++++++++++++++ arch/arm/mach-tegra/tegra_usb_phy.h | 104 + arch/arm/mach-tegra/usb_phy.c | 3491 ++++------------------------ 6 files changed, 4605 insertions(+), 3174 deletions(-) create mode 100644 arch/arm/mach-tegra/tegra2_usb_phy.c create mode 100644 arch/arm/mach-tegra/tegra3_usb_phy.c create mode 100644 arch/arm/mach-tegra/tegra_usb_phy.h diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index b1b862ff9376..3b046a93edf5 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -38,6 +38,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/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 -#include -#include -#include - -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/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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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_usb_phy.c b/arch/arm/mach-tegra/tegra3_usb_phy.c new file mode 100644 index 000000000000..94c3fb16cd20 --- /dev/null +++ b/arch/arm/mach-tegra/tegra3_usb_phy.c @@ -0,0 +1,2346 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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_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 + +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); +} + +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; +} + +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); +} + +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); +} + +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); + DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x] port_speed[%d]\n", + readl(base + USB_USBSTS), readl(base + USB_PORTSC), + phy->port_speed); + + /* 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); + + /* 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) +{ + 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__); +} + +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); + + /* 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); + } +} + +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); + unsigned int inst = phy->inst; + + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + 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; + + DBG("%s(%d) inst:[%d] BEGIN\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) { + 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); + } + } + + if (phy->inst == 0) { + 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, + 0, 2500)) + pr_warn("%s: timeout waiting for phy to stabilize\n", __func__); + + 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); + + 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; + DBG("%s(%d) End\n", __func__, __LINE__); + + 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 = 3000; /* 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 FPR bit is set automatically on remote resume */ + do { + val = readl(base + USB_PORTSC); + udelay(1); + if (wait_time_us == 0) + return; + wait_time_us--; + } while (!(val & USB_PORTSC_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 (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,3178 +18,624 @@ * GNU General Public License for more details. * */ - #include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 AHB_MEM_PREFETCH_CFG3 0xe0 -#define AHB_MEM_PREFETCH_CFG4 0xe4 -#define AHB_MEM_PREFETCH_CFG1 0xec -#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) -{ - 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); - } - - if (phy->instance == 0) { - phy->pad_regs = phy->regs; - } 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; - } - } - return 0; -} - -static void utmip_pad_close(struct tegra_usb_phy *phy) -{ - 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); - } - - 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) -{ - 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) -{ -#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 -} - -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; - - 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); -} - -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); -} - -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); -} -#endif - -static unsigned int tegra_phy_xcvr_setup_value(struct tegra_utmip_config *cfg) -{ - 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; -} - -static int utmi_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) -{ - 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 - - 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); - } - - 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); - } -#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); - } - - 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)); - } - 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)); - } - - /* 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); -} -#endif - -static int utmi_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) -{ - 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); - } - - 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); - } - - 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); - } - 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); - } - - utmi_phy_clk_disable(phy); - - utmip_pad_power_off(phy, true); - return 0; -} - -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 -} - -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; - } -#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 - } -} - - -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; - } - } - 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); - } -#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; - } - } - 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 - - - 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; - - 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 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; - - 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; - - 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->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; - } - 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); - - val = readl(base + ULPI_TIMING_CTRL_0); - val &= ~ULPI_OUTPUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); -#endif -} - -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) -{ - 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); - - 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 - } - - 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); - - 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; - } - - 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->clk) - clk_disable(phy->clk); +#include +#include +#include +#include +#include +#include +#include +#include "tegra_usb_phy.h" +#include - return 0; -} +#define ERR(stuff...) pr_err("usb_phy: " stuff) +#define WARNING(stuff...) pr_warning("usb_phy: " stuff) +#define INFO(stuff...) pr_info("usb_phy: " stuff) -static inline void null_phy_set_tristate(bool enable) -{ - int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL; +#define AHB_MEM_PREFETCH_CFG3 0xe0 +#define AHB_MEM_PREFETCH_CFG4 0xe4 +#define AHB_MEM_PREFETCH_CFG1 0xec +#define AHB_MEM_PREFETCH_CFG2 0xf0 +#define PREFETCH_ENB (1 << 31) -#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); +#ifdef DEBUG +#define DBG(stuff...) pr_info("usb_phy: " stuff) #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); +#define DBG(stuff...) do {} while (0) #endif -} -static void null_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) +static void print_usb_plat_data_info(struct tegra_usb_phy *phy) { - struct tegra_ulpi_config *config = phy->config; + 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 (config->phy_restore_start) - config->phy_restore_start(); + 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 { + 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"); + } } -static void null_phy_restore_end(struct tegra_usb_phy *phy) +static void usb_host_vbus_enable(struct tegra_usb_phy *phy, bool enable) { - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_ulpi_config *config = phy->config; - - /* disable ULPI pinmux bypass */ - ulpi_pinmux_bypass(phy, false); - - /* 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 - - /* 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 (retry == 0) - pr_info("phy_restore_gpio timeout\n"); + 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); } - - /* 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 } -static int null_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) +int usb_phy_reg_status_wait(void __iomem *reg, u32 mask, + u32 result, u32 timeout) { - 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; - } - - /* set ULPI trimmers */ - ulpi_set_trimmer(base, config->trimmer->data_trimmer, - config->trimmer->stpdirnxt_trimmer, 1); - - ulpi_set_host(base); - -#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; - } - - udelay(10); - - if (config->post_phy_on && config->post_phy_on()) - return -EAGAIN; + do { + if ((readl(reg) & mask) == result) + return 0; + udelay(1); + timeout--; + } while (timeout); - return 0; + return -1; } -static int null_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) +int tegra_usb_phy_init_ops(struct tegra_usb_phy *phy) { - struct tegra_ulpi_config *config = phy->config; - - if (config->pre_phy_off && config->pre_phy_off()) - return -EAGAIN; + int err = 0; - null_phy_set_tristate(true); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - if (config->post_phy_off && config->post_phy_off()) - return -EAGAIN; + if (phy->pdata->has_hostpc) + err = tegra3_usb_phy_init_ops(phy); + else + err = tegra2_usb_phy_init_ops(phy); - return 0; + return err; } -static int null_phy_pre_usbcmd_reset(struct tegra_usb_phy *phy, bool is_dpd) +static irqreturn_t usb_phy_dev_vbus_pmu_irq_thr(int irq, void *pdata) { -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - unsigned long val; - void __iomem *base = phy->regs; + /* FIXME : Need to enable pmu vbus handling */ - 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; + return IRQ_NONE; } -static int null_phy_post_usbcmd_reset(struct tegra_usb_phy *phy, bool is_dpd) +static void tegra_usb_phy_release_clocks(struct tegra_usb_phy *phy) { -#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; + 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 uhsic_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; - struct tegra_uhsic_config *uhsic_config = phy->config; - -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - uhsic_powerup_pmc_wake_detect(phy); -#endif + int err = 0; - if (uhsic_config->enable_gpio != -1) { - gpio_set_value_cansleep(uhsic_config->enable_gpio, 1); - /* keep hsic reset asserted for 1 ms */ - udelay(1000); + 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); - 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); + 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; + } - val = readl(base + UHSIC_MISC_CFG1); - val |= UHSIC_PLLU_STABLE_COUNT(phy->freq->stable_count); - writel(val, base + UHSIC_MISC_CFG1); + 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); - 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); + 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 + USB_SUSP_CTRL); - val &= ~(UHSIC_RESET); - writel(val, base + USB_SUSP_CTRL); - udelay(2); + if(phy->pdata->has_hostpc) + clk_set_rate(phy->emc_clk, 100000000); + else + clk_set_rate(phy->emc_clk, 300000000); -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - val = readl(base + USB_PORTSC1); - val &= ~USB_PORTSC1_PTS(~0); - writel(val, base + USB_PORTSC1); + return err; -#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); +fail_emc: + clk_put(phy->sys_clk); - val = readl(base + USB_PORTSC1); - val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN); - writel(val, base + USB_PORTSC1); +fail_sclk: + clk_put(phy->ctrlr_clk); - 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); +fail_ctrlr_clk: + clk_disable(phy->pllu_clk); + clk_put(phy->pllu_clk); - 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; - } +fail_pll: - return 0; + return err; } -static int uhsic_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; - 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 (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 + struct tegra_usb_phy *phy; + struct tegra_usb_platform_data *pdata; + struct resource *res; + int err; - return 0; -} + 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); + } -#ifdef CONFIG_USB_TEGRA_OTG -extern void tegra_otg_check_vbus_detection(void); -#endif + 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); + } -static irqreturn_t usb_phy_vbus_irq_thr(int irq, void *pdata) -{ - 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); + 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); } -#ifdef CONFIG_USB_TEGRA_OTG - tegra_otg_check_vbus_detection(); -#endif + memcpy(phy->pdata, pdata, sizeof(struct tegra_usb_platform_data)); + phy->pdev = pdev; + phy->inst = pdev->id; - return IRQ_HANDLED; -} + print_usb_plat_data_info(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) -{ - 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 + 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; + } - phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); - if (!phy) - return ERR_PTR(-ENOMEM); + 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; + } - 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]; - } + 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; } - 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; + err = tegra_usb_phy_get_clocks(phy); + if (err) { + ERR("inst:[%d] Failed to init clocks\n", phy->inst); + goto fail_clk; } - 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; + + 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 { - 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->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; + 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 { - /* Some USB ULPI chips are not driven by Tegra clocks or PLL */ - phy->clk = NULL; + 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; + } + } } - 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); + usb_host_vbus_enable(phy, true); } -#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; + err = tegra_usb_phy_init_ops(phy); + if (err) { + ERR("inst:[%d] Failed to init ops\n", phy->inst); + goto fail_init; } - 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 (phy->pdata->ops && phy->pdata->ops->open) + phy->pdata->ops->open(); + + if (phy->ops && phy->ops->open) { + err = phy->ops->open(phy); if (err) { - pr_err("Failed to register IRQ\n"); - goto err1; + ERR("inst:[%d] Failed to open hw ops\n", phy->inst); + goto fail_init; } } -#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->vdd_reg) + regulator_enable(phy->vdd_reg); + + return phy; + +fail_init: + tegra_usb_phy_release_clocks(phy); + + 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); } } } - 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: +fail_clk: + regulator_put(phy->vdd_reg); + iounmap(phy->regs); +fail_io: kfree(phy); + return ERR_PTR(err); } -int tegra_usb_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd) -{ - 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, - }; - if (phy->power_on) - return ret; +void tegra_usb_phy_close(struct tegra_usb_phy *phy) +{ + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + 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); + } + } + } - if ((phy->instance == 0) && usb_phy_data[0].vbus_irq && - (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)) - is_dpd = true; + tegra_usb_phy_release_clocks(phy); - if (phy->reg_vdd && !phy->regulator_on) { - regulator_enable(phy->reg_vdd); - phy->regulator_on = 1; + if (phy->vdd_reg) { + regulator_disable(phy->vdd_reg); + regulator_put(phy->vdd_reg); } - if (power_on[phy->usb_phy_type]) - ret = power_on[phy->usb_phy_type](phy, is_dpd); + if (phy->ops && phy->ops->close) + phy->ops->close(phy); - phy->power_on = true; - return ret; + if (phy->pdata->ops && phy->pdata->ops->close) + phy->pdata->ops->close(); + + kfree(phy->pdata); + kfree(phy); } -void tegra_usb_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd) +irqreturn_t tegra_usb_phy_irq(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, - }; + irqreturn_t status = IRQ_HANDLED; + + if (phy->ops && phy->ops->irq) + status = phy->ops->irq(phy); - if (!phy->power_on) - return; + return status; +} +int tegra_usb_phy_init(struct tegra_usb_phy *phy) +{ + int status = 0; - if ((phy->instance == 0) && usb_phy_data[0].vbus_irq && - (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)) - is_dpd = true; + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - if (power_off[phy->usb_phy_type]) - power_off[phy->usb_phy_type](phy, is_dpd); + if (phy->pdata->ops && phy->pdata->ops->init) + phy->pdata->ops->init(); - 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; + if (phy->ops && phy->ops->init) + status = phy->ops->init(phy); + + return status; } -void tegra_usb_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup) +int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) { - const tegra_phy_fp preresume[] = { - utmi_phy_preresume, - NULL, - NULL, - uhsic_phy_preresume, - }; + int err = 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->phy_power_on) + return err; -{ - const tegra_phy_fp postsuspend[] = { - NULL, - NULL, - NULL, - uhsic_phy_postsuspend, - }; + 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(); + } - if (postsuspend[phy->usb_phy_type]) - postsuspend[phy->usb_phy_type](phy, is_dpd); + clk_disable(phy->emc_clk); + clk_disable(phy->sys_clk); + clk_disable(phy->ctrlr_clk); + + phy->phy_power_on = false; + + return err; } -void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd) +int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) { - const tegra_phy_fp postresume[] = { - utmi_phy_postresume, - NULL, - NULL, - NULL, - }; + int status = 0; - usb_phy_set_tx_fill_tuning(phy, is_dpd); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - // If Phy type is utmi, call its post resume - if (phy->usb_phy_type == 0) - utmi_phy_postresume(phy, is_dpd); -} + if (phy->phy_power_on) + return status; -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, - }; + clk_enable(phy->ctrlr_clk); + clk_enable(phy->sys_clk); + clk_enable(phy->emc_clk); - if (pre_reset[phy->usb_phy_type]) - pre_reset[phy->usb_phy_type](phy, is_dpd); -} + 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(); + } -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, - }; + phy->phy_power_on = true; - if (post_reset[phy->usb_phy_type]) - post_reset[phy->usb_phy_type](phy, is_dpd); + return status; } -void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) +int tegra_usb_phy_reset(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); + if (phy->ops && phy->ops->reset) + status = phy->ops->reset(phy); -void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) + return status; +} +int tegra_usb_phy_pre_suspend(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, - }; + int status = 0; - if (phy_restore_end[phy->usb_phy_type]) - phy_restore_end[phy->usb_phy_type](phy); -} + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); -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); -} + if (phy->pdata->ops && phy->pdata->ops->pre_suspend) + phy->pdata->ops->pre_suspend(); -void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy) -{ - if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) - utmi_phy_clk_enable(phy); -} + if (phy->ops && phy->ops->pre_suspend) + status = phy->ops->pre_suspend(phy); -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); + return status; } - -int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy) +int tegra_usb_phy_suspend(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); + int err = 0; - val = readl(base + UHSIC_MISC_CFG0); - val |= UHSIC_FORCE_XCVR_MODE; - writel(val, base + UHSIC_MISC_CFG0); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - 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; - } + if (phy->ops && phy->ops->suspend) + err = phy->ops->suspend(phy); -#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 (!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(); } - return 0; + return err; } - -int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy) +int tegra_usb_phy_post_suspend(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 (phy->ops && phy->ops->post_suspend) + status = phy->ops->post_suspend(phy); - 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; - } + if (phy->pdata->ops && phy->pdata->ops->post_suspend) + phy->pdata->ops->post_suspend(); - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPU_STROBE; - val |= UHSIC_RPD_STROBE; - writel(val, base + UHSIC_PADS_CFG1); + return status; +} +int tegra_usb_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup) +{ + int status = 0; - mdelay(50); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPD_STROBE; - val |= UHSIC_RPU_STROBE; - writel(val, base + UHSIC_PADS_CFG1); + if (phy->pdata->ops && phy->pdata->ops->pre_resume) + phy->pdata->ops->pre_resume(); - val = readl(base + USB_USBCMD); - val |= USB_USBCMD_RS; - writel(val, base + USB_USBCMD); + if (phy->ops && phy->ops->pre_resume) + status = phy->ops->pre_resume(phy, remote_wakeup); - val = readl(base + UHSIC_PADS_CFG1); - val &= ~UHSIC_RPU_STROBE; - writel(val, base + UHSIC_PADS_CFG1); + return status; +} +int tegra_usb_phy_resume(struct tegra_usb_phy *phy) +{ + int err = 0; - 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; - } + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + 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(); } - return 0; -} + if (!err && phy->ops && phy->ops->resume) + err = phy->ops->resume(phy); -int tegra_usb_phy_bus_idle(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); + return err; - 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; } - -bool tegra_usb_phy_is_device_connected(struct tegra_usb_phy *phy) +int tegra_usb_phy_post_resume(struct tegra_usb_phy *phy) { - void __iomem *base = phy->regs; + int status = 0; - 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; -} + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); + + if (phy->ops && phy->ops->post_resume) + status = phy->ops->post_resume(phy); + + if (phy->pdata->ops && phy->pdata->ops->post_resume) + phy->pdata->ops->post_resume(); -bool tegra_usb_phy_charger_detect(struct tegra_usb_phy *phy) + return status; +} +int tegra_usb_phy_port_power(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; - } + int status = 0; - /* 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); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - /* Source should be on for 100 ms as per USB charging spec */ - msleep(TDP_SRC_ON_MS); + if (phy->ops && phy->ops->port_power) + status = phy->ops->port_power(phy); - 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); + if (phy->pdata->ops && phy->pdata->ops->port_power) + phy->pdata->ops->port_power(); - val = readl(base + USB_PHY_VBUS_WAKEUP_ID); - if (val & VDAT_DET_STS) - status = true; - else - status = false; + return status; +} +int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy) +{ + int status = 0; - /* 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); + DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); - /* Delay of 40 ms before we pull the D+ as per battery charger spec */ - msleep(TDPSRC_CON_MS); + if (phy->ops && phy->ops->bus_reset) + status = phy->ops->bus_reset(phy); return status; } -#ifndef CONFIG_ARCH_TEGRA_2x_SOC -void tegra_usb_phy_power_down_pmc(void) +bool tegra_usb_phy_charger_detected(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); + bool status = 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; } -#endif -int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size) +bool tegra_usb_phy_hw_accessible(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; - } - } + if (!phy->hw_accessible) + DBG("%s(%d) inst:[%d] Not Accessible\n", __func__, + __LINE__, phy->inst); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - tegra_usb_phy_power_down_pmc(); -#endif + return phy->hw_accessible; +} + +bool tegra_usb_phy_remote_wakeup(struct tegra_usb_phy *phy) +{ + return phy->remote_wakeup; +} + +bool tegra_usb_phy_has_hostpc(struct tegra_usb_phy *phy) +{ + return phy->pdata->has_hostpc; +} - return 0; +bool tegra_usb_phy_otg_supported(struct tegra_usb_phy *phy) +{ + 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; -} - -- cgit v1.2.3 From 4e8c072c5b697b9893273d054c82e12026cf2907 Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Tue, 22 May 2012 11:31:14 +0530 Subject: usb: host: tegra: update ehci to use common phy Following enhancements are done: a. Update driver with common phy interface b. Make host driver independent of phy type and remove unnecessary CONFIG variables. Bug 887361 Change-Id: Ibafa37a048df4377b73029039b04d04a53020bd4 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/103599 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venkat Moganty GVS: Gerrit_Virtual_Submit --- drivers/usb/host/ehci-hub.c | 12 +- drivers/usb/host/ehci-tegra.c | 1376 ++++++++--------------------------------- drivers/usb/host/ehci.h | 1 + 3 files changed, 264 insertions(+), 1125 deletions(-) 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..82523bd200a6 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 #include #include #include @@ -24,191 +23,146 @@ #include #include -#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 -#else -#define TEGRA_USB_PORTSC1_OFFSET 0x174 -#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 (!(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); - if (!tegra->default_enable) - clk_enable(tegra->clk); - tegra_usb_phy_power_on(tegra->phy, is_dpd); - tegra->host_resumed = 1; + 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; + + /* 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; - tegra->host_resumed = 0; - tegra_usb_phy_power_off(tegra->phy, is_dpd); - if (!tegra->default_enable) - clk_disable(tegra->clk); + /* 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; + int ret; - 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); + ret = alloc_align_buffer(urb, mem_flags); + if (ret) + return ret; - /* - * 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; + 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); irq_status = ehci_irq(hcd); @@ -220,561 +174,112 @@ static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) 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 */ - if (tegra->port_resuming) { - int delay = ehci->reset_done[wIndex-1] - jiffies; - /* Sometimes it seems we get called too soon... In that case, wait.*/ - if (delay > 0) { - ehci_dbg(ehci, "GetPortStatus called too soon, waiting %dms...\n", delay); - mdelay(jiffies_to_msecs(delay)); - } - /* 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__); + /* Do tegra phy specific actions based on the type request */ + switch (typeReq) { + case GetPortStatus: + if (time_after_eq(jiffies, ehci->reset_done[wIndex - 1])) { + if (tegra->port_resuming) { + int delay = ehci->reset_done[wIndex-1] - jiffies; + /* Sometimes it seems we get called too soon... In that case, wait.*/ + if (delay > 0) { + ehci_dbg(ehci, "GetPortStatus called too soon, waiting %dms...\n", delay); + mdelay(jiffies_to_msecs(delay)); + } + /* 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; + /* If run bit is not set by now enable it */ + if (ehci->command & CMD_RUN) { + ehci->command |= CMD_RUN; + ehci_writel(ehci, ehci->command, + &ehci->regs->command); + } } - tegra->port_resuming = 0; - tegra_usb_phy_postresume(tegra->phy, false); - if (tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) { - 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); - } - } - - } 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; } + spin_unlock_irqrestore(&ehci->lock, flags); - /* - * 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) { + spin_lock_irqsave(&ehci->lock, flags); + 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); } - 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) -{ - 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 ehci_hcd *ehci = hcd_to_ehci(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 +291,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 +314,46 @@ 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; + int err = 0; - mutex_lock(&tegra->tegra_ehci_hcd_mutex); + 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); - 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; - 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_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 +363,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 +380,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 +391,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 +422,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 +528,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 +536,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 +559,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 */ -- cgit v1.2.3 From 86c5f5fb289804f915fcd23ee812a1013be2e525 Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Mon, 21 May 2012 16:35:11 +0530 Subject: usb: gadget: tegra: update udc driver to use common phy Update the udc driver to use common phy. Bug 887361 Change-Id: I013c3df22fd7d41718debb96dc8db78f56d73bd1 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/103600 Reviewed-by: Venkat Moganty GVS: Gerrit_Virtual_Submit --- drivers/usb/gadget/Makefile | 1 - drivers/usb/gadget/fsl_tegra_udc.c | 170 ------------------------------------- drivers/usb/gadget/tegra_udc.c | 119 ++++---------------------- 3 files changed, 16 insertions(+), 274 deletions(-) delete mode 100644 drivers/usb/gadget/fsl_tegra_udc.c 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/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 -#include -#include -#include -#include - -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..dc14c612b38f 100644 --- a/drivers/usb/gadget/tegra_udc.c +++ b/drivers/usb/gadget/tegra_udc.c @@ -37,7 +37,6 @@ #include #include #include -#include /* check this */ #include #include @@ -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; @@ -733,11 +727,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 +818,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,7 +1215,7 @@ 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) @@ -1251,22 +1237,14 @@ static int tegra_vbus_session(struct usb_gadget *gadget, int is_active) udc->vbus_active = 0; udc->usb_state = USB_STATE_DEFAULT; spin_unlock(&udc->lock); -#ifdef IS_NEW_PHY_DRIVER 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 +1326,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 +2082,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 +2103,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 +2243,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 +2374,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 +2522,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 +2540,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 +2553,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 +2573,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 +2594,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 +2610,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 +2636,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 +2681,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 +2695,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; @@ -2771,7 +2706,7 @@ static int tegra_udc_suspend(struct platform_device *pdev, pm_message_t state) struct tegra_udc *udc = platform_get_drvdata(pdev); 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; @@ -2783,16 +2718,12 @@ static int tegra_udc_suspend(struct platform_device *pdev, pm_message_t state) udc->usb_state = USB_STATE_DEFAULT; spin_unlock(&udc->lock); } - /* 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 +2734,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; } -- cgit v1.2.3 From 0d88e1dc78fd422c07b8ef385871223bf7dbc9da Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Mon, 21 May 2012 16:36:19 +0530 Subject: usb: otg: tegra: enhance tegra otg driver Following enhancements are done: a. Removed unnecessary apis. b. Update the new platform data structures. c. Removed unnecessary function call overheads. Bug 887361 Change-Id: I148f2c0adb617c6f3100b84854bbd4ed1e953ecd Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/103601 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venkat Moganty GVS: Gerrit_Virtual_Submit --- drivers/usb/otg/tegra-otg.c | 153 ++++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 99 deletions(-) diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c index d95d238fd9d6..5258b3ec8992 100644 --- a/drivers/usb/otg/tegra-otg.c +++ b/drivers/usb/otg/tegra-otg.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -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 */ @@ -290,8 +262,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) @@ -301,8 +271,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); @@ -311,17 +282,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) @@ -344,7 +309,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__); @@ -364,7 +329,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); @@ -426,8 +390,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; @@ -436,8 +398,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; @@ -448,7 +408,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); @@ -496,10 +455,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); @@ -543,59 +500,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__); } -- cgit v1.2.3 From 8be5b34f5420304183d0ebba8dd757b6b4b9476e Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Mon, 21 May 2012 12:39:38 -0400 Subject: CHROMEOS: add chrome kernel infrastructure The ChromeOS build environment expects to build the kernel using a splitconfig. This change adds the scripts and configs required to satisfy this requirement. Right now the chromeos-tegra3 config is the only supported configuration using the splitconfigs. Signed-off-by: Rhyland Klein Change-Id: I21ac515261a03bdbe1c79bbd6cd02a6e34c82ef9 Reviewed-on: http://git-master/r/103683 Reviewed-by: Yu-Huan Hsu Reviewed-by: Dan Willemsen Reviewed-by: Allen Martin --- chromeos/config/armel/config.common.armel | 528 +++++ .../config/armel/config.flavour.chromeos-tegra3 | 125 ++ .../config/armel/config.flavour.chromiumos-arm | 86 + chromeos/config/config.common.chromeos | 2039 ++++++++++++++++++++ chromeos/config/i386/config.common.i386 | 749 +++++++ .../i386/config.flavour.chromeos-intel-menlow | 1 + .../i386/config.flavour.chromeos-pinetrail-i386 | 41 + .../config/i386/config.flavour.chromiumos-i386 | 85 + chromeos/config/x86_64/config.common.x86_64 | 740 +++++++ .../x86_64/config.flavour.chromeos-intel-pineview | 3 + chromeos/scripts/allconfigs | 28 + chromeos/scripts/kernelconfig | 123 ++ chromeos/scripts/prepareconfig | 18 + chromeos/scripts/splitconfig | 49 + 14 files changed, 4615 insertions(+) create mode 100644 chromeos/config/armel/config.common.armel create mode 100644 chromeos/config/armel/config.flavour.chromeos-tegra3 create mode 100644 chromeos/config/armel/config.flavour.chromiumos-arm create mode 100644 chromeos/config/config.common.chromeos create mode 100644 chromeos/config/i386/config.common.i386 create mode 120000 chromeos/config/i386/config.flavour.chromeos-intel-menlow create mode 100644 chromeos/config/i386/config.flavour.chromeos-pinetrail-i386 create mode 100644 chromeos/config/i386/config.flavour.chromiumos-i386 create mode 100644 chromeos/config/x86_64/config.common.x86_64 create mode 100644 chromeos/config/x86_64/config.flavour.chromeos-intel-pineview create mode 100755 chromeos/scripts/allconfigs create mode 100755 chromeos/scripts/kernelconfig create mode 100755 chromeos/scripts/prepareconfig create mode 100755 chromeos/scripts/splitconfig 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. + + # config.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. 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() -- cgit v1.2.3 From c20772878b3e88a31ef3021e8030d2c20a2daa19 Mon Sep 17 00:00:00 2001 From: Krishna Reddy Date: Tue, 22 May 2012 11:36:03 -0700 Subject: video: tegra: nvmap: Change function declaration order. Change function declaration order to avoid multiple CONFIG_TEGRA_NVMAP #ifdef's. Change-Id: Icb10380f8da4b8037b90e787f961a28e8528814f Signed-off-by: Krishna Reddy Reviewed-on: http://git-master/r/103990 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bo Yan Reviewed-by: Jon Mayo --- drivers/video/tegra/nvmap/nvmap.h | 86 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) 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 */ -- cgit v1.2.3 From 9d85ccb8c12126fdb48f00a8951860d4ed070653 Mon Sep 17 00:00:00 2001 From: Krishna Reddy Date: Tue, 22 May 2012 15:46:04 -0700 Subject: video: tegra: nvmap: Clean up carveout to iovmm conversion. Clean up carveout to iovmm conversion code. Fixed bug in converting iovmm requests to carveout. Change-Id: I35a5238c955d0478f0e1a295e501bae9ee52b0a8 Signed-off-by: Krishna Reddy Reviewed-on: http://git-master/r/103991 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Yu-Huan Hsu --- drivers/video/tegra/nvmap/nvmap_handle.c | 58 ++++++++------------------------ 1 file changed, 14 insertions(+), 44 deletions(-) diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c index 2e2b8b3d46a1..56e2dab1820c 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.c +++ b/drivers/video/tegra/nvmap/nvmap_handle.c @@ -44,13 +44,6 @@ #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 @@ -643,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); @@ -686,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; @@ -710,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; @@ -772,24 +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) { - 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. */ -- cgit v1.2.3 From 4e571e426a41d0a5297854bd8bf303a2b8be66f1 Mon Sep 17 00:00:00 2001 From: Marvin Zhang Date: Tue, 3 Apr 2012 12:53:58 -0700 Subject: tf_driver: integrate latest TL release: Tegra 2 version: TF_TEGRA2_AA01.09.34784 Tegra 3 version: TF_TEGRA3_AB01.08.34931 Add dynamic support for UART used by the Secure World trace driver. The files are from the Tegra 3 version of SDK. Bug 960201. Change-Id: I14c3cfc35f81d3a37981e82760c2a2259164a904 Signed-off-by: Marvin Zhang Reviewed-on: http://git-master/r/94306 (cherry picked from commit 173b55aa4d30fc3771719093d675972fca600cd3) Reviewed-on: http://git-master/r/104037 Reviewed-by: Chris Johnson Reviewed-by: Karan Jhavar Tested-by: Karan Jhavar Reviewed-by: Yu-Huan Hsu GVS: Gerrit_Virtual_Submit --- security/tf_driver/Makefile | 2 +- security/tf_driver/s_version.h | 4 ++-- security/tf_driver/tf_comm_tz.c | 18 ++++++++++++++++++ security/tf_driver/tf_protocol.h | 4 ++++ 4 files changed, 25 insertions(+), 3 deletions(-) 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 -- cgit v1.2.3 From 043165e17e77abf771aae9ba03aff4467770cfc1 Mon Sep 17 00:00:00 2001 From: Krishna Reddy Date: Wed, 23 May 2012 14:58:52 -0700 Subject: video: tegra: nvmap: Fix debug allocations data shown. Debug allocations data for iovmm has carvout allocations also and vice versa. Fixed it to show only iovmm for iovmm and carveout for carveout. Add missing "FLAGS" print for iovmm allocations. Change-Id: I0fd271be24d0d2d3924ca473fd32476776fdcf84 Signed-off-by: Krishna Reddy Reviewed-on: http://git-master/r/104246 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Yu-Huan Hsu Reviewed-by: Jon Mayo --- drivers/video/tegra/nvmap/nvmap_dev.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) 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); } -- cgit v1.2.3 From eff5dd61e05e1b01c396609e2129a8ab433d2666 Mon Sep 17 00:00:00 2001 From: Yen Lin Date: Mon, 12 Mar 2012 17:07:58 -0700 Subject: arm: tegra: ahci/sata: Add SATA driver Upgrade the Tegra 3 SATA driver to support kernel 3.1. The driver supports runtime_pm when doing power-gating during idle. A new CONFIG_TEGRA_SATA_IDLE_POWERGATE is provided to enable/disable power-gating during idle. When sata clocks (sata, sata-oob and pll_e clocks) are in the core_dvfs_table[] table, CONFIG_TEGRA_SATA_IDLE_POWERGATE must not be enabled. Currently, sata clocks are in the core_dvfs_table[]. Those clocks will not be in that table in the future. By then, CONFIG_TEGRA_SATA_IDLE_POWERGATE can then be enabled. Change-Id: I15b585713bfd891f8827fd028b21bf3e5c2b80d9 Signed-off-by: Yen Lin Reviewed-on: http://git-master/r/89614 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Jon Mayo Reviewed-by: Yu-Huan Hsu --- drivers/ata/Kconfig | 17 + drivers/ata/Makefile | 1 + drivers/ata/ahci-tegra.c | 2154 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2172 insertions(+) create mode 100644 drivers/ata/ahci-tegra.c 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 . + * + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ahci.h" + +#include +#include +#include +#include +#include + +#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 +#include + +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); -- cgit v1.2.3 From 168971ab0977d04e958671651c0be4be116fee01 Mon Sep 17 00:00:00 2001 From: Sang-Hun Lee Date: Tue, 15 May 2012 16:04:41 -0700 Subject: tegra: usb: disable interrupts when locking Problem description: - tegra_udc_irq uses udc->lock - Some functions running in the process context was not disabling interrupts when locking udc->lock - If a function gets interrupted by tegra_udc_irq after locking udc->lock, a deadlock occurs, as tegra_udc_irq would also try to lock Fix description: - Use an interruption disabling variant of spin_lock Bug 983958 Change-Id: Ib774847212da64f1f727a207a4821860ffa7b4a8 Signed-off-by: Sang-Hun Lee Reviewed-on: http://git-master/r/102693 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bharat Nihalani Reviewed-by: Venkat Moganty GVS: Gerrit_Virtual_Submit --- drivers/usb/gadget/tegra_udc.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/tegra_udc.c b/drivers/usb/gadget/tegra_udc.c index dc14c612b38f..f978f0f2d1e7 100644 --- a/drivers/usb/gadget/tegra_udc.c +++ b/drivers/usb/gadget/tegra_udc.c @@ -130,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); @@ -180,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) { @@ -1221,14 +1222,14 @@ static int tegra_set_selfpowered(struct usb_gadget *gadget, int is_on) 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 */ @@ -1236,7 +1237,7 @@ 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); + spin_unlock_irqrestore(&udc->lock,flags); tegra_usb_phy_power_off(udc->phy); if (udc->vbus_reg) { /* set the current limit to 0mA */ @@ -2704,6 +2705,7 @@ 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 the controller is in otg mode, return */ @@ -2711,12 +2713,12 @@ static int tegra_udc_suspend(struct platform_device *pdev, pm_message_t state) 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 */ dr_controller_stop(udc); -- cgit v1.2.3 From f745e7ea486bcbf9665071df2e818141ed90ac07 Mon Sep 17 00:00:00 2001 From: Wen Yi Date: Wed, 23 May 2012 17:41:03 -0700 Subject: Revert "video: tegra: host: t30: use max 2d clock" This reverts commit 5bdd03b21f625d0a07c66e4894b79e557287a3a1. The reverted commit kept vcore at 1.2 volts whenever 2D engine is on and increased power consumption for use cases that utilize 2D but doesn't require its full speed. Bug 979545 Change-Id: I4297ab1fb83558501ff620952284c8590dc5f1dd Signed-off-by: Wen Yi Reviewed-on: http://git-master/r/104293 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Donghan Ryu Tested-by: Donghan Ryu GVS: Gerrit_Virtual_Submit --- drivers/video/tegra/host/t30/t30.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, -- cgit v1.2.3 From a5b582a0ad0cd078b059c68036406f9b7f1645ce Mon Sep 17 00:00:00 2001 From: Hunk Lin Date: Thu, 24 May 2012 10:09:22 +0800 Subject: Revert "Revert "arm: tegra3: change min_rate for clocks"" This reverts commit 18ed77b122dd1fbb9a6a5373da36ab32d0f0cee1. The noisy audio playback on Tegra3 with secure-OS issue is fixed by updating TL's SDK to 1.08. Change min_rate for clocks back to 12Mhz. Bug 939415 Change-Id: Ib0daf98faa85cc7cbc1dbfd4bf458427f914d830 Signed-off-by: Hunk Lin Reviewed-on: http://git-master/r/104317 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Wen Yi Reviewed-by: Aleksandr Frid Reviewed-by: Yu-Huan Hsu GVS: Gerrit_Virtual_Submit --- arch/arm/mach-tegra/tegra3_clocks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c index 2dfdb1db39b7..9e4e117cc3bc 100644 --- a/arch/arm/mach-tegra/tegra3_clocks.c +++ b/arch/arm/mach-tegra/tegra3_clocks.c @@ -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; -- cgit v1.2.3 From 5f965f2c63d3e9c6b335d1f6337c83c1f5437739 Mon Sep 17 00:00:00 2001 From: Mohit Kataria Date: Tue, 24 Apr 2012 13:03:54 +0530 Subject: Arm: Tegra3: clocks: Disabled SSCCENTER bit for plle Disabled SSCCENTRE bit for plle as per golden register (value provided by syseng) Bug 942384 978870 Change-Id: I3c2f8e8e220015b58f0c8bcbaac4e9998a5b6dcd Reviewed-on: http://git-master/r/98381 Signed-off-by: Mohit Kataria Reviewed-on: http://git-master/r/102408 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/tegra3_clocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c index 9e4e117cc3bc..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< Date: Wed, 16 May 2012 17:13:28 +0530 Subject: ARM: tegra: cardhu: Remove tegra_gpio_enb/disable Removing tegra_gpio_enable and disable calls from board files as they are supported through set direction calls in the driver Bug 984439 Change-Id: I51b17389dbb17b0e94e1635ec6d68acd01c743b4 Signed-off-by: Ashwini Ghuge Reviewed-on: http://git-master/r/102529 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/board-cardhu-kbc.c | 4 -- arch/arm/mach-tegra/board-cardhu-panel.c | 45 +++------------------- arch/arm/mach-tegra/board-cardhu-pinmux.c | 4 -- .../mach-tegra/board-cardhu-pm298-power-rails.c | 7 ---- .../mach-tegra/board-cardhu-pm299-power-rails.c | 7 ---- arch/arm/mach-tegra/board-cardhu-power.c | 7 ---- arch/arm/mach-tegra/board-cardhu-sdhci.c | 4 -- arch/arm/mach-tegra/board-cardhu-sensors.c | 9 ----- arch/arm/mach-tegra/board-cardhu.c | 35 +---------------- 9 files changed, 7 insertions(+), 115 deletions(-) diff --git a/arch/arm/mach-tegra/board-cardhu-kbc.c b/arch/arm/mach-tegra/board-cardhu-kbc.c index 16e83bbb03f8..28402f0834ef 100644 --- a/arch/arm/mach-tegra/board-cardhu-kbc.c +++ b/arch/arm/mach-tegra/board-cardhu-kbc.c @@ -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..8b6bb681a68d 100644 --- a/arch/arm/mach-tegra/board-cardhu-pinmux.c +++ b/arch/arm/mach-tegra/board-cardhu-pinmux.c @@ -544,11 +544,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 +752,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..587a8c49d471 100644 --- a/arch/arm/mach-tegra/board-cardhu-power.c +++ b/arch/arm/mach-tegra/board-cardhu-power.c @@ -1072,13 +1072,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..b4fd1a2a1765 100644 --- a/arch/arm/mach-tegra/board-cardhu-sensors.c +++ b/arch/arm/mach-tegra/board-cardhu-sensors.c @@ -87,24 +87,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 +120,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", @@ -785,8 +780,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 +909,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 +925,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 b57bec4dbf7d..5994b7d399b2 100644 --- a/arch/arm/mach-tegra/board-cardhu.c +++ b/arch/arm/mach-tegra/board-cardhu.c @@ -133,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; } @@ -808,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); @@ -1120,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 = { @@ -1210,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", @@ -1230,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; @@ -1283,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(); @@ -1297,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(); -- cgit v1.2.3 From 18a04ce5332061e6e7c7b33d3e755c691c0aba36 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh Date: Mon, 21 May 2012 19:08:09 +0530 Subject: arm: tegra: kai: configure gpio direction for bluesleep Bug 986813 Change-Id: Iaca0465041af3442da8e052e3efec1efa60d0d79 Signed-off-by: Om Prakash Singh Reviewed-on: http://git-master/r/103632 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/board-kai.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c index 7d3bb90e99f4..a2cc35717cb8 100644 --- a/arch/arm/mach-tegra/board-kai.c +++ b/arch/arm/mach-tegra/board-kai.c @@ -129,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[] = { -- cgit v1.2.3 From 98c26489fd954b63655c805ff87b8dd6368b31d5 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Tue, 22 May 2012 10:27:38 +0530 Subject: ASoC: resolve compilation time warnings Bug 949219 Change-Id: If7b4dd928cc5a808fd1a674bcc5f31c9a396a043 Signed-off-by: Sanjay Singh Rawat Reviewed-on: http://git-master/r/103772 Reviewed-by: Simone Willett Tested-by: Simone Willett --- sound/soc/tegra/tegra20_das.c | 6 +++--- sound/soc/tegra/tegra20_das.h | 4 ++-- sound/soc/tegra/tegra_asoc_utils.c | 2 +- sound/soc/tegra/tegra_wm8753.c | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) 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_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index dfbafa061993..a189fb5c61c1 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -31,7 +31,7 @@ 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; diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 795356875ba4..99d0b19c7106 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); -- cgit v1.2.3 From 839b2b9c17da5b96ecccf0acf5e8c9d3ae3816af Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Thu, 24 May 2012 11:30:30 +0300 Subject: video: tegra: host: Merge waitchk and relocation Job pinning and relocation already maps the gather buffers to kernel memory. Move waitchk to be done at the same time so that we do not need to re-map the memory to patch expired waits. Bug 965206 Change-Id: I23634b501a45de080200e57d3debf267b39fea38 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/104415 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Juha Tukkinen Reviewed-by: Mayuresh Kulkarni --- drivers/video/tegra/host/bus_client.c | 8 +-- drivers/video/tegra/host/chip_support.h | 8 +-- drivers/video/tegra/host/host1x/host1x_channel.c | 16 ------ drivers/video/tegra/host/host1x/host1x_syncpt.c | 64 +++--------------------- drivers/video/tegra/host/nvhost_channel.h | 1 - drivers/video/tegra/host/nvhost_job.c | 58 ++++++++++++++++++++- drivers/video/tegra/host/nvhost_job.h | 7 ++- drivers/video/tegra/host/nvhost_syncpt.c | 13 ++--- drivers/video/tegra/host/nvhost_syncpt.h | 18 +------ 9 files changed, 81 insertions(+), 112 deletions(-) diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 822f8f3a456d..397cd21f555d 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -306,7 +306,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); @@ -316,13 +316,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; } diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h index 173a36065458..d69e1c4bccb9 100644 --- a/drivers/video/tegra/host/chip_support.h +++ b/drivers/video/tegra/host/chip_support.h @@ -28,7 +28,6 @@ struct output; struct nvhost_master; struct nvhost_intr; struct nvhost_syncpt; -struct nvhost_waitchk; struct nvhost_userctx_timeout; struct nvhost_channel; struct nvmap_handle_ref; @@ -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/host1x/host1x_channel.c b/drivers/video/tegra/host/host1x/host1x_channel.c index 0b4d07cb9e47..c72e6478b806 100644 --- a/drivers/video/tegra/host/host1x/host1x_channel.c +++ b/drivers/video/tegra/host/host1x/host1x_channel.c @@ -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_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/nvhost_channel.h b/drivers/video/tegra/host/nvhost_channel.h index a8f16f0c5abc..b3a904d5a3ee 100644 --- a/drivers/video/tegra/host/nvhost_channel.h +++ b/drivers/video/tegra/host/nvhost_channel.h @@ -31,7 +31,6 @@ #define NVHOST_MAX_POWERGATE_IDS 2 struct nvhost_master; -struct nvhost_waitchk; struct nvhost_device; struct nvhost_channel; struct nvhost_hwctx; diff --git a/drivers/video/tegra/host/nvhost_job.c b/drivers/video/tegra/host/nvhost_job.c index 11d65964e2c9..6d8c3bd2bd50 100644 --- a/drivers/video/tegra/host/nvhost_job.c +++ b/drivers/video/tegra/host/nvhost_job.c @@ -27,6 +27,7 @@ #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 */ @@ -196,11 +197,63 @@ static int do_relocs(struct nvhost_job *job, u32 patch_mem, void *patch_addr) return 0; } -int nvhost_job_pin(struct nvhost_job *job) +/* + * 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); + 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++) { @@ -233,6 +286,9 @@ int nvhost_job_pin(struct nvhost_job *job) } 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) diff --git a/drivers/video/tegra/host/nvhost_job.h b/drivers/video/tegra/host/nvhost_job.h index 48555a231412..b30f5faf7e8f 100644 --- a/drivers/video/tegra/host/nvhost_job.h +++ b/drivers/video/tegra/host/nvhost_job.h @@ -27,7 +27,7 @@ struct nvhost_channel; struct nvhost_hwctx; struct nvmap_client; struct nvhost_waitchk; -struct nvmap_handle; +struct nvhost_syncpt; struct nvhost_job_gather { u32 words; @@ -129,8 +129,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 1458a7cb5acc..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; @@ -330,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); -- cgit v1.2.3 From 97b5fcb955784c5245debc020473318dd45e5683 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Thu, 24 May 2012 16:39:37 +0530 Subject: ASoC: tegra: treat compilation warning as error Bug 949219 Change-Id: Ic8976b008772220299369369427a80dd370df596 Signed-off-by: Sanjay Singh Rawat Reviewed-on: http://git-master/r/104419 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani --- sound/soc/tegra/Makefile | 2 ++ 1 file changed, 2 insertions(+) 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 -- cgit v1.2.3 From 73f65f7f6898bd88fe457f96d4dc702f746058bc Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Thu, 24 May 2012 15:06:58 +0300 Subject: video: tegra: host: Replace nvmap structs with own Replace usage of nvmap_pinarray_elem with own nvhost_reloc and nvhost_reloc_shift structs. Bug 965206 Change-Id: I90618d8a34d79156d8880d9925dadbf416353811 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/104450 Reviewed-by: Juha Tukkinen Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mayuresh Kulkarni --- drivers/video/tegra/host/bus_client.c | 39 +++++++++++++++---------- drivers/video/tegra/host/nvhost_job.c | 54 +++++++++++++++++++---------------- drivers/video/tegra/host/nvhost_job.h | 3 +- include/trace/events/nvhost.h | 15 ++++++---- 4 files changed, 65 insertions(+), 46 deletions(-) diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 397cd21f555d..9b71542a48aa 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -238,21 +238,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_relocs], + 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->pinarray[job->num_relocs].patch_mem, - job->pinarray[job->num_relocs].patch_offset, - job->pinarray[job->num_relocs].pin_mem, - job->pinarray[job->num_relocs].pin_offset); - job->num_relocs++; - 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)); @@ -274,16 +281,18 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, } else if (priv->num_relocshifts) { int next_shift = job->num_relocs - priv->num_relocshifts; - consumed = sizeof(struct nvhost_reloc_shift); - if (remaining < consumed) + 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; diff --git a/drivers/video/tegra/host/nvhost_job.c b/drivers/video/tegra/host/nvhost_job.c index 6d8c3bd2bd50..e029449b6184 100644 --- a/drivers/video/tegra/host/nvhost_job.c +++ b/drivers/video/tegra/host/nvhost_job.c @@ -41,7 +41,8 @@ static int job_size(struct nvhost_submit_hdr_ext *hdr) int num_unpins = num_cmdbufs + num_relocs; return sizeof(struct nvhost_job) - + num_relocs * sizeof(struct nvmap_pinarray_elem) + + 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); @@ -63,8 +64,10 @@ static void init_fields(struct nvhost_job *job, /* Redistribute memory to the structs */ mem += sizeof(struct nvhost_job); - job->pinarray = num_relocs ? mem : NULL; - mem += num_relocs * sizeof(struct nvmap_pinarray_elem); + 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; @@ -154,44 +157,46 @@ void nvhost_job_add_gather(struct nvhost_job *job, job->num_gathers += 1; } -static int do_relocs(struct nvhost_job *job, u32 patch_mem, void *patch_addr) +static int do_relocs(struct nvhost_job *job, u32 cmdbuf_mem, void *cmdbuf_addr) { - phys_addr_t pin_phys; + phys_addr_t target_phys; int i; u32 mem_id = 0; - struct nvmap_handle_ref *pin_ref = NULL; + struct nvmap_handle_ref *target_ref = NULL; /* pin & patch the relocs for one gather */ for (i = 0; i < job->num_relocs; i++) { - struct nvmap_pinarray_elem *pin = &job->pinarray[i]; + struct nvhost_reloc *reloc = &job->relocarray[i]; + struct nvhost_reloc_shift *shift = &job->relocshiftarray[i]; /* skip all other gathers */ - if (patch_mem != pin->patch_mem) + if (cmdbuf_mem != reloc->cmdbuf_mem) continue; /* check if pin-mem is same as previous */ - if (pin->pin_mem != mem_id) { - pin_ref = nvmap_duplicate_handle_id(job->nvmap, - pin->pin_mem); - if (IS_ERR(pin_ref)) - return PTR_ERR(pin_ref); - - pin_phys = nvmap_pin(job->nvmap, pin_ref); - if (IS_ERR((void *)pin_phys)) { - nvmap_free(job->nvmap, pin_ref); - return pin_phys; + 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 = pin->pin_mem; - job->unpins[job->num_unpins++] = pin_ref; + mem_id = reloc->target; + job->unpins[job->num_unpins++] = target_ref; } - __raw_writel((pin_phys + pin->pin_offset) >> pin->reloc_shift, - (patch_addr + pin->patch_offset)); + __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. */ - pin->patch_mem = 0; + reloc->cmdbuf_mem = 0; } return 0; @@ -216,7 +221,8 @@ static int do_waitchks(struct nvhost_job *job, struct nvhost_syncpt *sp, continue; trace_nvhost_syncpt_wait_check(wait->mem, wait->offset, - wait->syncpt_id, wait->thresh); + wait->syncpt_id, wait->thresh, + nvhost_syncpt_read(sp, wait->syncpt_id)); if (nvhost_syncpt_is_expired(sp, wait->syncpt_id, wait->thresh)) { /* diff --git a/drivers/video/tegra/host/nvhost_job.h b/drivers/video/tegra/host/nvhost_job.h index b30f5faf7e8f..ec1366337279 100644 --- a/drivers/video/tegra/host/nvhost_job.h +++ b/drivers/video/tegra/host/nvhost_job.h @@ -67,7 +67,8 @@ struct nvhost_job { u32 waitchk_mask; /* Array of handles to be pinned & unpinned */ - struct nvmap_pinarray_elem *pinarray; + struct nvhost_reloc *relocarray; + struct nvhost_reloc_shift *relocshiftarray; int num_relocs; struct nvmap_handle_ref **unpins; int num_unpins; diff --git a/include/trace/events/nvhost.h b/include/trace/events/nvhost.h index 6358fedf4482..b4818f55844c 100644 --- a/include/trace/events/nvhost.h +++ b/include/trace/events/nvhost.h @@ -482,27 +482,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 */ -- cgit v1.2.3 From 84a74690b616591b2f178bd9b08953433c66b620 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Thu, 24 May 2012 18:22:29 +0530 Subject: spi: tegra: fix fifo_depth to 32. Slink controller have the fifo depth of 32 words in rx and tx side. But some of places it was taken the value as 4. Fixing this to 32 words. Change-Id: I262127c59241ce75d4385464c21ee733a48b1475 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/104463 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Stephen Warren GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas --- drivers/spi/spi-tegra.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 070cc1581efd..67143178c125 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; @@ -807,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); @@ -1158,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); -- cgit v1.2.3 From 95c66daaa95d7cb04803d798db36ebbc43927f2a Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Thu, 24 May 2012 16:17:29 +0530 Subject: spi: tegra: use devm_* for resource allocation Using of devm_* function for resource allocation does not require to free resource on code and hence it reduces code sizes. Change-Id: Id6f0ba3cde2f351d5668ed28b098e5a829716a30 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/104464 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas --- drivers/spi/spi-tegra.c | 60 ++++++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 67143178c125..05c2d2c2607b 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c @@ -1220,55 +1220,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; + goto exit_free_master; } - - if (!request_mem_region(r->start, resource_size(r), - dev_name(&pdev->dev))) { - ret = -EBUSY; - goto fail_no_mem; - } - 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); @@ -1317,7 +1312,7 @@ static int __init spi_tegra_probe(struct platform_device *pdev) if (!tspi->rx_dma) { dev_err(&pdev->dev, "can not allocate rx dma channel\n"); ret = -ENODEV; - goto fail_rx_dma_alloc; + goto exit_free_master; } tspi->rx_buf = dma_alloc_coherent(&pdev->dev, tspi->dma_buf_size, @@ -1433,17 +1428,8 @@ fail_tx_dma_alloc: fail_rx_buf_alloc: if (tspi->rx_dma) tegra_dma_free_channel(tspi->rx_dma); -fail_rx_dma_alloc: - 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: + +exit_free_master: spi_master_put(master); return ret; } @@ -1452,7 +1438,6 @@ 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); @@ -1477,15 +1462,8 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) if (!pm_runtime_status_suspended(&pdev->dev)) tegra_spi_runtime_idle(&pdev->dev); - clk_put(tspi->sclk); - clk_put(tspi->clk); - iounmap(tspi->base); - destroy_workqueue(tspi->spi_workqueue); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, resource_size(r)); - return 0; } -- cgit v1.2.3 From 0a9c2618396cdb1fb88a70bae9492c7c7e60c34a Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Thu, 24 May 2012 18:26:54 +0530 Subject: spi: tegra: use functions to avoid duplicated code The dma allocation method for receive and transmit is same and so instead of duplicating the same code for rx and tx, making the function to have common code and using the function for dma allocation. This reduces duplicated code. Change-Id: Ibe15eec896bc581bda8c68572eb1425c3bf6a7b2 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/104465 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas --- drivers/spi/spi-tegra.c | 182 +++++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 80 deletions(-) diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 05c2d2c2607b..d4b9c3344eee 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c @@ -1185,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; @@ -1306,64 +1387,18 @@ 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; + 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->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; - } - - 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; @@ -1374,7 +1409,7 @@ skip_dma_alloc: ret = tegra_spi_runtime_resume(&pdev->dev); if (ret) { dev_err(&pdev->dev, "runtime resume failed %d", ret); - goto err_pm_disable; + goto exit_pm_disable; } } @@ -1386,7 +1421,7 @@ skip_dma_alloc: 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 */ @@ -1395,39 +1430,30 @@ 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->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); -err_pm_disable: +exit_pm_disable: pm_runtime_disable(&pdev->dev); - 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); + 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); @@ -1443,16 +1469,12 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) 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); /* Disable clock if it is always enabled */ if (tspi->is_clkon_always) -- cgit v1.2.3 From d3869078b53e6e3499880d508607dc4a9883cbe0 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal Date: Thu, 24 May 2012 19:03:11 +0530 Subject: arm: tegra: cardhu: remove unused pinmux setting Remove unsued pinmux for pn544 nfc which was introduced in http://git-master/r/#change,62746 Bug 978207 Change-Id: I7724e9c17c8c5717e07fbc9e091f26f6e81cb422 Signed-off-by: Rakesh Goyal Reviewed-on: http://git-master/r/104468 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/board-cardhu-pinmux.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-cardhu-pinmux.c b/arch/arm/mach-tegra/board-cardhu-pinmux.c index 8b6bb681a68d..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), -- cgit v1.2.3 From ed1309fe218e55d7f32bee16a40816f74ccd4fe5 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Fri, 25 May 2012 10:48:09 +0530 Subject: ARM: tegra: clock: Update secondary pll dividers resume During resume from LP0 on Tegra2 always enable pll secondary dividers before clocks restoration (to make sure clock sources are enabled). Restore actual secondary dividers settings after clocks are restored. Bug 965928 Bug 953030 Change-Id: Id0cd99b601f90ad9fe8452817810969e41002199 Signed-off-by: Prashant Gaikwad Reviewed on http://git-master/r/#change,104661 (cherry picked from commit 6350d1fd475373779cf5110403717b2c84e723ba) Change-Id: Ic50477603b97a99d2ac2c926df1728faa107b108 Reviewed-on: http://git-master/r/104668 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Prashant Gaikwad Tested-by: Prashant Gaikwad Reviewed-by: Bharat Nihalani GVS: Gerrit_Virtual_Submit --- arch/arm/mach-tegra/tegra2_clocks.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index af30cf2ea18c..135ae6ad9765 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -2771,7 +2771,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 +2779,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 +2833,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 +2865,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 +2908,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 -- cgit v1.2.3 From bd09096c7b6431f31d312e45689f59215a0e1356 Mon Sep 17 00:00:00 2001 From: Sumit Bhattacharya Date: Fri, 20 Apr 2012 17:41:16 +0530 Subject: ASoC: Tegra: Add support for AVP rendering Add alsa controls to specify which alsa device is used by AVP to render audio. Also add support for disabling DMA interrupt when AVP renders audio. Also add couple of alsa controls to query DMA channel ID and DMA buffer physical address. Bug 968814 Signed-off-by: Sumit Bhattacharya Change-Id: If593329db72bf00d97f7433f5c54e13500281253 Reviewed-on: http://git-master/r/97916 Reviewed-by: Rohan Somvanshi Tested-by: Rohan Somvanshi --- sound/soc/tegra/tegra_aic326x.c | 4 ++ sound/soc/tegra/tegra_asoc_utils.c | 132 +++++++++++++++++++++++++++++++++++++ sound/soc/tegra/tegra_asoc_utils.h | 4 ++ sound/soc/tegra/tegra_max98088.c | 4 ++ sound/soc/tegra/tegra_max98095.c | 4 ++ sound/soc/tegra/tegra_pcm.c | 18 +++-- sound/soc/tegra/tegra_pcm.h | 1 + sound/soc/tegra/tegra_rt5640.c | 5 ++ sound/soc/tegra/tegra_wm8753.c | 4 ++ sound/soc/tegra/tegra_wm8903.c | 4 ++ 10 files changed, 176 insertions(+), 4 deletions(-) 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 a189fb5c61c1..6ab5b2d46a1f 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -27,6 +27,9 @@ #include +#include + +#include "tegra_pcm.h" #include "tegra_asoc_utils.h" int g_is_call_mode; @@ -40,6 +43,115 @@ bool tegra_is_voice_call_active(void) } 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) { 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_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 99d0b19c7106..f7c7a4c6b5a1 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -782,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? */ -- cgit v1.2.3 From 819931a20214284ae55d8bc67c458c6790035a93 Mon Sep 17 00:00:00 2001 From: Nitin Pai Date: Tue, 22 May 2012 19:56:35 +0530 Subject: arm: tegra: p1852: Instantiated TDM mode driver Instantiated TDM mode driver. Changed clock values for TDM mode. Bug 948478 Change-Id: I64fb6c6f3ff0d573494656ae04f29323a41da50a Signed-off-by: Bob Johnston Reviewed-on: http://git-master/r/103895 Reviewed-by: Rohan Somvanshi Tested-by: Rohan Somvanshi --- arch/arm/mach-tegra/board-p1852.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-tegra/board-p1852.c b/arch/arm/mach-tegra/board-p1852.c index 1065afe05cca..71c12756539d 100644 --- a/arch/arm/mach-tegra/board-p1852.c +++ b/arch/arm/mach-tegra/board-p1852.c @@ -65,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}, @@ -79,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}, @@ -205,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, }, }; @@ -242,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); } -- cgit v1.2.3 From 6101daf11fb99307e2b7491eea2b1bf39c8ff5d1 Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Fri, 25 May 2012 18:10:07 +0530 Subject: usb: ehci: tegra: fix remote wakeup issues This change fixes remote wakeup issues when usb line is in suspend state. Bug 989441 Bug 989400 Change-Id: I97982943d5521470b83ed87b83ab8703c4e9c260 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/104746 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venkat Moganty --- drivers/usb/host/ehci-tegra.c | 64 +++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 82523bd200a6..c5fa8160bffe 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -23,6 +23,12 @@ #include #include +#if 0 +#define EHCI_DBG(stuff...) pr_info("ehci-tegra: " stuff) +#else +#define EHCI_DBG(stuff...) do {} while (0) +#endif + static const char driver_name[] = "tegra-ehci"; #define TEGRA_USB_DMA_ALIGN 32 @@ -164,6 +170,11 @@ static irqreturn_t tegra_ehci_irq(struct usb_hcd *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); if (pmc_remote_wakeup) { @@ -172,8 +183,6 @@ 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_pre_resume(tegra->phy, true); tegra->port_resuming = 1; } @@ -202,33 +211,30 @@ static int tegra_ehci_hub_control( return retval; } - status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; - - spin_lock_irqsave(&ehci->lock, flags); /* Do tegra phy specific actions based on the type request */ switch (typeReq) { case GetPortStatus: - if (time_after_eq(jiffies, ehci->reset_done[wIndex - 1])) { - if (tegra->port_resuming) { - int delay = ehci->reset_done[wIndex-1] - jiffies; - /* Sometimes it seems we get called too soon... In that case, wait.*/ - if (delay > 0) { - ehci_dbg(ehci, "GetPortStatus called too soon, waiting %dms...\n", delay); - mdelay(jiffies_to_msecs(delay)); - } - /* 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; - /* If run bit is not set by now enable it */ - if (ehci->command & CMD_RUN) { - ehci->command |= CMD_RUN; - ehci_writel(ehci, ehci->command, - &ehci->regs->command); - } + if (tegra->port_resuming) { + int delay = ehci->reset_done[wIndex-1] - jiffies; + /* Sometimes it seems we get called too soon... In that case, wait.*/ + if (delay > 0) { + 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; + /* If run bit is not set by now enable it */ + if (ehci->command & CMD_RUN) { + ehci->command |= CMD_RUN; + ehci_writel(ehci, ehci->command, &ehci->regs->command); + } + /* Now we can safely re-enable irqs */ + ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); } break; case ClearPortFeature: @@ -238,14 +244,12 @@ static int tegra_ehci_hub_control( } break; } - spin_unlock_irqrestore(&ehci->lock, flags); /* handle ehci hub control request */ retval = ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); /* do tegra phy specific actions based on the type request */ if (!retval) { - spin_lock_irqsave(&ehci->lock, flags); switch (typeReq) { case SetPortFeature: if (wValue == USB_PORT_FEAT_SUSPEND) { @@ -261,7 +265,6 @@ static int tegra_ehci_hub_control( } break; } - spin_unlock_irqrestore(&ehci->lock, flags); } return retval; @@ -327,7 +330,7 @@ static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); int err = 0; - + EHCI_DBG("%s() BEGIN\n", __func__); mutex_lock(&tegra->sync_lock); tegra->bus_suspended_fail = false; err = ehci_bus_suspend(hcd); @@ -336,6 +339,7 @@ static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) else tegra_usb_phy_suspend(tegra->phy); mutex_unlock(&tegra->sync_lock); + EHCI_DBG("%s() END\n", __func__); return err; } @@ -344,11 +348,13 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); int err = 0; + EHCI_DBG("%s() BEGIN\n", __func__); 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__); return err; } -- cgit v1.2.3 From 80bf2509026e174502fa571c5275b686e00b8cbc Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Fri, 25 May 2012 18:14:18 +0530 Subject: arm: tegra: usb_phy: fix remote wakeup issues This change fixes remote wakeup issues when usb line is in suspend state. Bug 989441 Bug 989400 Change-Id: I90a417c1d0a5e273c87a079133bb0ca1b4d18041 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/104747 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venkat Moganty --- arch/arm/mach-tegra/tegra3_usb_phy.c | 133 ++++++++++++++++++++++++++--------- 1 file changed, 98 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-tegra/tegra3_usb_phy.c b/arch/arm/mach-tegra/tegra3_usb_phy.c index 94c3fb16cd20..5b3e51974d3b 100644 --- a/arch/arm/mach-tegra/tegra3_usb_phy.c +++ b/arch/arm/mach-tegra/tegra3_usb_phy.c @@ -40,6 +40,8 @@ #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 @@ -412,6 +414,12 @@ #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; @@ -648,6 +656,7 @@ static void utmip_setup_pmc_wake_detect(struct tegra_usb_phy *phy) 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) @@ -688,6 +697,7 @@ static void utmip_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy) 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) @@ -820,6 +830,7 @@ static void utmip_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy) 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) @@ -834,6 +845,7 @@ static void utmip_powerup_pmc_wake_detect(struct tegra_usb_phy *phy) 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) @@ -926,10 +938,31 @@ static int usb_phy_bringup_host_controller(struct tegra_usb_phy *phy) 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]\n", + 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; @@ -975,21 +1008,26 @@ static int usb_phy_bringup_host_controller(struct tegra_usb_phy *phy) 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__); + 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)); @@ -1233,9 +1271,10 @@ static void utmi_phy_enable_obs_bus(struct tegra_usb_phy *phy) writel(val, base + UTMIP_MISC_CFG0); udelay(10); DBG("%s(%d) Enable OBS bus\n", __func__, __LINE__); + PHY_DBG("ENABLE_OBS_BUS\n"); } -static void utmi_phy_disable_obs_bus(struct tegra_usb_phy *phy) +static int utmi_phy_disable_obs_bus(struct tegra_usb_phy *phy) { unsigned long val; void __iomem *base = phy->regs; @@ -1243,6 +1282,7 @@ static void utmi_phy_disable_obs_bus(struct tegra_usb_phy *phy) /* 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); @@ -1262,7 +1302,17 @@ static void utmi_phy_disable_obs_bus(struct tegra_usb_phy *phy) 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) @@ -1287,9 +1337,22 @@ 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) @@ -1306,9 +1369,9 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) unsigned long val; void __iomem *base = phy->regs; - DBG("%s(%d) inst:[%d] BEGIN\n", __func__, __LINE__, phy->inst); + PHY_DBG("%s(%d) inst:[%d] BEGIN\n", __func__, __LINE__, phy->inst); if (!phy->phy_clk_on) { - DBG("%s(%d) inst:[%d] phy clk is already off\n", + PHY_DBG("%s(%d) inst:[%d] phy clk is already off\n", __func__, __LINE__, phy->inst); return 0; } @@ -1373,24 +1436,20 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) } } - if (phy->inst == 0) { - 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, - 0, 2500)) - pr_warn("%s: timeout waiting for phy to stabilize\n", __func__); + 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; - DBG("%s(%d) inst:[%d] END\n", __func__, __LINE__, phy->inst); + PHY_DBG("%s(%d) inst:[%d] END\n", __func__, __LINE__, phy->inst); return 0; } @@ -1402,9 +1461,9 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) 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); + 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 On\n", + PHY_DBG("%s(%d) inst:[%d] phy clk is already On\n", __func__, __LINE__, phy->inst); return 0; } @@ -1518,8 +1577,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) utmip_powerup_pmc_wake_detect(phy); phy->phy_clk_on = true; phy->hw_accessible = true; - DBG("%s(%d) End\n", __func__, __LINE__); - + PHY_DBG("%s(%d) End inst:[%d]\n", __func__, __LINE__, phy->inst); return 0; } @@ -1547,19 +1605,24 @@ static void utmi_phy_restore_end(struct tegra_usb_phy *phy) { unsigned long val; void __iomem *base = phy->regs; - int wait_time_us = 3000; /* FPR should be set by this time */ + 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 FPR bit is set automatically on remote resume */ + /* wait until SUSPEND and RESUME bit is cleared on remote resume */ do { val = readl(base + USB_PORTSC); udelay(1); - if (wait_time_us == 0) + 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)); + } while (val & (USB_PORTSC_RESUME | USB_PORTSC_SUSP)); + /* wait for 25 ms to port resume complete */ msleep(25); /* disable PMC master control */ -- cgit v1.2.3 From 7ea6f9e5b038552021d8516d583d4ae717fbcf43 Mon Sep 17 00:00:00 2001 From: Rakesh Bodla Date: Fri, 25 May 2012 18:15:01 +0530 Subject: arm: tegra: cardhu: disable hotplug for usb instance 1 USB 1 instance is used for modem, so disabling the hotplug. Bug 989441 Bug 989400 Change-Id: I94ad80e75f5b1f5d2cdb009e0d474943e11393e3 Signed-off-by: Rakesh Bodla Reviewed-on: http://git-master/r/104748 Reviewed-by: Rohan Somvanshi Tested-by: Rohan Somvanshi --- arch/arm/mach-tegra/board-cardhu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c index 5994b7d399b2..4480ab3ef47b 100644 --- a/arch/arm/mach-tegra/board-cardhu.c +++ b/arch/arm/mach-tegra/board-cardhu.c @@ -1028,7 +1028,7 @@ static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = { .op_mode = TEGRA_USB_OPMODE_HOST, .u_data.host = { .vbus_gpio = -1, - .hot_plug = true, + .hot_plug = false, .remote_wakeup_supported = true, .power_off_on_suspend = true, }, -- cgit v1.2.3 From c894a870d87d1f742107109a3b69cd005d0d55f8 Mon Sep 17 00:00:00 2001 From: Sudhir Vyas Date: Thu, 17 May 2012 20:02:22 +0530 Subject: ARM: tegra: Add ad5816 focuser board support - Add support for new focuser ad5816 driver to cardhu boards. - Add regulator for new focuser ad5816. Bug 947792 Change-Id: I62e89e9188d307704098e2d4e88d276914836d70 Signed-off-by: Sudhir vyas Reviewed-on: http://git-master/r/103138 Reviewed-by: Rohan Somvanshi Tested-by: Rohan Somvanshi --- arch/arm/mach-tegra/board-cardhu-power.c | 4 +- arch/arm/mach-tegra/board-cardhu-sensors.c | 65 ++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c index 587a8c49d471..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"), }; diff --git a/arch/arm/mach-tegra/board-cardhu-sensors.c b/arch/arm/mach-tegra/board-cardhu-sensors.c index b4fd1a2a1765..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 #include +#include #include #include #include @@ -596,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*/ @@ -623,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[] = { @@ -634,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[] = { @@ -645,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[] = { @@ -656,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[] = { -- cgit v1.2.3 From ce79280836a67b3128b03d90147259f56aebf081 Mon Sep 17 00:00:00 2001 From: Sudhir Vyas Date: Thu, 17 May 2012 20:50:14 +0530 Subject: ARM: tegra: Add config for new focuser ad5816 Add config param for new focuser ad5816 driver in tegra3 defconfig. Bug 947792 Change-Id: Ie34a982ac120abd7c9f980c9f038a734845b6f02 Signed-off-by: Sudhir Vyas Reviewed-on: http://git-master/r/103143 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Sachin Nikam --- arch/arm/configs/tegra3_android_defconfig | 1 + 1 file changed, 1 insertion(+) 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 -- cgit v1.2.3 From b6f12a3449234f9960998954382e1a9afea7764d Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Thu, 24 May 2012 14:18:28 +0300 Subject: video: tegra: nvmap: Remove nvhost specific APIs Remove nvmap_pin_array() and nvmap_patch_word() and their utility functions. Bug 965206 Change-Id: I217a427934b0b99b5252b33ab3ac4eaaa8c7e076 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/104451 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mayuresh Kulkarni GVS: Gerrit_Virtual_Submit Reviewed-by: Juha Tukkinen --- drivers/video/tegra/nvmap/nvmap.c | 268 -------------------------------------- include/linux/nvmap.h | 16 --- 2 files changed, 284 deletions(-) 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/include/linux/nvmap.h b/include/linux/nvmap.h index 60ccdc192df5..553a7bd01a6d 100644 --- a/include/linux/nvmap.h +++ b/include/linux/nvmap.h @@ -92,14 +92,6 @@ struct nvmap_handle_ref { #define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id)) -struct nvmap_pinarray_elem { - __u32 patch_mem; - __u32 patch_offset; - __u32 pin_mem; - __u32 pin_offset; - __u32 reloc_shift; -}; - struct nvmap_client *nvmap_create_client(struct nvmap_device *dev, const char *name); @@ -125,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); -- cgit v1.2.3 From bc056c017381a85acf2d41a1e537f45e04ea297a Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 28 May 2012 11:56:54 +0300 Subject: video: tegra: host: Throttle lower priority jobs Implement per channel counter for jobs in each priority level. If there are jobs active with higher priority than the one being submitted, throttle. Bug 926690 Change-Id: I5fed341e3f248325873b31d1c53bf57bf0a78074 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/104939 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Juha Tukkinen Reviewed-by: Mayuresh Kulkarni --- drivers/video/tegra/host/bus_client.c | 6 --- drivers/video/tegra/host/nvhost_cdma.c | 33 ++++++++++++++++ drivers/video/tegra/host/nvhost_cdma.h | 3 ++ drivers/video/tegra/host/nvhost_channel.c | 24 ++++++++++-- drivers/video/tegra/host/nvhost_intr.c | 10 +++-- include/trace/events/nvhost.h | 62 +++++++++++++++++++++++++++++-- 6 files changed, 121 insertions(+), 17 deletions(-) diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 9b71542a48aa..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); diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c index b1f138317cc1..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); } @@ -466,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); } @@ -490,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 98393f0cc765..2056774a7bc7 100644 --- a/drivers/video/tegra/host/nvhost_cdma.h +++ b/drivers/video/tegra/host/nvhost_cdma.h @@ -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) 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_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/include/trace/events/nvhost.h b/include/trace/events/nvhost.h index b4818f55844c..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), @@ -425,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, -- cgit v1.2.3 From aef1c84834f5228316d1e096434abf98ced90eb6 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 28 May 2012 14:06:05 +0300 Subject: video: tegra: host: Dump sync queue in debug dump Dump contents of sync queue when debug dump is requested, either because of a stuck sync point, or when the debugfs entry is accessed. Exclude FIFO from normal debugfs dump. Dumping FIFO is invasive and actually changes how the channel behaves. It's safe to dump only when system is in fault condition. Change-Id: I12c68e8186acd7bd17e4ab52b2589f765396ed17 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/104970 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Juha Tukkinen --- drivers/video/tegra/host/debug.c | 67 +++++++++++++- drivers/video/tegra/host/host1x/host1x_debug.c | 117 +++++++++++++++---------- 2 files changed, 134 insertions(+), 50 deletions(-) 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/host1x/host1x_debug.c b/drivers/video/tegra/host/host1x/host1x_debug.c index a5574a0fb60a..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) @@ -171,10 +199,8 @@ static void show_channel_gather(struct output *o, u32 addr, struct nvmap_client_handle *nvmap = &pb->nvmap[cur/8]; u32 *map_addr, offset; phys_addr_t pin_addr; - int state, count, i; - if (!nvmap->handle || !nvmap->client - || atomic_read(&nvmap->handle->handle->ref) < 1) { + if (!nvmap || !nvmap->handle || !nvmap->client) { nvhost_debug_output(o, "[already deallocated]\n"); return; } @@ -194,51 +220,13 @@ static void show_channel_gather(struct output *o, u32 addr, } 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); - } + 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; @@ -248,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) { @@ -256,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); @@ -305,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"); } -- cgit v1.2.3 From 80b76730062873275081176219463225d0997bbf Mon Sep 17 00:00:00 2001 From: Jay Agarwal Date: Fri, 18 May 2012 12:16:28 +0530 Subject: arm: tegra: pcie: resolve flaw in lp0 save state 1. Restoring control register correctly. 2. Enabling clock clamping while resume Bug 959642 Change-Id: Ic97306b4dfed0e131274aa93b35dba3f906e55be Signed-off-by: Jay Agarwal Reviewed-on: http://git-master/r/103127 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bharat Nihalani GVS: Gerrit_Virtual_Submit --- arch/arm/mach-tegra/pcie.c | 191 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 145 insertions(+), 46 deletions(-) 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 -- cgit v1.2.3 From 932bb6942b32bcc0945624ec5285457c7dd40832 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Mon, 28 May 2012 12:50:58 +0530 Subject: arm: tegra: resolve compilation time warnings Warnings removed are related to unused variables/labels, structure/argument type mismatch, copyright update, function return type mismatch and wrong C coding style. Bug 949219 Change-Id: Ib748d12d5ab3cfc35118be28c29983081cca6cbb Signed-off-by: Sanjay Singh Rawat Reviewed-on: http://git-master/r/103770 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bharat Nihalani Reviewed-by: Sachin Nikam --- arch/arm/mach-tegra/board-harmony-pcie.c | 3 ++- arch/arm/mach-tegra/board-trimslice.c | 3 ++- arch/arm/mach-tegra/board-whistler-sdhci.c | 4 +--- arch/arm/mach-tegra/board-whistler.c | 26 +--------------------- arch/arm/mach-tegra/common-t2.c | 6 +++-- arch/arm/mach-tegra/common.c | 6 +++-- .../mach-tegra/include/mach/latency_allowance.h | 4 ++-- arch/arm/mach-tegra/iovmm-gart.c | 6 ++--- arch/arm/mach-tegra/tegra2_clocks.c | 3 ++- arch/arm/mach-tegra/tegra2_mc.c | 6 +++-- 10 files changed, 25 insertions(+), 42 deletions(-) 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 * + * 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-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-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 39ed3eab29ec..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 @@ -482,36 +482,12 @@ static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = { }, }; -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_usb_otg_data tegra_otg_pdata = { .ehci_device = &tegra_ehci1_device, .ehci_pdata = &tegra_ehci1_utmi_pdata, }; #define SERIAL_NUMBER_LENGTH 20 -static char usb_serial_num[SERIAL_NUMBER_LENGTH]; static void whistler_usb_init(void) { tegra_otg_device.dev.platform_data = &tegra_otg_pdata; 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/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/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/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index 135ae6ad9765..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) { 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) { -- cgit v1.2.3 From 58f7137049f6e7ad1d41fda34f68753de89bee39 Mon Sep 17 00:00:00 2001 From: naveenk Date: Fri, 25 May 2012 15:06:34 +0530 Subject: sdhci: tegra: Do not exceed platform voltage limits check for platform limits before setting the voltage Bug 979504 Change-Id: Iea78be15d6a0eea0f4344c9b78ff9366f4759af8 Signed-off-by: naveen kumar arepalli Reviewed-on: http://git-master/r/104711 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Pavan Kunapuli Reviewed-by: Sachin Nikam Reviewed-by: Bharat Nihalani --- drivers/mmc/host/sdhci-tegra.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) 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 */ -- cgit v1.2.3 From ecfc4f641d3bc4491170d6a5dd212ff587683bfa Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 7 Mar 2012 12:11:41 +0530 Subject: i2c: tegra: Fix possible race condition. on tegra3, the i2c communication start immediately after writing the tx fifo. And hence there is possibility to complete the transfer and generates done interrupt before actually sw updates their local pointers/count. This patch will make sure that pointers/count can get updated before data written into the fifo. Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/89510 (cherry picked from commit 999c09f0ed32f271e767a319dd094947e63fdb8c) Change-Id: I8e974b83b5306ec3363d4ca31ce1b539a498ca08 Signed-off-by: Johnny Qiu Reviewed-on: http://git-master/r/99997 Reviewed-by: Simone Willett Tested-by: Simone Willett --- drivers/i2c/busses/i2c-tegra.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) 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. */ -- cgit v1.2.3 From 8f8b86c91e52ca3aa76adee5869edc6a38695974 Mon Sep 17 00:00:00 2001 From: Johnny Qiu Date: Sat, 28 Apr 2012 16:37:11 +0800 Subject: arm: tegra: cardhu: pm298: do not enable wakeup for interrupt keys Bug 975433 MAX77663 driver hasn't implemented irq_set_wake(). Actually its interrupt always wakes up AP. Set wakeup = false to reduce warning messages in kernel Change-Id: If3e44fea359e363bd99ec415f7be3c4b3945205e Signed-off-by: Johnny Qiu Reviewed-on: http://git-master/r/100000 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/board-cardhu-kbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-tegra/board-cardhu-kbc.c b/arch/arm/mach-tegra/board-cardhu-kbc.c index 28402f0834ef..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[] = { -- cgit v1.2.3 From c9d3eda2af45736e73f0dfd2261257e083f3758a Mon Sep 17 00:00:00 2001 From: Hunk Lin Date: Wed, 30 May 2012 13:56:29 +0800 Subject: arm: tegra: kai: disable hotplug for usb instance 1 Kai's USB1 instance is used for modem, so disabling the hotplug. Bug 989441 Bug 989400 Change-Id: Ia1e84a727f8343a55d6afc5360b35e5afed6947c Signed-off-by: Hunk Lin Reviewed-on: http://git-master/r/105315 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Rakesh Bodla Reviewed-by: Venkat Moganty GVS: Gerrit_Virtual_Submit --- arch/arm/mach-tegra/board-kai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c index a2cc35717cb8..193d68632d52 100644 --- a/arch/arm/mach-tegra/board-kai.c +++ b/arch/arm/mach-tegra/board-kai.c @@ -724,7 +724,7 @@ static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = { .u_data.host = { .vbus_gpio = -1, .vbus_reg = NULL, - .hot_plug = true, + .hot_plug = false, .remote_wakeup_supported = true, .power_off_on_suspend = true, -- cgit v1.2.3