From e0b35b89d8d150eeb12437159bf059acd34758e5 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Nov 2013 15:43:27 +0800 Subject: spi: bcm2835: fix reference leak to master in bcm2835_spi_remove() Once a spi_master_get() call succeeds, we need an additional spi_master_put() call to free the memory, otherwise we will leak a reference to master. Fix by removing the unnecessary spi_master_get() call. Fixes: 247263dba208 ('spi: bcm2835: use devm_spi_register_master()') Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- drivers/spi/spi-bcm2835.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 4c332143a310..3c5aca8d677a 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -377,7 +377,7 @@ out_master_put: static int bcm2835_spi_remove(struct platform_device *pdev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = platform_get_drvdata(pdev); struct bcm2835_spi *bs = spi_master_get_devdata(master); free_irq(bs->irq, master); -- cgit v1.2.3 From 53063ec6e2cc38000f98a5de557b7e4fed186cfc Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Nov 2013 15:44:02 +0800 Subject: spi: rspi: use platform drvdata correctly in rspi_remove() We had set the platform drvdata in rspi_probe() as a type of struct rspi_data, but use it as struct spi_master in rspi_remove() Fix by remove the unnecessary spi_master_[get|put]() since rspi->master is no longer used after spi_unregister_master(). Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 58449ad4ad0d..9e829cee7357 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -885,14 +885,13 @@ static void rspi_release_dma(struct rspi_data *rspi) static int rspi_remove(struct platform_device *pdev) { - struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev)); + struct rspi_data *rspi = platform_get_drvdata(pdev); spi_unregister_master(rspi->master); rspi_release_dma(rspi); free_irq(platform_get_irq(pdev, 0), rspi); clk_put(rspi->clk); iounmap(rspi->addr); - spi_master_put(rspi->master); return 0; } -- cgit v1.2.3 From a4469a429fc71af6bad9c9e3f7307249dedfe8d1 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Nov 2013 15:48:56 +0800 Subject: spi: mpc512x: fix reference leak to master in mpc512x_psc_spi_do_remove() Once a spi_master_get() call succeeds, we need an additional spi_master_put() call to free the memory, otherwise we will leak a reference to master. Fix by removing the unnecessary spi_master_get() call. Fixes: eaa24297846b ('spi: mpc512x: use devm_spi_register_master()') Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- drivers/spi/spi-mpc512x-psc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index ee6e61cbf7f5..e9f22a802cdb 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -556,7 +556,7 @@ free_master: static int mpc512x_psc_spi_do_remove(struct device *dev) { - struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct spi_master *master = dev_get_drvdata(dev); struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); clk_disable_unprepare(mps->clk_mclk); -- cgit v1.2.3 From b38f87ec503ac68e5c38044101eedba869a56b0d Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Nov 2013 15:49:29 +0800 Subject: spi: txx9: fix reference leak to master in txx9spi_remove() Once a spi_master_get() call succeeds, we need an additional spi_master_put() call to free the memory, otherwise we will leak a reference to master. Fix by removing the unnecessary spi_master_get() call. Fixes: 2fe7e4add3e5 ('spi: txx9: use devm_spi_register_master()') Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- drivers/spi/spi-txx9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 637cce2b8bdd..18c9bb2b5f39 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c @@ -425,7 +425,7 @@ exit: static int txx9spi_remove(struct platform_device *dev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(dev)); + struct spi_master *master = platform_get_drvdata(dev); struct txx9spi *c = spi_master_get_devdata(master); destroy_workqueue(c->workqueue); -- cgit v1.2.3 From ec3252687ae4ad0c3889010aee726c7a05606fe0 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Nov 2013 15:50:59 +0800 Subject: spi: bcm63xx: fix reference leak to master in bcm63xx_spi_remove() Once a spi_master_get() call succeeds, we need an additional spi_master_put() call to free the memory, otherwise we will leak a reference to master. Fix by removing the unnecessary spi_master_get() call. Fixes: 247263dba208 ('spi: bcm63xx: use devm_spi_register_master()') Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 80d56b214eb5..469ecd876358 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -435,7 +435,7 @@ out: static int bcm63xx_spi_remove(struct platform_device *pdev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = platform_get_drvdata(pdev); struct bcm63xx_spi *bs = spi_master_get_devdata(master); /* reset spi block */ -- cgit v1.2.3 From 71bfae9097a94bb9a07afc6c16077429d3e40709 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 15 Nov 2013 14:22:15 +0000 Subject: swiotlb-xen: add missing xen_dma_map_page call swiotlb-xen is missing a xen_dma_map_page call in xen_swiotlb_map_sg_attrs, in the bounce buffer path. Signed-off-by: Stefano Stabellini Acked-by: Konrad Rzeszutek Wilk --- drivers/xen/swiotlb-xen.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index a224bc74b6b9..1eac0731c349 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -555,6 +555,11 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, sg_dma_len(sgl) = 0; return 0; } + xen_dma_map_page(hwdev, pfn_to_page(map >> PAGE_SHIFT), + map & ~PAGE_MASK, + sg->length, + dir, + attrs); sg->dma_address = xen_phys_to_bus(map); } else { /* we are not interested in the dma_addr returned by -- cgit v1.2.3 From e322ce9365693b417867f6bd700ddf09cca36b37 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Nov 2013 15:50:31 +0800 Subject: spi: spi-mxs: fix reference leak to master in mxs_spi_remove() Once a spi_master_get() call succeeds, we need an additional spi_master_put() call to free the memory, otherwise we will leak a reference to master. Fix by removing the unnecessary spi_master_get() call. Fixes: 33e195acf268 ('spi: mxs: use devm_spi_register_master()') Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- drivers/spi/spi-mxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index de333059a9a7..37b3e41bf46f 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -565,7 +565,7 @@ static int mxs_spi_remove(struct platform_device *pdev) struct mxs_spi *spi; struct mxs_ssp *ssp; - master = spi_master_get(platform_get_drvdata(pdev)); + master = platform_get_drvdata(pdev); spi = spi_master_get_devdata(master); ssp = &spi->ssp; -- cgit v1.2.3 From a4a5fc3b64cd553820d97667056506636eaaba77 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 8 Nov 2013 11:07:59 +0100 Subject: clocksource: sh_mtu2: Release clock when sh_mtu2_register() fails Fix the probe error path to release the clock resource when the sh_mtu2_register() call fails. Cc: Daniel Lezcano Cc: linux-kernel@vger.kernel.org Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Signed-off-by: Daniel Lezcano --- drivers/clocksource/sh_mtu2.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 4aac9ee0d0c0..e6cfb328eb2e 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -313,8 +313,15 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) goto err1; } - return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), - cfg->clockevent_rating); + ret = sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), + cfg->clockevent_rating); + if (ret < 0) + goto err2; + + return 0; + + err2: + clk_put(p->clk); err1: iounmap(p->mapbase); err0: -- cgit v1.2.3 From bd7549308eed47b3750b3dab692034a553e75663 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 8 Nov 2013 11:07:59 +0100 Subject: clocksource: sh_mtu2: Add clk_prepare/unprepare support Prepare the clock at probe time, as there is no other appropriate place in the driver where we're allowed to sleep. Cc: Daniel Lezcano Cc: linux-kernel@vger.kernel.org Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Signed-off-by: Daniel Lezcano --- drivers/clocksource/sh_mtu2.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index e6cfb328eb2e..3cf12834681e 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -313,13 +313,18 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) goto err1; } + ret = clk_prepare(p->clk); + if (ret < 0) + goto err2; + ret = sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), cfg->clockevent_rating); if (ret < 0) - goto err2; + goto err3; return 0; - + err3: + clk_unprepare(p->clk); err2: clk_put(p->clk); err1: -- cgit v1.2.3 From 394a4486f009a184b58fc2f2435d6f5f800870bb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 8 Nov 2013 11:07:59 +0100 Subject: clocksource: sh_tmu: Release clock when sh_tmu_register() fails Fix the probe error path to release the clock resource when the sh_tmu_register() call fails. Cc: Daniel Lezcano Cc: linux-kernel@vger.kernel.org Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Signed-off-by: Daniel Lezcano --- drivers/clocksource/sh_tmu.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 78b8dae49628..15978372c937 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -475,9 +475,16 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) p->cs_enabled = false; p->enable_count = 0; - return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), - cfg->clockevent_rating, - cfg->clocksource_rating); + ret = sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), + cfg->clockevent_rating, + cfg->clocksource_rating); + if (ret < 0) + goto err2; + + return 0; + + err2: + clk_put(p->clk); err1: iounmap(p->mapbase); err0: -- cgit v1.2.3 From 1c09eb3e2d761ffd152faa6b9d06caf560e7d445 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 8 Nov 2013 11:08:00 +0100 Subject: clocksource: sh_tmu: Add clk_prepare/unprepare support Prepare the clock at probe time, as there is no other appropriate place in the driver where we're allowed to sleep. Cc: Daniel Lezcano Cc: linux-kernel@vger.kernel.org Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Signed-off-by: Daniel Lezcano --- drivers/clocksource/sh_tmu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 15978372c937..63557cda0a7d 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -472,6 +472,11 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) ret = PTR_ERR(p->clk); goto err1; } + + ret = clk_prepare(p->clk); + if (ret < 0) + goto err2; + p->cs_enabled = false; p->enable_count = 0; @@ -479,10 +484,12 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) cfg->clockevent_rating, cfg->clocksource_rating); if (ret < 0) - goto err2; + goto err3; return 0; + err3: + clk_unprepare(p->clk); err2: clk_put(p->clk); err1: -- cgit v1.2.3 From 77f7ce9a9f636daaa65731a833bae1311a7b80e5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 20 Nov 2013 12:02:03 -0800 Subject: clocksource: arm_arch_timer: Hide eventstream Kconfig on non-ARM Pavel Machek reports that this config is exposed on x86 where the ARM architected timers aren't even present. Make it depend on the ARM architected timers being selected so that non-ARM builds aren't asked about it. Reported-by: Pavel Machek Reviewed-by: Pavel Machek Signed-off-by: Stephen Boyd Signed-off-by: Daniel Lezcano --- drivers/clocksource/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index bdb953e15d2a..5c07a56962db 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -87,6 +87,7 @@ config ARM_ARCH_TIMER config ARM_ARCH_TIMER_EVTSTREAM bool "Support for ARM architected timer event stream generation" default y if ARM_ARCH_TIMER + depends on ARM_ARCH_TIMER help This option enables support for event stream generation based on the ARM architected timer. It is used for waking up CPUs executing -- cgit v1.2.3 From 4b92894ee70c9110c083aa60b0663d357495864d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 21 Nov 2013 16:11:15 -0700 Subject: spi: core: invert success test in devm_spi_register_master devres_add() should be called when the action to be undone succeeded, not when it failed. Fix the inverted test in devm_spi_register_master() which was doing the opposite. The user-visible issue without this fix is: insmod spi-tegra114.ko Assume there's an MTD device on that SPI bus, which creates /dev/mtd0. rmmod spi-tegra114 Doesn't remove devices on the SPI bus. insmod spi-tegra114.ko Creates a duplicate SPI device which creates /dev/mtd1. hexdump -C /dev/mtd0 That's the old device, which uses an SPI bus hosted by a non-existent module, which causes the oops below. Unable to handle kernel paging request at virtual address bf0017c0 pgd = c0004000 [bf0017c0] *pgd=ad51b811, *pte=00000000, *ppte=00000000 Internal error: Oops: 80000007 [#1] PREEMPT SMP ARM ... PC is at 0xbf0017c0 LR is at spi_pump_messages+0x15c/0x204 pc : [] lr : [] psr: 60000113 ... Fixes: 666d5b4c742b ("spi: core: Add devm_spi_register_master()") Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 8d05accf706c..481e13f0db54 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1390,7 +1390,7 @@ int devm_spi_register_master(struct device *dev, struct spi_master *master) return -ENOMEM; ret = spi_register_master(master); - if (ret != 0) { + if (!ret) { *ptr = master; devres_add(dev, ptr); } else { -- cgit v1.2.3 From d4360d6fb61af7aa8e027bf5983598d5437737cc Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 22 Nov 2013 12:51:09 -0600 Subject: be2net: Disabling and enabling interrupts in suspend and resume Interrupts need to be enabled in be_resume, when adapter boots back up from D3cold. disabling interrupts in be_suspend() just to be symmetric to be_resume(). Signed-off-by: Ravikumar Nelavelli Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index abde97471636..9b148cf04704 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4599,6 +4599,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) if (adapter->wol) be_setup_wol(adapter, true); + be_intr_set(adapter, false); cancel_delayed_work_sync(&adapter->func_recovery_work); netif_device_detach(netdev); @@ -4634,6 +4635,7 @@ static int be_resume(struct pci_dev *pdev) if (status) return status; + be_intr_set(adapter, true); /* tell fw we're ready to fire cmds */ status = be_cmd_fw_init(adapter); if (status) -- cgit v1.2.3 From 09e83a9d449c1af533321f5bda62b6a59a4098c6 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 22 Nov 2013 12:51:20 -0600 Subject: be2net: set coalesce-wm in CQ_CREATE_V2 cmd It is not being set currently. (This field is not applicable for Lancer) Signed-off-by: Vasundhara Volam Signed-off-by: Sathya Perla Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index dbcd5262c016..e0e8bc1ef14c 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -1032,6 +1032,13 @@ int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq, } else { req->hdr.version = 2; req->page_size = 1; /* 1 for 4K */ + + /* coalesce-wm field in this cmd is not relevant to Lancer. + * Lancer uses COMMON_MODIFY_CQ to set this field + */ + if (!lancer_chip(adapter)) + AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm, + ctxt, coalesce_wm); AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt, no_delay); AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt, -- cgit v1.2.3 From 2c7a9dc1641664173211c4ebc5db510a08684c46 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 22 Nov 2013 12:51:28 -0600 Subject: be2net: Avoid programming permenant MAC by BE3-R VFs On BE3-R, the PF programs the initial MAC address for its VFs. Doing it again in VF probe, causes a FW error which although harmless generates an unnecessary error log message. Signed-off-by: Vasundhara Volam Signed-off-by: Sathya Perla Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 1 + drivers/net/ethernet/emulex/benet/be_main.c | 10 ++++------ 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index f4825db5d179..5878df619b53 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -503,6 +503,7 @@ struct be_adapter { }; #define be_physfn(adapter) (!adapter->virtfn) +#define be_virtfn(adapter) (adapter->virtfn) #define sriov_enabled(adapter) (adapter->num_vfs > 0) #define sriov_want(adapter) (be_physfn(adapter) && \ (num_vfs || pci_num_vf(adapter->pdev))) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 9b148cf04704..78a0e859760b 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3253,12 +3253,10 @@ static int be_mac_setup(struct be_adapter *adapter) memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN); } - /* On BE3 VFs this cmd may fail due to lack of privilege. - * Ignore the failure as in this case pmac_id is fetched - * in the IFACE_CREATE cmd. - */ - be_cmd_pmac_add(adapter, mac, adapter->if_handle, - &adapter->pmac_id[0], 0); + /* For BE3-R VFs, the PF programs the initial MAC address */ + if (!(BEx_chip(adapter) && be_virtfn(adapter))) + be_cmd_pmac_add(adapter, mac, adapter->if_handle, + &adapter->pmac_id[0], 0); return 0; } -- cgit v1.2.3 From 54acbd9688e6324470671525c7916011f1ff8081 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 12 Nov 2013 12:06:21 +0200 Subject: spi/pxa2xx: add new ACPI IDs Newer Intel PCHs with LPSS have the same SPI controllers than Haswell but ACPI IDs are different. Add these IDs to the driver list. Signed-off-by: Mika Westerberg Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-pxa2xx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index cb0e1f1137ad..7028180a020a 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1073,6 +1073,8 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) static struct acpi_device_id pxa2xx_spi_acpi_match[] = { { "INT33C0", 0 }, { "INT33C1", 0 }, + { "INT3430", 0 }, + { "INT3431", 0 }, { "80860F0E", 0 }, { }, }; -- cgit v1.2.3 From 160a061301c7adf54c40696e7ceedc73f6b747dd Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Nov 2013 14:13:41 +0800 Subject: spi/qspi: set correct platform drvdata in ti_qspi_probe() The ti_qspi_remove() use the platform drvdata as a type of struct ti_qspi, we should pass correct platform drvdata to platform_set_drvdata() in ti_qspi_probe(). Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 0b71270fbf67..e147ed42e1fc 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -459,11 +459,10 @@ static int ti_qspi_probe(struct platform_device *pdev) if (!of_property_read_u32(np, "num-cs", &num_cs)) master->num_chipselect = num_cs; - platform_set_drvdata(pdev, master); - qspi = spi_master_get_devdata(master); qspi->master = master; qspi->dev = &pdev->dev; + platform_set_drvdata(pdev, qspi); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.3 From 05b96675dbfc97fbb66d58cacbf2c8def020375e Mon Sep 17 00:00:00 2001 From: Sourav Poddar Date: Tue, 19 Nov 2013 18:37:15 +0530 Subject: spi/qspi: cleanup pm_runtime error check. clean up pm_runtime error check in accordance with rest of the check in the driver. Signed-off-by: Sourav Poddar Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index e147ed42e1fc..f3c3c3f7aaed 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -161,7 +161,7 @@ static int ti_qspi_setup(struct spi_device *spi) qspi->spi_max_frequency, clk_div); ret = pm_runtime_get_sync(qspi->dev); - if (ret) { + if (ret < 0) { dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); return ret; } -- cgit v1.2.3 From cbcabb7a300bf5ab868c632048889a933e7cdae5 Mon Sep 17 00:00:00 2001 From: Sourav Poddar Date: Tue, 19 Nov 2013 18:37:16 +0530 Subject: spi/qspi: Fix qspi remove path. There is a bug in qspi removal path, as a result of which qspi cannot be removed when used as a module. The patch solves the bug and qspi can be removed cleanly. The bugs fixed are: -pm_runtime used around register access. - pm_runtime_disable need to be done before removal. - spi_unregister_master need to be called to unregister the spi device. Tested on DRA7 board. Signed-off-by: Sourav Poddar Signed-off-by: Mark Brown --- drivers/spi/spi-ti-qspi.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index f3c3c3f7aaed..4396bd448540 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -516,10 +516,26 @@ free_master: static int ti_qspi_remove(struct platform_device *pdev) { - struct ti_qspi *qspi = platform_get_drvdata(pdev); + struct spi_master *master; + struct ti_qspi *qspi; + int ret; + + master = platform_get_drvdata(pdev); + qspi = spi_master_get_devdata(master); + + ret = pm_runtime_get_sync(qspi->dev); + if (ret < 0) { + dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); + return ret; + } ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); + pm_runtime_put(qspi->dev); + pm_runtime_disable(&pdev->dev); + + spi_unregister_master(master); + return 0; } -- cgit v1.2.3 From c170bbb45febc03ac4d34ba2b8bb55e06104b7e7 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 24 Nov 2013 16:32:22 -0700 Subject: block: submit_bio_wait() conversions It was being open coded in a few places. Signed-off-by: Kent Overstreet Cc: Jens Axboe Cc: Joern Engel Cc: Prasad Joshi Cc: Neil Brown Cc: Chris Mason Acked-by: NeilBrown Signed-off-by: Jens Axboe --- block/blk-flush.c | 19 +------------------ drivers/md/md.c | 12 +----------- fs/btrfs/check-integrity.c | 32 +++++++++++++------------------- fs/btrfs/check-integrity.h | 2 ++ fs/btrfs/extent_io.c | 12 +----------- fs/btrfs/scrub.c | 33 ++++----------------------------- fs/hfsplus/wrapper.c | 17 +---------------- fs/logfs/dev_bdev.c | 13 +------------ 8 files changed, 24 insertions(+), 116 deletions(-) (limited to 'drivers') diff --git a/block/blk-flush.c b/block/blk-flush.c index 331e627301ea..fb6f3c0ffa49 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -502,15 +502,6 @@ void blk_abort_flushes(struct request_queue *q) } } -static void bio_end_flush(struct bio *bio, int err) -{ - if (err) - clear_bit(BIO_UPTODATE, &bio->bi_flags); - if (bio->bi_private) - complete(bio->bi_private); - bio_put(bio); -} - /** * blkdev_issue_flush - queue a flush * @bdev: blockdev to issue flush for @@ -526,7 +517,6 @@ static void bio_end_flush(struct bio *bio, int err) int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask, sector_t *error_sector) { - DECLARE_COMPLETION_ONSTACK(wait); struct request_queue *q; struct bio *bio; int ret = 0; @@ -548,13 +538,9 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask, return -ENXIO; bio = bio_alloc(gfp_mask, 0); - bio->bi_end_io = bio_end_flush; bio->bi_bdev = bdev; - bio->bi_private = &wait; - bio_get(bio); - submit_bio(WRITE_FLUSH, bio); - wait_for_completion_io(&wait); + ret = submit_bio_wait(WRITE_FLUSH, bio); /* * The driver must store the error location in ->bi_sector, if @@ -564,9 +550,6 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask, if (error_sector) *error_sector = bio->bi_sector; - if (!bio_flagged(bio, BIO_UPTODATE)) - ret = -EIO; - bio_put(bio); return ret; } diff --git a/drivers/md/md.c b/drivers/md/md.c index b6b7a2866c9e..8700de376876 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -776,16 +776,10 @@ void md_super_wait(struct mddev *mddev) finish_wait(&mddev->sb_wait, &wq); } -static void bi_complete(struct bio *bio, int error) -{ - complete((struct completion*)bio->bi_private); -} - int sync_page_io(struct md_rdev *rdev, sector_t sector, int size, struct page *page, int rw, bool metadata_op) { struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev); - struct completion event; int ret; rw |= REQ_SYNC; @@ -801,11 +795,7 @@ int sync_page_io(struct md_rdev *rdev, sector_t sector, int size, else bio->bi_sector = sector + rdev->data_offset; bio_add_page(bio, page, size, 0); - init_completion(&event); - bio->bi_private = &event; - bio->bi_end_io = bi_complete; - submit_bio(rw, bio); - wait_for_completion(&event); + submit_bio_wait(rw, bio); ret = test_bit(BIO_UPTODATE, &bio->bi_flags); bio_put(bio); diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index e0aab4456974..f85b1c409003 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -323,7 +323,6 @@ static void btrfsic_release_block_ctx(struct btrfsic_block_data_ctx *block_ctx); static int btrfsic_read_block(struct btrfsic_state *state, struct btrfsic_block_data_ctx *block_ctx); static void btrfsic_dump_database(struct btrfsic_state *state); -static void btrfsic_complete_bio_end_io(struct bio *bio, int err); static int btrfsic_test_for_metadata(struct btrfsic_state *state, char **datav, unsigned int num_pages); static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, @@ -1677,7 +1676,6 @@ static int btrfsic_read_block(struct btrfsic_state *state, for (i = 0; i < num_pages;) { struct bio *bio; unsigned int j; - DECLARE_COMPLETION_ONSTACK(complete); bio = btrfs_io_bio_alloc(GFP_NOFS, num_pages - i); if (!bio) { @@ -1688,8 +1686,6 @@ static int btrfsic_read_block(struct btrfsic_state *state, } bio->bi_bdev = block_ctx->dev->bdev; bio->bi_sector = dev_bytenr >> 9; - bio->bi_end_io = btrfsic_complete_bio_end_io; - bio->bi_private = &complete; for (j = i; j < num_pages; j++) { ret = bio_add_page(bio, block_ctx->pagev[j], @@ -1702,12 +1698,7 @@ static int btrfsic_read_block(struct btrfsic_state *state, "btrfsic: error, failed to add a single page!\n"); return -1; } - submit_bio(READ, bio); - - /* this will also unplug the queue */ - wait_for_completion(&complete); - - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { + if (submit_bio_wait(READ, bio)) { printk(KERN_INFO "btrfsic: read error at logical %llu dev %s!\n", block_ctx->start, block_ctx->dev->name); @@ -1730,11 +1721,6 @@ static int btrfsic_read_block(struct btrfsic_state *state, return block_ctx->len; } -static void btrfsic_complete_bio_end_io(struct bio *bio, int err) -{ - complete((struct completion *)bio->bi_private); -} - static void btrfsic_dump_database(struct btrfsic_state *state) { struct list_head *elem_all; @@ -2998,14 +2984,12 @@ int btrfsic_submit_bh(int rw, struct buffer_head *bh) return submit_bh(rw, bh); } -void btrfsic_submit_bio(int rw, struct bio *bio) +static void __btrfsic_submit_bio(int rw, struct bio *bio) { struct btrfsic_dev_state *dev_state; - if (!btrfsic_is_initialized) { - submit_bio(rw, bio); + if (!btrfsic_is_initialized) return; - } mutex_lock(&btrfsic_mutex); /* since btrfsic_submit_bio() is also called before @@ -3097,10 +3081,20 @@ void btrfsic_submit_bio(int rw, struct bio *bio) } leave: mutex_unlock(&btrfsic_mutex); +} +void btrfsic_submit_bio(int rw, struct bio *bio) +{ + __btrfsic_submit_bio(rw, bio); submit_bio(rw, bio); } +int btrfsic_submit_bio_wait(int rw, struct bio *bio) +{ + __btrfsic_submit_bio(rw, bio); + return submit_bio_wait(rw, bio); +} + int btrfsic_mount(struct btrfs_root *root, struct btrfs_fs_devices *fs_devices, int including_extent_data, u32 print_mask) diff --git a/fs/btrfs/check-integrity.h b/fs/btrfs/check-integrity.h index 8b59175cc502..13b8566c97ab 100644 --- a/fs/btrfs/check-integrity.h +++ b/fs/btrfs/check-integrity.h @@ -22,9 +22,11 @@ #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY int btrfsic_submit_bh(int rw, struct buffer_head *bh); void btrfsic_submit_bio(int rw, struct bio *bio); +int btrfsic_submit_bio_wait(int rw, struct bio *bio); #else #define btrfsic_submit_bh submit_bh #define btrfsic_submit_bio submit_bio +#define btrfsic_submit_bio_wait submit_bio_wait #endif int btrfsic_mount(struct btrfs_root *root, diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 856bc2b2192c..014beaa9458c 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1952,11 +1952,6 @@ static int free_io_failure(struct inode *inode, struct io_failure_record *rec, return err; } -static void repair_io_failure_callback(struct bio *bio, int err) -{ - complete(bio->bi_private); -} - /* * this bypasses the standard btrfs submit functions deliberately, as * the standard behavior is to write all copies in a raid setup. here we only @@ -1973,7 +1968,6 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, { struct bio *bio; struct btrfs_device *dev; - DECLARE_COMPLETION_ONSTACK(compl); u64 map_length = 0; u64 sector; struct btrfs_bio *bbio = NULL; @@ -1989,8 +1983,6 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, bio = btrfs_io_bio_alloc(GFP_NOFS, 1); if (!bio) return -EIO; - bio->bi_private = &compl; - bio->bi_end_io = repair_io_failure_callback; bio->bi_size = 0; map_length = length; @@ -2011,10 +2003,8 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, } bio->bi_bdev = dev->bdev; bio_add_page(bio, page, length, start - page_offset(page)); - btrfsic_submit_bio(WRITE_SYNC, bio); - wait_for_completion(&compl); - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { + if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) { /* try to remap that extent elsewhere? */ bio_put(bio); btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS); diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 2544805544f0..3214ebe593bd 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -208,7 +208,6 @@ static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, int is_metadata, int have_csum, const u8 *csum, u64 generation, u16 csum_size); -static void scrub_complete_bio_end_io(struct bio *bio, int err); static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad, struct scrub_block *sblock_good, int force_write); @@ -1292,7 +1291,6 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info, for (page_num = 0; page_num < sblock->page_count; page_num++) { struct bio *bio; struct scrub_page *page = sblock->pagev[page_num]; - DECLARE_COMPLETION_ONSTACK(complete); if (page->dev->bdev == NULL) { page->io_error = 1; @@ -1309,18 +1307,11 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info, } bio->bi_bdev = page->dev->bdev; bio->bi_sector = page->physical >> 9; - bio->bi_end_io = scrub_complete_bio_end_io; - bio->bi_private = &complete; bio_add_page(bio, page->page, PAGE_SIZE, 0); - btrfsic_submit_bio(READ, bio); - - /* this will also unplug the queue */ - wait_for_completion(&complete); - - page->io_error = !test_bit(BIO_UPTODATE, &bio->bi_flags); - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) + if (btrfsic_submit_bio_wait(READ, bio)) sblock->no_io_error_seen = 0; + bio_put(bio); } @@ -1389,11 +1380,6 @@ static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, sblock->checksum_error = 1; } -static void scrub_complete_bio_end_io(struct bio *bio, int err) -{ - complete((struct completion *)bio->bi_private); -} - static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad, struct scrub_block *sblock_good, int force_write) @@ -1428,7 +1414,6 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, sblock_bad->checksum_error || page_bad->io_error) { struct bio *bio; int ret; - DECLARE_COMPLETION_ONSTACK(complete); if (!page_bad->dev->bdev) { printk_ratelimited(KERN_WARNING @@ -1441,19 +1426,14 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, return -EIO; bio->bi_bdev = page_bad->dev->bdev; bio->bi_sector = page_bad->physical >> 9; - bio->bi_end_io = scrub_complete_bio_end_io; - bio->bi_private = &complete; ret = bio_add_page(bio, page_good->page, PAGE_SIZE, 0); if (PAGE_SIZE != ret) { bio_put(bio); return -EIO; } - btrfsic_submit_bio(WRITE, bio); - /* this will also unplug the queue */ - wait_for_completion(&complete); - if (!bio_flagged(bio, BIO_UPTODATE)) { + if (btrfsic_submit_bio_wait(WRITE, bio)) { btrfs_dev_stat_inc_and_print(page_bad->dev, BTRFS_DEV_STAT_WRITE_ERRS); btrfs_dev_replace_stats_inc( @@ -3373,7 +3353,6 @@ static int write_page_nocow(struct scrub_ctx *sctx, struct bio *bio; struct btrfs_device *dev; int ret; - DECLARE_COMPLETION_ONSTACK(compl); dev = sctx->wr_ctx.tgtdev; if (!dev) @@ -3390,8 +3369,6 @@ static int write_page_nocow(struct scrub_ctx *sctx, spin_unlock(&sctx->stat_lock); return -ENOMEM; } - bio->bi_private = &compl; - bio->bi_end_io = scrub_complete_bio_end_io; bio->bi_size = 0; bio->bi_sector = physical_for_dev_replace >> 9; bio->bi_bdev = dev->bdev; @@ -3402,10 +3379,8 @@ leave_with_eio: btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS); return -EIO; } - btrfsic_submit_bio(WRITE_SYNC, bio); - wait_for_completion(&compl); - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) + if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) goto leave_with_eio; bio_put(bio); diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index b51a6079108d..e9a97a0d4314 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c @@ -24,13 +24,6 @@ struct hfsplus_wd { u16 embed_count; }; -static void hfsplus_end_io_sync(struct bio *bio, int err) -{ - if (err) - clear_bit(BIO_UPTODATE, &bio->bi_flags); - complete(bio->bi_private); -} - /* * hfsplus_submit_bio - Perfrom block I/O * @sb: super block of volume for I/O @@ -53,7 +46,6 @@ static void hfsplus_end_io_sync(struct bio *bio, int err) int hfsplus_submit_bio(struct super_block *sb, sector_t sector, void *buf, void **data, int rw) { - DECLARE_COMPLETION_ONSTACK(wait); struct bio *bio; int ret = 0; u64 io_size; @@ -73,8 +65,6 @@ int hfsplus_submit_bio(struct super_block *sb, sector_t sector, bio = bio_alloc(GFP_NOIO, 1); bio->bi_sector = sector; bio->bi_bdev = sb->s_bdev; - bio->bi_end_io = hfsplus_end_io_sync; - bio->bi_private = &wait; if (!(rw & WRITE) && data) *data = (u8 *)buf + offset; @@ -93,12 +83,7 @@ int hfsplus_submit_bio(struct super_block *sb, sector_t sector, buf = (u8 *)buf + len; } - submit_bio(rw, bio); - wait_for_completion(&wait); - - if (!bio_flagged(bio, BIO_UPTODATE)) - ret = -EIO; - + ret = submit_bio_wait(rw, bio); out: bio_put(bio); return ret < 0 ? ret : 0; diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index 550475ca6a0e..0f95f0d0b313 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c @@ -14,16 +14,10 @@ #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1)) -static void request_complete(struct bio *bio, int err) -{ - complete((struct completion *)bio->bi_private); -} - static int sync_request(struct page *page, struct block_device *bdev, int rw) { struct bio bio; struct bio_vec bio_vec; - struct completion complete; bio_init(&bio); bio.bi_max_vecs = 1; @@ -35,13 +29,8 @@ static int sync_request(struct page *page, struct block_device *bdev, int rw) bio.bi_size = PAGE_SIZE; bio.bi_bdev = bdev; bio.bi_sector = page->index * (PAGE_SIZE >> 9); - init_completion(&complete); - bio.bi_private = &complete; - bio.bi_end_io = request_complete; - submit_bio(rw, &bio); - wait_for_completion(&complete); - return test_bit(BIO_UPTODATE, &bio.bi_flags) ? 0 : -EIO; + return submit_bio_wait(rw, &bio); } static int bdev_readpage(void *_sb, struct page *page) -- cgit v1.2.3 From 38d321c899457be111f1a1bcd8c8d1ca18772072 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Nov 2013 02:01:38 -0800 Subject: pinctrl: rockchip: testing the wrong variable There is a copy and paste bug so we test "info->reg_base" instead of "info->reg_pull". Signed-off-by: Dan Carpenter Acked-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index e939c28cbf1f..fe2ec1bdf56e 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1453,8 +1453,8 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) if (ctrl->type == RK3188) { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); info->reg_pull = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(info->reg_base)) - return PTR_ERR(info->reg_base); + if (IS_ERR(info->reg_pull)) + return PTR_ERR(info->reg_pull); } ret = rockchip_gpiolib_register(pdev, info); -- cgit v1.2.3 From c590854dffc06095f38a63b3bdb9e4370282a53e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 10 Nov 2013 02:35:56 +0300 Subject: pinctrl: abx500: fix some more bitwise AND tests I sent a patch to fix some bitwise AND tests but I guess I missed some. Sorry about that. Signed-off-by: Dan Carpenter Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-abx500.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c index 4780959e11d4..5183e7bb8de3 100644 --- a/drivers/pinctrl/pinctrl-abx500.c +++ b/drivers/pinctrl/pinctrl-abx500.c @@ -418,7 +418,7 @@ static int abx500_set_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG, af.alt_bit1, - !!(af.alta_val && BIT(0))); + !!(af.alta_val & BIT(0))); if (ret < 0) goto out; @@ -439,7 +439,7 @@ static int abx500_set_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, goto out; ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG, - af.alt_bit1, !!(af.altb_val && BIT(0))); + af.alt_bit1, !!(af.altb_val & BIT(0))); if (ret < 0) goto out; @@ -462,7 +462,7 @@ static int abx500_set_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, goto out; ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG, - af.alt_bit2, !!(af.altc_val && BIT(1))); + af.alt_bit2, !!(af.altc_val & BIT(1))); break; default: -- cgit v1.2.3 From d32c3e260f95f5d8ed42c64dc2d9ec79cc36da1e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Nov 2013 11:22:54 +0300 Subject: pinctrl: rockchip: missing unlock on error in rockchip_set_pull() We need to unlock here before returning -EINVAL. Fixes: 6ca5274d1d12 ('pinctrl: rockchip: add rk3188 specifics') Signed-off-by: Dan Carpenter Acked-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index fe2ec1bdf56e..46dddc159286 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -504,6 +504,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, data |= (3 << bit); break; default: + spin_unlock_irqrestore(&bank->slock, flags); dev_err(info->dev, "unsupported pull setting %d\n", pull); return -EINVAL; -- cgit v1.2.3 From c9e2d69a1801045f28668e6853d9dccadbfbe494 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Thu, 22 Aug 2013 15:27:46 +0300 Subject: clk: tegra: replace enum tegra114_clk by binding header As the clock IDs are now specified in a header file, we can use those definitions instead of maintaining an internal enum. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra114.c | 431 ++++++++++++++++++--------------------- 1 file changed, 198 insertions(+), 233 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9467da7dee49..15d94d0d44d9 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "clk.h" @@ -864,43 +865,6 @@ static unsigned long tegra114_input_freq[] = { periph_clk_enb_refcnt, _gate_flags , _clk_id, \ mux_d_audio_clk_idx, 0) -enum tegra114_clk { - rtc = 4, timer = 5, uarta = 6, sdmmc2 = 9, i2s1 = 11, i2c1 = 12, - ndflash = 13, sdmmc1 = 14, sdmmc4 = 15, pwm = 17, i2s2 = 18, epp = 19, - gr_2d = 21, usbd = 22, isp = 23, gr_3d = 24, disp2 = 26, disp1 = 27, - host1x = 28, vcp = 29, i2s0 = 30, apbdma = 34, kbc = 36, kfuse = 40, - sbc1 = 41, nor = 42, sbc2 = 44, sbc3 = 46, i2c5 = 47, dsia = 48, - mipi = 50, hdmi = 51, csi = 52, i2c2 = 54, uartc = 55, mipi_cal = 56, - emc, usb2, usb3, vde = 61, bsea = 62, bsev = 63, uartd = 65, - i2c3 = 67, sbc4 = 68, sdmmc3 = 69, owr = 71, csite = 73, - la = 76, trace = 77, soc_therm = 78, dtv = 79, ndspeed = 80, - i2cslow = 81, dsib = 82, tsec = 83, xusb_host = 89, msenc = 91, - csus = 92, mselect = 99, tsensor = 100, i2s3 = 101, i2s4 = 102, - i2c4 = 103, sbc5 = 104, sbc6 = 105, d_audio, apbif = 107, dam0, dam1, - dam2, hda2codec_2x = 111, audio0_2x = 113, audio1_2x, audio2_2x, - audio3_2x, audio4_2x, spdif_2x, actmon = 119, extern1 = 120, - extern2 = 121, extern3 = 122, hda = 125, se = 127, hda2hdmi = 128, - cilab = 144, cilcd = 145, cile = 146, dsialp = 147, dsiblp = 148, - dds = 150, dp2 = 152, amx = 153, adx = 154, xusb_ss = 156, uartb = 192, - vfir, spdif_in, spdif_out, vi, vi_sensor, fuse, fuse_burn, clk_32k, - clk_m, clk_m_div2, clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_c2, - pll_c3, pll_m, pll_m_out1, pll_p, pll_p_out1, pll_p_out2, pll_p_out3, - pll_p_out4, pll_a, pll_a_out0, pll_d, pll_d_out0, pll_d2, pll_d2_out0, - pll_u, pll_u_480M, pll_u_60M, pll_u_48M, pll_u_12M, pll_x, pll_x_out0, - pll_re_vco, pll_re_out, pll_e_out0, spdif_in_sync, i2s0_sync, - i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, vimclk_sync, audio0, - audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3, - blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src, - xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp, - dfll_ref = 264, dfll_soc, - - /* Mux clocks */ - - audio0_mux = 300, audio1_mux, audio2_mux, audio3_mux, audio4_mux, - spdif_mux, clk_out_1_mux, clk_out_2_mux, clk_out_3_mux, dsia_mux, - dsib_mux, clk_max, -}; - struct utmi_clk_param { /* Oscillator Frequency in KHz */ u32 osc_frequency; @@ -1064,7 +1028,7 @@ static const struct clk_div_table pll_re_div_table[] = { { .val = 0, .div = 0 }, }; -static struct clk *clks[clk_max]; +static struct clk *clks[TEGRA114_CLK_CLK_MAX]; static struct clk_onecell_data clk_data; static unsigned long osc_freq; @@ -1087,7 +1051,7 @@ static int __init tegra114_osc_clk_init(void __iomem *clk_base) clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, osc_freq); clk_register_clkdev(clk, "clk_m", NULL); - clks[clk_m] = clk; + clks[TEGRA114_CLK_CLK_M] = clk; /* pll_ref */ val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; @@ -1095,7 +1059,7 @@ static int __init tegra114_osc_clk_init(void __iomem *clk_base) clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", CLK_SET_RATE_PARENT, 1, pll_ref_div); clk_register_clkdev(clk, "pll_ref", NULL); - clks[pll_ref] = clk; + clks[TEGRA114_CLK_PLL_REF] = clk; pll_ref_freq = osc_freq / pll_ref_div; @@ -1110,19 +1074,19 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, 32768); clk_register_clkdev(clk, "clk_32k", NULL); - clks[clk_32k] = clk; + clks[TEGRA114_CLK_CLK_32K] = clk; /* clk_m_div2 */ clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", CLK_SET_RATE_PARENT, 1, 2); clk_register_clkdev(clk, "clk_m_div2", NULL); - clks[clk_m_div2] = clk; + clks[TEGRA114_CLK_CLK_M_DIV2] = clk; /* clk_m_div4 */ clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", CLK_SET_RATE_PARENT, 1, 4); clk_register_clkdev(clk, "clk_m_div4", NULL); - clks[clk_m_div4] = clk; + clks[TEGRA114_CLK_CLK_M_DIV4] = clk; } @@ -1279,7 +1243,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, pll_c_freq_table, NULL); clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; + clks[TEGRA114_CLK_PLL_C] = clk; /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", @@ -1289,7 +1253,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); clk_register_clkdev(clk, "pll_c_out1", NULL); - clks[pll_c_out1] = clk; + clks[TEGRA114_CLK_PLL_C_OUT1] = clk; } /* PLLC2 */ @@ -1298,7 +1262,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, &pll_c2_params, TEGRA_PLL_USE_LOCK, pll_cx_freq_table, NULL); clk_register_clkdev(clk, "pll_c2", NULL); - clks[pll_c2] = clk; + clks[TEGRA114_CLK_PLL_C2] = clk; /* PLLC3 */ _clip_vco_min(&pll_c3_params); @@ -1306,7 +1270,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, &pll_c3_params, TEGRA_PLL_USE_LOCK, pll_cx_freq_table, NULL); clk_register_clkdev(clk, "pll_c3", NULL); - clks[pll_c3] = clk; + clks[TEGRA114_CLK_PLL_C3] = clk; /* PLLP */ clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0, @@ -1314,7 +1278,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, pll_p_freq_table, NULL); clk_register_clkdev(clk, "pll_p", NULL); - clks[pll_p] = clk; + clks[TEGRA114_CLK_PLL_P] = clk; /* PLLP_OUT1 */ clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", @@ -1325,7 +1289,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); clk_register_clkdev(clk, "pll_p_out1", NULL); - clks[pll_p_out1] = clk; + clks[TEGRA114_CLK_PLL_P_OUT1] = clk; /* PLLP_OUT2 */ clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", @@ -1337,7 +1301,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); clk_register_clkdev(clk, "pll_p_out2", NULL); - clks[pll_p_out2] = clk; + clks[TEGRA114_CLK_PLL_P_OUT2] = clk; /* PLLP_OUT3 */ clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", @@ -1348,7 +1312,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); clk_register_clkdev(clk, "pll_p_out3", NULL); - clks[pll_p_out3] = clk; + clks[TEGRA114_CLK_PLL_P_OUT3] = clk; /* PLLP_OUT4 */ clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", @@ -1360,7 +1324,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); clk_register_clkdev(clk, "pll_p_out4", NULL); - clks[pll_p_out4] = clk; + clks[TEGRA114_CLK_PLL_P_OUT4] = clk; /* PLLM */ _clip_vco_min(&pll_m_params); @@ -1369,7 +1333,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, &pll_m_params, TEGRA_PLL_USE_LOCK, pll_m_freq_table, NULL); clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + clks[TEGRA114_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -1379,7 +1343,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); clk_register_clkdev(clk, "pll_m_out1", NULL); - clks[pll_m_out1] = clk; + clks[TEGRA114_CLK_PLL_M_OUT1] = clk; /* PLLM_UD */ clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", @@ -1393,14 +1357,14 @@ static void __init tegra114_pll_init(void __iomem *clk_base, pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL); clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; + clks[TEGRA114_CLK_PLL_X] = clk; } /* PLLX_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", CLK_SET_RATE_PARENT, 1, 2); clk_register_clkdev(clk, "pll_x_out0", NULL); - clks[pll_x_out0] = clk; + clks[TEGRA114_CLK_PLL_X_OUT0] = clk; /* PLLU */ val = readl(clk_base + pll_u_params.base_reg); @@ -1412,7 +1376,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, pll_u_freq_table, &pll_u_lock); clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + clks[TEGRA114_CLK_PLL_U] = clk; tegra114_utmi_param_configure(clk_base); @@ -1421,25 +1385,25 @@ static void __init tegra114_pll_init(void __iomem *clk_base, CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, 22, 0, &pll_u_lock); clk_register_clkdev(clk, "pll_u_480M", NULL); - clks[pll_u_480M] = clk; + clks[TEGRA114_CLK_PLL_U_480M] = clk; /* PLLU_60M */ clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", CLK_SET_RATE_PARENT, 1, 8); clk_register_clkdev(clk, "pll_u_60M", NULL); - clks[pll_u_60M] = clk; + clks[TEGRA114_CLK_PLL_U_60M] = clk; /* PLLU_48M */ clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", CLK_SET_RATE_PARENT, 1, 10); clk_register_clkdev(clk, "pll_u_48M", NULL); - clks[pll_u_48M] = clk; + clks[TEGRA114_CLK_PLL_U_48M] = clk; /* PLLU_12M */ clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", CLK_SET_RATE_PARENT, 1, 40); clk_register_clkdev(clk, "pll_u_12M", NULL); - clks[pll_u_12M] = clk; + clks[TEGRA114_CLK_PLL_U_12M] = clk; /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, @@ -1447,13 +1411,13 @@ static void __init tegra114_pll_init(void __iomem *clk_base, TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d_lock); clk_register_clkdev(clk, "pll_d", NULL); - clks[pll_d] = clk; + clks[TEGRA114_CLK_PLL_D] = clk; /* PLLD_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", CLK_SET_RATE_PARENT, 1, 2); clk_register_clkdev(clk, "pll_d_out0", NULL); - clks[pll_d_out0] = clk; + clks[TEGRA114_CLK_PLL_D_OUT0] = clk; /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0, @@ -1461,20 +1425,20 @@ static void __init tegra114_pll_init(void __iomem *clk_base, TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d2_lock); clk_register_clkdev(clk, "pll_d2", NULL); - clks[pll_d2] = clk; + clks[TEGRA114_CLK_PLL_D2] = clk; /* PLLD2_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", CLK_SET_RATE_PARENT, 1, 2); clk_register_clkdev(clk, "pll_d2_out0", NULL); - clks[pll_d2_out0] = clk; + clks[TEGRA114_CLK_PLL_D2_OUT0] = clk; /* PLLA */ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0, 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); clk_register_clkdev(clk, "pll_a", NULL); - clks[pll_a] = clk; + clks[TEGRA114_CLK_PLL_A] = clk; /* PLLA_OUT0 */ clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", @@ -1484,7 +1448,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); clk_register_clkdev(clk, "pll_a_out0", NULL); - clks[pll_a_out0] = clk; + clks[TEGRA114_CLK_PLL_A_OUT0] = clk; /* PLLRE */ _clip_vco_min(&pll_re_vco_params); @@ -1492,20 +1456,20 @@ static void __init tegra114_pll_init(void __iomem *clk_base, 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK, NULL, &pll_re_lock, pll_ref_freq); clk_register_clkdev(clk, "pll_re_vco", NULL); - clks[pll_re_vco] = clk; + clks[TEGRA114_CLK_PLL_RE_VCO] = clk; clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, clk_base + PLLRE_BASE, 16, 4, 0, pll_re_div_table, &pll_re_lock); clk_register_clkdev(clk, "pll_re_out", NULL); - clks[pll_re_out] = clk; + clks[TEGRA114_CLK_PLL_RE_OUT] = clk; /* PLLE */ clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_re_vco", clk_base, 0, 100000000, &pll_e_params, pll_e_freq_table, NULL); clk_register_clkdev(clk, "pll_e_out0", NULL); - clks[pll_e_out0] = clk; + clks[TEGRA114_CLK_PLL_E_OUT0] = clk; } static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", @@ -1532,37 +1496,37 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, 24000000); clk_register_clkdev(clk, "spdif_in_sync", NULL); - clks[spdif_in_sync] = clk; + clks[TEGRA114_CLK_SPDIF_IN_SYNC] = clk; /* i2s0_sync */ clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); clk_register_clkdev(clk, "i2s0_sync", NULL); - clks[i2s0_sync] = clk; + clks[TEGRA114_CLK_I2S0_SYNC] = clk; /* i2s1_sync */ clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); clk_register_clkdev(clk, "i2s1_sync", NULL); - clks[i2s1_sync] = clk; + clks[TEGRA114_CLK_I2S1_SYNC] = clk; /* i2s2_sync */ clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); clk_register_clkdev(clk, "i2s2_sync", NULL); - clks[i2s2_sync] = clk; + clks[TEGRA114_CLK_I2S2_SYNC] = clk; /* i2s3_sync */ clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); clk_register_clkdev(clk, "i2s3_sync", NULL); - clks[i2s3_sync] = clk; + clks[TEGRA114_CLK_I2S3_SYNC] = clk; /* i2s4_sync */ clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); clk_register_clkdev(clk, "i2s4_sync", NULL); - clks[i2s4_sync] = clk; + clks[TEGRA114_CLK_I2S4_SYNC] = clk; /* vimclk_sync */ clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); clk_register_clkdev(clk, "vimclk_sync", NULL); - clks[vimclk_sync] = clk; + clks[TEGRA114_CLK_VIMCLK_SYNC] = clk; /* audio0 */ clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, @@ -1570,12 +1534,12 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_NO_REPARENT, clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, NULL); - clks[audio0_mux] = clk; + clks[TEGRA114_CLK_AUDIO0_MUX] = clk; clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S0, 4, CLK_GATE_SET_TO_DISABLE, NULL); clk_register_clkdev(clk, "audio0", NULL); - clks[audio0] = clk; + clks[TEGRA114_CLK_AUDIO0] = clk; /* audio1 */ clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, @@ -1583,12 +1547,12 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_NO_REPARENT, clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, NULL); - clks[audio1_mux] = clk; + clks[TEGRA114_CLK_AUDIO1_MUX] = clk; clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S1, 4, CLK_GATE_SET_TO_DISABLE, NULL); clk_register_clkdev(clk, "audio1", NULL); - clks[audio1] = clk; + clks[TEGRA114_CLK_AUDIO1] = clk; /* audio2 */ clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, @@ -1596,12 +1560,12 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_NO_REPARENT, clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, NULL); - clks[audio2_mux] = clk; + clks[TEGRA114_CLK_AUDIO2_MUX] = clk; clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S2, 4, CLK_GATE_SET_TO_DISABLE, NULL); clk_register_clkdev(clk, "audio2", NULL); - clks[audio2] = clk; + clks[TEGRA114_CLK_AUDIO2] = clk; /* audio3 */ clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, @@ -1609,12 +1573,12 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_NO_REPARENT, clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, NULL); - clks[audio3_mux] = clk; + clks[TEGRA114_CLK_AUDIO3_MUX] = clk; clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S3, 4, CLK_GATE_SET_TO_DISABLE, NULL); clk_register_clkdev(clk, "audio3", NULL); - clks[audio3] = clk; + clks[TEGRA114_CLK_AUDIO3] = clk; /* audio4 */ clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, @@ -1622,12 +1586,12 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_NO_REPARENT, clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, NULL); - clks[audio4_mux] = clk; + clks[TEGRA114_CLK_AUDIO4_MUX] = clk; clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S4, 4, CLK_GATE_SET_TO_DISABLE, NULL); clk_register_clkdev(clk, "audio4", NULL); - clks[audio4] = clk; + clks[TEGRA114_CLK_AUDIO4] = clk; /* spdif */ clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, @@ -1635,12 +1599,12 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_NO_REPARENT, clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, NULL); - clks[spdif_mux] = clk; + clks[TEGRA114_CLK_SPDIF_MUX] = clk; clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, clk_base + AUDIO_SYNC_CLK_SPDIF, 4, CLK_GATE_SET_TO_DISABLE, NULL); clk_register_clkdev(clk, "spdif", NULL); - clks[spdif] = clk; + clks[TEGRA114_CLK_SPDIF] = clk; /* audio0_2x */ clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", @@ -1653,7 +1617,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, 113, &periph_v_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio0_2x", NULL); - clks[audio0_2x] = clk; + clks[TEGRA114_CLK_AUDIO0_2X] = clk; /* audio1_2x */ clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", @@ -1666,7 +1630,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, 114, &periph_v_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio1_2x", NULL); - clks[audio1_2x] = clk; + clks[TEGRA114_CLK_AUDIO1_2X] = clk; /* audio2_2x */ clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", @@ -1679,7 +1643,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, 115, &periph_v_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio2_2x", NULL); - clks[audio2_2x] = clk; + clks[TEGRA114_CLK_AUDIO2_2X] = clk; /* audio3_2x */ clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", @@ -1692,7 +1656,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, 116, &periph_v_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio3_2x", NULL); - clks[audio3_2x] = clk; + clks[TEGRA114_CLK_AUDIO3_2X] = clk; /* audio4_2x */ clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", @@ -1705,7 +1669,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, 117, &periph_v_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio4_2x", NULL); - clks[audio4_2x] = clk; + clks[TEGRA114_CLK_AUDIO4_2X] = clk; /* spdif_2x */ clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", @@ -1718,7 +1682,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, 118, &periph_v_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, "spdif_2x", NULL); - clks[spdif_2x] = clk; + clks[TEGRA114_CLK_SPDIF_2X] = clk; } static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) @@ -1731,12 +1695,12 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) CLK_SET_RATE_NO_REPARENT, pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, &clk_out_lock); - clks[clk_out_1_mux] = clk; + clks[TEGRA114_CLK_CLK_OUT_1_MUX] = clk; clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, &clk_out_lock); clk_register_clkdev(clk, "extern1", "clk_out_1"); - clks[clk_out_1] = clk; + clks[TEGRA114_CLK_CLK_OUT_1] = clk; /* clk_out_2 */ clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, @@ -1744,12 +1708,12 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) CLK_SET_RATE_NO_REPARENT, pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, &clk_out_lock); - clks[clk_out_2_mux] = clk; + clks[TEGRA114_CLK_CLK_OUT_2_MUX] = clk; clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, &clk_out_lock); clk_register_clkdev(clk, "extern2", "clk_out_2"); - clks[clk_out_2] = clk; + clks[TEGRA114_CLK_CLK_OUT_2] = clk; /* clk_out_3 */ clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, @@ -1757,12 +1721,12 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) CLK_SET_RATE_NO_REPARENT, pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, &clk_out_lock); - clks[clk_out_3_mux] = clk; + clks[TEGRA114_CLK_CLK_OUT_3_MUX] = clk; clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, &clk_out_lock); clk_register_clkdev(clk, "extern3", "clk_out_3"); - clks[clk_out_3] = clk; + clks[TEGRA114_CLK_CLK_OUT_3] = clk; /* blink */ /* clear the blink timer register to directly output clk_32k */ @@ -1774,7 +1738,7 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) pmc_base + PMC_CTRL, PMC_CTRL_BLINK_ENB, 0, NULL); clk_register_clkdev(clk, "blink", NULL); - clks[blink] = clk; + clks[TEGRA114_CLK_BLINK] = clk; } @@ -1801,7 +1765,7 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) clk_base + CCLKG_BURST_POLICY, 0, 4, 0, 0, NULL); clk_register_clkdev(clk, "cclk_g", NULL); - clks[cclk_g] = clk; + clks[TEGRA114_CLK_CCLK_G] = clk; /* CCLKLP */ clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, @@ -1810,7 +1774,7 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) clk_base + CCLKLP_BURST_POLICY, 0, 4, 8, 9, NULL); clk_register_clkdev(clk, "cclk_lp", NULL); - clks[cclk_lp] = clk; + clks[TEGRA114_CLK_CCLK_LP] = clk; /* SCLK */ clk = tegra_clk_register_super_mux("sclk", sclk_parents, @@ -1819,7 +1783,7 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); clk_register_clkdev(clk, "sclk", NULL); - clks[sclk] = clk; + clks[TEGRA114_CLK_SCLK] = clk; /* HCLK */ clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, @@ -1829,7 +1793,7 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); clk_register_clkdev(clk, "hclk", NULL); - clks[hclk] = clk; + clks[TEGRA114_CLK_HCLK] = clk; /* PCLK */ clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, @@ -1839,90 +1803,90 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); clk_register_clkdev(clk, "pclk", NULL); - clks[pclk] = clk; + clks[TEGRA114_CLK_PCLK] = clk; } static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), - TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, pwm), - TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, adx), - TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, amx), - TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda), - TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda2codec_2x), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), - TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), - TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), - TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), - TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), - TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), - TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, trace), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, i2c1), - TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, i2c2), - TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, i2c3), - TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, i2c4), - TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, i2c5), - TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), - TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), - TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), - TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), - TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, gr_3d), - TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr_2d), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), - TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), - TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_u_regs, TEGRA_PERIPH_WAR_1005168, msenc), - TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec), - TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), - TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), - TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, cilab), - TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, cilcd), - TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, cile), - TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, dsialp), - TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, dsiblp), - TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), - TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), - TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), - TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), - TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), - TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), - TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se), - TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_ref), - TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_soc), - TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm), - TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src), - TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src), - TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_fs_src), - TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_ss_src), - TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_dev_src), - TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, d_audio), - TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam0), - TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam1), - TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam2), + TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S0), + TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S1), + TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S2), + TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S3), + TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S4), + TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_OUT), + TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_IN), + TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_PWM), + TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_ADX), + TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_AMX), + TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA), + TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA2CODEC_2X), + TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), + TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), + TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), + TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), + TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), + TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), + TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), + TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), + TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_VFIR), + TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, TEGRA114_CLK_SDMMC1), + TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, TEGRA114_CLK_SDMMC2), + TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, TEGRA114_CLK_SDMMC3), + TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, TEGRA114_CLK_SDMMC4), + TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, TEGRA114_CLK_VDE), + TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_CSITE, CLK_IGNORE_UNUSED), + TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_LA), + TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TRACE), + TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_OWR), + TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, TEGRA114_CLK_NOR), + TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_MIPI), + TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA114_CLK_I2C1), + TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA114_CLK_I2C2), + TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA114_CLK_I2C3), + TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, TEGRA114_CLK_I2C4), + TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, TEGRA114_CLK_I2C5), + TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, TEGRA114_CLK_UARTA), + TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, TEGRA114_CLK_UARTB), + TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, TEGRA114_CLK_UARTC), + TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, TEGRA114_CLK_UARTD), + TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, TEGRA114_CLK_GR_3D), + TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, TEGRA114_CLK_GR_2D), + TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), + TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, TEGRA114_CLK_VI), + TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, TEGRA114_CLK_EPP), + TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_u_regs, TEGRA_PERIPH_WAR_1005168, TEGRA114_CLK_MSENC), + TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, TEGRA114_CLK_TSEC), + TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, TEGRA114_CLK_HOST1X), + TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, TEGRA114_CLK_HDMI), + TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, TEGRA114_CLK_CILAB), + TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, TEGRA114_CLK_CILCD), + TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, TEGRA114_CLK_CILE), + TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, TEGRA114_CLK_DSIALP), + TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, TEGRA114_CLK_DSIBLP), + TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TSENSOR), + TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, TEGRA114_CLK_ACTMON), + TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, TEGRA114_CLK_EXTERN1), + TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, TEGRA114_CLK_EXTERN2), + TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, TEGRA114_CLK_EXTERN3), + TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2CSLOW), + TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SE), + TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, TEGRA114_CLK_MSELECT, CLK_IGNORE_UNUSED), + TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_REF), + TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_SOC), + TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SOC_THERM), + TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_HOST_SRC), + TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FALCON_SRC), + TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FS_SRC), + TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_SS_SRC), + TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_DEV_SRC), + TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_D_AUDIO), + TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM0), + TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM1), + TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM2), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, &periph_l_regs, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, &periph_l_regs, 0, disp2), + TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, &periph_l_regs, 0, TEGRA114_CLK_DISP1), + TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, &periph_l_regs, 0, TEGRA114_CLK_DISP2), }; static __init void tegra114_periph_clk_init(void __iomem *clk_base) @@ -1936,7 +1900,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, 0, 34, &periph_h_regs, periph_clk_enb_refcnt); - clks[apbdma] = clk; + clks[TEGRA114_CLK_APBDMA] = clk; /* rtc */ clk = tegra_clk_register_periph_gate("rtc", "clk_32k", @@ -1945,7 +1909,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) 0, 4, &periph_l_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "rtc-tegra"); - clks[rtc] = clk; + clks[TEGRA114_CLK_RTC] = clk; /* kbc */ clk = tegra_clk_register_periph_gate("kbc", "clk_32k", @@ -1953,144 +1917,144 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) TEGRA_PERIPH_NO_RESET, clk_base, 0, 36, &periph_h_regs, periph_clk_enb_refcnt); - clks[kbc] = clk; + clks[TEGRA114_CLK_KBC] = clk; /* timer */ clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0, 5, &periph_l_regs, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "timer"); - clks[timer] = clk; + clks[TEGRA114_CLK_TIMER] = clk; /* kfuse */ clk = tegra_clk_register_periph_gate("kfuse", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 40, &periph_h_regs, periph_clk_enb_refcnt); - clks[kfuse] = clk; + clks[TEGRA114_CLK_KFUSE] = clk; /* fuse */ clk = tegra_clk_register_periph_gate("fuse", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 39, &periph_h_regs, periph_clk_enb_refcnt); - clks[fuse] = clk; + clks[TEGRA114_CLK_FUSE] = clk; /* fuse_burn */ clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 39, &periph_h_regs, periph_clk_enb_refcnt); - clks[fuse_burn] = clk; + clks[TEGRA114_CLK_FUSE_BURN] = clk; /* apbif */ clk = tegra_clk_register_periph_gate("apbif", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 107, &periph_v_regs, periph_clk_enb_refcnt); - clks[apbif] = clk; + clks[TEGRA114_CLK_APBIF] = clk; /* hda2hdmi */ clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 128, &periph_w_regs, periph_clk_enb_refcnt); - clks[hda2hdmi] = clk; + clks[TEGRA114_CLK_HDA2HDMI] = clk; /* vcp */ clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, 29, &periph_l_regs, periph_clk_enb_refcnt); - clks[vcp] = clk; + clks[TEGRA114_CLK_VCP] = clk; /* bsea */ clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, 0, 62, &periph_h_regs, periph_clk_enb_refcnt); - clks[bsea] = clk; + clks[TEGRA114_CLK_BSEA] = clk; /* bsev */ clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, 0, 63, &periph_h_regs, periph_clk_enb_refcnt); - clks[bsev] = clk; + clks[TEGRA114_CLK_BSEV] = clk; /* mipi-cal */ clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, 0, 56, &periph_h_regs, periph_clk_enb_refcnt); - clks[mipi_cal] = clk; + clks[TEGRA114_CLK_MIPI_CAL] = clk; /* usbd */ clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, 22, &periph_l_regs, periph_clk_enb_refcnt); - clks[usbd] = clk; + clks[TEGRA114_CLK_USBD] = clk; /* usb2 */ clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, 58, &periph_h_regs, periph_clk_enb_refcnt); - clks[usb2] = clk; + clks[TEGRA114_CLK_USB2] = clk; /* usb3 */ clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, 59, &periph_h_regs, periph_clk_enb_refcnt); - clks[usb3] = clk; + clks[TEGRA114_CLK_USB3] = clk; /* csi */ clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, 0, 52, &periph_h_regs, periph_clk_enb_refcnt); - clks[csi] = clk; + clks[TEGRA114_CLK_CSI] = clk; /* isp */ clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, &periph_l_regs, periph_clk_enb_refcnt); - clks[isp] = clk; + clks[TEGRA114_CLK_ISP] = clk; /* csus */ clk = tegra_clk_register_periph_gate("csus", "clk_m", TEGRA_PERIPH_NO_RESET, clk_base, 0, 92, &periph_u_regs, periph_clk_enb_refcnt); - clks[csus] = clk; + clks[TEGRA114_CLK_CSUS] = clk; /* dds */ clk = tegra_clk_register_periph_gate("dds", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 150, &periph_w_regs, periph_clk_enb_refcnt); - clks[dds] = clk; + clks[TEGRA114_CLK_DDS] = clk; /* dp2 */ clk = tegra_clk_register_periph_gate("dp2", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 152, &periph_w_regs, periph_clk_enb_refcnt); - clks[dp2] = clk; + clks[TEGRA114_CLK_DP2] = clk; /* dtv */ clk = tegra_clk_register_periph_gate("dtv", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 79, &periph_u_regs, periph_clk_enb_refcnt); - clks[dtv] = clk; + clks[TEGRA114_CLK_DTV] = clk; /* dsia */ clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, ARRAY_SIZE(mux_plld_out0_plld2_out0), CLK_SET_RATE_NO_REPARENT, clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); - clks[dsia_mux] = clk; + clks[TEGRA114_CLK_DSIA_MUX] = clk; clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, 0, 48, &periph_h_regs, periph_clk_enb_refcnt); - clks[dsia] = clk; + clks[TEGRA114_CLK_DSIA] = clk; /* dsib */ clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, ARRAY_SIZE(mux_plld_out0_plld2_out0), CLK_SET_RATE_NO_REPARENT, clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); - clks[dsib_mux] = clk; + clks[TEGRA114_CLK_DSIB_MUX] = clk; clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, 0, 82, &periph_u_regs, periph_clk_enb_refcnt); - clks[dsib] = clk; + clks[TEGRA114_CLK_DSIB] = clk; /* xusb_hs_src */ val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); @@ -2099,25 +2063,25 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, 1, 1); - clks[xusb_hs_src] = clk; + clks[TEGRA114_CLK_XUSB_HS_SRC] = clk; /* xusb_host */ clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, clk_base, 0, 89, &periph_u_regs, periph_clk_enb_refcnt); - clks[xusb_host] = clk; + clks[TEGRA114_CLK_XUSB_HOST] = clk; /* xusb_ss */ clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, clk_base, 0, 156, &periph_w_regs, periph_clk_enb_refcnt); - clks[xusb_host] = clk; + clks[TEGRA114_CLK_XUSB_HOST] = clk; /* xusb_dev */ clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, clk_base, 0, 95, &periph_u_regs, periph_clk_enb_refcnt); - clks[xusb_dev] = clk; + clks[TEGRA114_CLK_XUSB_DEV] = clk; /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, @@ -2128,7 +2092,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, CLK_IGNORE_UNUSED, 57, &periph_h_regs, periph_clk_enb_refcnt); - clks[emc] = clk; + clks[TEGRA114_CLK_EMC] = clk; for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; @@ -2207,28 +2171,29 @@ static const struct of_device_id pmc_match[] __initconst = { * breaks */ static struct tegra_clk_init_table init_table[] __initdata = { - {uarta, pll_p, 408000000, 0}, - {uartb, pll_p, 408000000, 0}, - {uartc, pll_p, 408000000, 0}, - {uartd, pll_p, 408000000, 0}, - {pll_a, clk_max, 564480000, 1}, - {pll_a_out0, clk_max, 11289600, 1}, - {extern1, pll_a_out0, 0, 1}, - {clk_out_1_mux, extern1, 0, 1}, - {clk_out_1, clk_max, 0, 1}, - {i2s0, pll_a_out0, 11289600, 0}, - {i2s1, pll_a_out0, 11289600, 0}, - {i2s2, pll_a_out0, 11289600, 0}, - {i2s3, pll_a_out0, 11289600, 0}, - {i2s4, pll_a_out0, 11289600, 0}, - {dfll_soc, pll_p, 51000000, 1}, - {dfll_ref, pll_p, 51000000, 1}, - {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ + {TEGRA114_CLK_UARTA, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_UARTB, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_UARTC, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_UARTD, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 1}, + {TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 1}, + {TEGRA114_CLK_EXTERN1, TEGRA114_CLK_PLL_A_OUT0, 0, 1}, + {TEGRA114_CLK_CLK_OUT_1_MUX, TEGRA114_CLK_EXTERN1, 0, 1}, + {TEGRA114_CLK_CLK_OUT_1, TEGRA114_CLK_CLK_MAX, 0, 1}, + {TEGRA114_CLK_I2S0, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S1, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S3, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S4, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, + {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, + /* This MUST be the last entry. */ + {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, }; static void __init tegra114_clock_apply_init_table(void) { - tegra_init_from_table(init_table, clks, clk_max); + tegra_init_from_table(init_table, clks, TEGRA114_CLK_CLK_MAX); } -- cgit v1.2.3 From 2b54ffc2693b917743de6f34815b63638ad3853f Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Thu, 8 Aug 2013 13:55:27 +0800 Subject: clk: tegra: Correct sbc mux width & parent Tegra114 sbc1-sbc6 have more possible parent clocks than Tegra30. So correct the parents and mux width for them. Signed-off-by: Mark Zhang Acked-by: Stephen Warren Acked-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra114.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 15d94d0d44d9..519f9556d0c9 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1819,12 +1819,12 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_AMX), TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA), TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA2CODEC_2X), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), - TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), - TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), + TEGRA_INIT_DATA_MUX8("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), + TEGRA_INIT_DATA_MUX8("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), + TEGRA_INIT_DATA_MUX8("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), + TEGRA_INIT_DATA_MUX8("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), + TEGRA_INIT_DATA_MUX8("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), + TEGRA_INIT_DATA_MUX8("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_VFIR), -- cgit v1.2.3 From d17cb95fa0b8676a38c0d07e2da26885d4ff8187 Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Wed, 7 Aug 2013 19:25:07 +0800 Subject: clk: tegra: Fix vde/2d/3d clock src offset In Tegra114, vde/gr_2d/gr_3d have 3 bits for clock source selection. So change the clock init macro for these clocks from "TEGRA_INIT_DATA_INT" to "TEGRA_INIT_DATA_INT8". Besides, no one uses "TEGRA_INIT_DATA_INT" after this change, so remove this macro. Signed-off-by: Mark Zhang Acked-by: Stephen Warren Acked-By: Peter De Schrijver --- drivers/clk/tegra/clk-tegra114.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 519f9556d0c9..6d6491c7b479 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -809,13 +809,6 @@ static unsigned long tegra114_input_freq[] = { periph_clk_enb_refcnt, _gate_flags, _clk_id, \ _parents##_idx, 0) -#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, 0) - #define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _regs, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ @@ -1832,7 +1825,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, TEGRA114_CLK_SDMMC2), TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, TEGRA114_CLK_SDMMC3), TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, TEGRA114_CLK_SDMMC4), - TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, TEGRA114_CLK_VDE), + TEGRA_INIT_DATA_INT8("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, TEGRA114_CLK_VDE), TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_CSITE, CLK_IGNORE_UNUSED), TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_LA), TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TRACE), @@ -1848,8 +1841,8 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, TEGRA114_CLK_UARTB), TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, TEGRA114_CLK_UARTC), TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, TEGRA114_CLK_UARTD), - TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, TEGRA114_CLK_GR_3D), - TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, TEGRA114_CLK_GR_2D), + TEGRA_INIT_DATA_INT8("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, TEGRA114_CLK_GR_3D), + TEGRA_INIT_DATA_INT8("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, TEGRA114_CLK_GR_2D), TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, TEGRA114_CLK_VI), TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, TEGRA114_CLK_EPP), -- cgit v1.2.3 From fc20eeff6c03fcdbb2b5ac21472778b573850e77 Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Wed, 7 Aug 2013 19:25:08 +0800 Subject: clk: tegra: Set the clock parent of gr2d/gr3d to pll_c2 pll_m will be the parent of gr2d/gr3d if we don't do this. And because pll_m runs at a high rate so gr2d/gr3d will be unstable. So change the parent of them to pll_c2. Signed-off-by: Mark Zhang Acked-By: Peter De Schrijver --- drivers/clk/tegra/clk-tegra114.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 6d6491c7b479..76611289b8e6 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -2180,6 +2180,9 @@ static struct tegra_clk_init_table init_table[] __initdata = { {TEGRA114_CLK_I2S4, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, + {TEGRA114_CLK_GR_2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, + {TEGRA114_CLK_GR_3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, + /* This MUST be the last entry. */ {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, }; -- cgit v1.2.3 From 2fea6cd303c0d0cd9067da31d873b6a6d5bd75e7 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Thu, 21 Nov 2013 18:03:07 +0100 Subject: can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value This patch fixes the issue that the sja1000_interrupt() function may have returned IRQ_NONE without processing the optional pre_irq() and post_irq() function before. Further the irq processing counter 'n' is moved to the end of the while statement to return correct IRQ_[NONE|HANDLED] values at error conditions. Reported-by: Wolfgang Grandegger Acked-by: Wolfgang Grandegger Signed-off-by: Oliver Hartkopp Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sja1000/sja1000.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 7164a999f50f..f17c3018b7c7 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -494,20 +494,20 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) uint8_t isrc, status; int n = 0; - /* Shared interrupts and IRQ off? */ - if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF) - return IRQ_NONE; - if (priv->pre_irq) priv->pre_irq(priv); + /* Shared interrupts and IRQ off? */ + if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF) + goto out; + while ((isrc = priv->read_reg(priv, SJA1000_IR)) && (n < SJA1000_MAX_IRQ)) { - n++; + status = priv->read_reg(priv, SJA1000_SR); /* check for absent controller due to hw unplug */ if (status == 0xFF && sja1000_is_absent(priv)) - return IRQ_NONE; + goto out; if (isrc & IRQ_WUI) netdev_warn(dev, "wakeup interrupt\n"); @@ -535,7 +535,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) status = priv->read_reg(priv, SJA1000_SR); /* check for absent controller */ if (status == 0xFF && sja1000_is_absent(priv)) - return IRQ_NONE; + goto out; } } if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) { @@ -543,8 +543,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) if (sja1000_err(dev, isrc, status)) break; } + n++; } - +out: if (priv->post_irq) priv->post_irq(priv); -- cgit v1.2.3 From e35d46adc49b469fd92bdb64fea8af93640e6651 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 24 Nov 2013 23:31:24 +0100 Subject: can: c_can: don't call pm_runtime_get_sync() from interrupt context The c_can driver contians a callpath (c_can_poll -> c_can_state_change -> c_can_get_berr_counter) which may call pm_runtime_get_sync() from the IRQ handler, which is not allowed and results in "BUG: scheduling while atomic". This problem is fixed by introducing __c_can_get_berr_counter, which will not call pm_runtime_get_sync(). Reported-by: Andrew Glen Tested-by: Andrew Glen Signed-off-by: Andrew Glen Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index e3fc07cf2f62..e59c42b446a9 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -712,22 +712,31 @@ static int c_can_set_mode(struct net_device *dev, enum can_mode mode) return 0; } -static int c_can_get_berr_counter(const struct net_device *dev, - struct can_berr_counter *bec) +static int __c_can_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) { unsigned int reg_err_counter; struct c_can_priv *priv = netdev_priv(dev); - c_can_pm_runtime_get_sync(priv); - reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> ERR_CNT_REC_SHIFT; bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; + return 0; +} + +static int c_can_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct c_can_priv *priv = netdev_priv(dev); + int err; + + c_can_pm_runtime_get_sync(priv); + err = __c_can_get_berr_counter(dev, bec); c_can_pm_runtime_put_sync(priv); - return 0; + return err; } /* @@ -872,7 +881,7 @@ static int c_can_handle_state_change(struct net_device *dev, if (unlikely(!skb)) return 0; - c_can_get_berr_counter(dev, &bec); + __c_can_get_berr_counter(dev, &bec); reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> ERR_CNT_RP_SHIFT; -- cgit v1.2.3 From 7ee330c7b3b738847bf297912b371bbcec3bc994 Mon Sep 17 00:00:00 2001 From: Holger Bechtold Date: Mon, 25 Nov 2013 15:48:19 +0100 Subject: can: c_can: fix calculation of transmitted bytes on tx complete The number of bytes transmitted was not updated correctly, if several CAN messages (with different length) were transmitted in one 'bunch'. Thus programs like 'ifconfig' showed wrong transmit byte counts. Reason was, that the message object whose DLC is to be read was not necessarily the active one at the time when priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, 0)) & IF_MCONT_DLC_MASK; was executed. Signed-off-by: Holger Bechtold Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index e59c42b446a9..77061eebb034 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -763,6 +763,7 @@ static void c_can_do_tx(struct net_device *dev) if (!(val & (1 << (msg_obj_no - 1)))) { can_get_echo_skb(dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); + c_can_object_get(dev, 0, msg_obj_no, IF_COMM_ALL); stats->tx_bytes += priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, 0)) & IF_MCONT_DLC_MASK; -- cgit v1.2.3 From c37dd677988ca50bc8bc60ab5ab053720583c168 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 11 Nov 2013 20:41:38 +0200 Subject: ARM: OMAPFB: panel-sony-acx565akm: fix bad unlock balance When booting Nokia N900 smartphone with v3.12 + omap2plus_defconfig (LOCKDEP enabled) and CONFIG_DISPLAY_PANEL_SONY_ACX565AKM enabled, the following BUG is seen during the boot: [ 7.302154] ===================================== [ 7.307128] [ BUG: bad unlock balance detected! ] [ 7.312103] 3.12.0-los.git-2093492-00120-g5e01dc7 #3 Not tainted [ 7.318450] ------------------------------------- [ 7.323425] kworker/u2:1/12 is trying to release lock (&ddata->mutex) at: [ 7.330657] [] acx565akm_enable+0x12c/0x18c [ 7.335998] but there are no more locks to release! Fix by removing double unlock and handling the locking completely inside acx565akm_panel_power_on() when doing the power on. Reported-by: Eduardo Valentin Signed-off-by: Aaro Koskinen Cc: stable@vger.kernel.org Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays-new/panel-sony-acx565akm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/omap2/displays-new/panel-sony-acx565akm.c index e6d56f714ae4..d94f35dbd536 100644 --- a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c +++ b/drivers/video/omap2/displays-new/panel-sony-acx565akm.c @@ -526,6 +526,8 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev) struct omap_dss_device *in = ddata->in; int r; + mutex_lock(&ddata->mutex); + dev_dbg(&ddata->spi->dev, "%s\n", __func__); in->ops.sdi->set_timings(in, &ddata->videomode); @@ -614,10 +616,7 @@ static int acx565akm_enable(struct omap_dss_device *dssdev) if (omapdss_device_is_enabled(dssdev)) return 0; - mutex_lock(&ddata->mutex); r = acx565akm_panel_power_on(dssdev); - mutex_unlock(&ddata->mutex); - if (r) return r; -- cgit v1.2.3 From 6c5dc7f8afbd2f480ebe9ff6919c6420fcf1abd6 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Mon, 18 Nov 2013 15:20:01 +1100 Subject: crypto: caam - Add missing Job Ring include linuxnext currently doesn't compile with the powerpc mpc85xx_defconfig giving: drivers/crypto/caam/jr.c: In function 'caam_jr_probe': drivers/crypto/caam/jr.c:468:2: error: implicit declaration of function 'of_iomap' [-Werror=implicit-function-declaration] In: commit 313ea293e9c4d1eabcaddd2c0800f083b03c2a2e Author: Ruchika Gupta crypto: caam - Add Platform driver for Job Ring We added a reference to of_iomap but did add the necessary include file. The below adds this include. Signed-off-by: Michael Neuling Acked-by: Ruchika Gupta Signed-off-by: Herbert Xu --- drivers/crypto/caam/jr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index d23356d20e1c..1d80bd3636c5 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -6,6 +6,7 @@ */ #include +#include #include "compat.h" #include "regs.h" -- cgit v1.2.3 From 1a3e5173f5e72cbf7f0c8927b33082e361c16d72 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 25 Nov 2013 22:15:20 +0100 Subject: can: flexcan: use correct clock as base for bit rate calculation The flexcan IP core uses the peripheral clock ("per") as basic clock for the bit timing calculation. However the driver uses the the wrong clock ("ipg"). This leads to wrong bit rates if the rates on both clock are different. This patch fixes the problem by using the correct clock for the bit rate calculation. Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index ae08cf129ebb..aaed97bee471 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1020,13 +1020,13 @@ static int flexcan_probe(struct platform_device *pdev) dev_err(&pdev->dev, "no ipg clock defined\n"); return PTR_ERR(clk_ipg); } - clock_freq = clk_get_rate(clk_ipg); clk_per = devm_clk_get(&pdev->dev, "per"); if (IS_ERR(clk_per)) { dev_err(&pdev->dev, "no per clock defined\n"); return PTR_ERR(clk_per); } + clock_freq = clk_get_rate(clk_per); } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.3 From 2ab68ec927310dc488f3403bb48f9e4ad00a9491 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 19 Nov 2013 14:25:36 -0500 Subject: video: kyro: fix incorrect sizes when copying to userspace kyro would copy u32s and specify sizeof(unsigned long) as the size to copy. This would copy more data than intended and cause memory corruption and might leak kernel memory. Signed-off-by: Sasha Levin Signed-off-by: Tomi Valkeinen --- drivers/video/kyro/fbdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c index 50c857477e4f..65041e15fd59 100644 --- a/drivers/video/kyro/fbdev.c +++ b/drivers/video/kyro/fbdev.c @@ -624,15 +624,15 @@ static int kyrofb_ioctl(struct fb_info *info, return -EINVAL; } case KYRO_IOCTL_UVSTRIDE: - if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long))) + if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(deviceInfo.ulOverlayUVStride))) return -EFAULT; break; case KYRO_IOCTL_STRIDE: - if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long))) + if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(deviceInfo.ulOverlayStride))) return -EFAULT; break; case KYRO_IOCTL_OVERLAY_OFFSET: - if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long))) + if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(deviceInfo.ulOverlayOffset))) return -EFAULT; break; } -- cgit v1.2.3 From 974dbcfcca1ee88279e274051e1719b4980ebdb3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Nov 2013 09:57:27 +0100 Subject: fbdev: sh_mobile_meram: Fix defined but not used compiler warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If both CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME are not set: drivers/video/sh_mobile_meram.c:573: warning: ‘sh_mobile_meram_suspend’ defined but not used drivers/video/sh_mobile_meram.c:597: warning: ‘sh_mobile_meram_resume’ defined but not used Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Tomi Valkeinen --- drivers/video/sh_mobile_meram.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index e0f098562a74..a297de5cc859 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -569,6 +569,7 @@ EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_update); * Power management */ +#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME) static int sh_mobile_meram_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -611,6 +612,7 @@ static int sh_mobile_meram_resume(struct device *dev) meram_write_reg(priv->base, common_regs[i], priv->regs[i]); return 0; } +#endif /* CONFIG_PM_SLEEP || CONFIG_PM_RUNTIME */ static UNIVERSAL_DEV_PM_OPS(sh_mobile_meram_dev_pm_ops, sh_mobile_meram_suspend, -- cgit v1.2.3 From 427bfe07e6744c058ce6fc4aa187cda96b635539 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Thu, 14 Nov 2013 14:29:52 -0700 Subject: xen-blkfront: Silence pfn maybe-uninitialized warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pfn cannot actually be used unless (!info->feature_persistent), nor is pfn accessed in get_grant() unless (!info->feature_persistent), but silence this warning anyway. gcc-4.8 drivers/block/xen-blkfront.c: In function 'do_blkif_request': drivers/block/xen-blkfront.c:508:20: warning: 'pfn' may be used uninitialized in this function [-Wmaybe-uninitialized] gnt_list_entry = get_grant(&gref_head, pfn, info); ^ drivers/block/xen-blkfront.c:492:19: note: 'pfn' was declared here unsigned long pfn; Cc: Konrad Rzeszutek Wilk Cc: Boris Ostrovsky Cc: David Vrabel Signed-off-by: Tim Gardner Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Roger Pau Monné --- drivers/block/xen-blkfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 432db1b59b00..5f926de61950 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -489,7 +489,7 @@ static int blkif_queue_request(struct request *req) if ((ring_req->operation == BLKIF_OP_INDIRECT) && (i % SEGS_PER_INDIRECT_FRAME == 0)) { - unsigned long pfn; + unsigned long uninitialized_var(pfn); if (segments) kunmap_atomic(segments); -- cgit v1.2.3 From 2f089cb89d2f47702c31bd584c12badc88bbe17c Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 9 Nov 2013 13:36:09 -0200 Subject: block: xen-blkfront: Fix possible NULL ptr dereference In the blkif_release function the bdget_disk() call might returns a NULL ptr which might be dereferenced on bdev->bd_openers checking Signed-off-by: Felipe Pena Signed-off-by: Konrad Rzeszutek Wilk [v2: Added WARN per Roger's suggestion] --- drivers/block/xen-blkfront.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 5f926de61950..c4a4c9006288 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -2011,6 +2011,10 @@ static void blkif_release(struct gendisk *disk, fmode_t mode) bdev = bdget_disk(disk, 0); + if (!bdev) { + WARN(1, "Block device %s yanked out from us!\n", disk->disk_name); + goto out_mutex; + } if (bdev->bd_openers) goto out; @@ -2041,6 +2045,7 @@ static void blkif_release(struct gendisk *disk, fmode_t mode) out: bdput(bdev); +out_mutex: mutex_unlock(&blkfront_mutex); } -- cgit v1.2.3 From 252d0d2bb07119296e215de7dc9afa8d12746b80 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Tue, 26 Nov 2013 13:48:09 +0200 Subject: clk: tegra: add TEGRA_DIVIDER_ROUND_UP for periph clks Perform upwards rounding when calculating dividers for periph clks on Tegra30 and Tegra114. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra114.c | 53 ++++++++++++++++++++++------------------ drivers/clk/tegra/clk-tegra30.c | 19 +++++++------- 2 files changed, 39 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 76611289b8e6..e3904923005b 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -791,50 +791,53 @@ static unsigned long tegra114_input_freq[] = { #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, 0) + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ + _regs, _clk_num, periph_clk_enb_refcnt, _gate_flags,\ + _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _regs, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, flags) + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + _regs, _clk_num, periph_clk_enb_refcnt, _gate_flags,\ + _clk_id, _parents##_idx, flags) #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 29, MASK(3), 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, 0) + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + _regs, _clk_num, periph_clk_enb_refcnt, _gate_flags,\ + _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _regs, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, flags) + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ + TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + periph_clk_enb_refcnt, _gate_flags, _clk_id, \ + _parents##_idx, flags) #define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, 0) + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ + TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + periph_clk_enb_refcnt, _gate_flags, _clk_id, \ + _parents##_idx, 0) #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _regs, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs,\ - _clk_num, periph_clk_enb_refcnt, 0, _clk_id, \ - _parents##_idx, 0) + 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ + TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _regs, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 16, 0, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) + 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ + _regs, _clk_num, periph_clk_enb_refcnt, 0, _clk_id,\ + _parents##_idx, 0) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ _mux_shift, _mux_mask, _clk_num, _regs, \ @@ -847,14 +850,16 @@ static unsigned long tegra114_input_freq[] = { #define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ - 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, 0) + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ + TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + periph_clk_enb_refcnt, _gate_flags, _clk_id, \ + _parents##_idx, 0) #define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ - _offset, 16, 0xE01F, 0, 0, 8, 1, 0, _regs, _clk_num, \ + _offset, 16, 0xE01F, 0, 0, 8, 1, \ + TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ periph_clk_enb_refcnt, _gate_flags , _clk_id, \ mux_d_audio_clk_idx, 0) diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index dbe7c8003c5c..147f5b9fed11 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -282,8 +282,8 @@ static DEFINE_SPINLOCK(sysrate_lock); #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id) + 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, _regs, \ + _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _regs, _gate_flags, _clk_id) \ @@ -295,21 +295,22 @@ static DEFINE_SPINLOCK(sysrate_lock); #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 29, 3, 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id) + 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, _regs,\ + _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _regs, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id) + 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ + TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + periph_clk_enb_refcnt, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _regs, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs, \ - _clk_num, periph_clk_enb_refcnt, 0, _clk_id) + 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ + TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + periph_clk_enb_refcnt, 0, _clk_id) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ _mux_shift, _mux_width, _clk_num, _regs, \ -- cgit v1.2.3 From 897e1dde1ec1571a28545594633624927fa0a76e Mon Sep 17 00:00:00 2001 From: Andrew Chew Date: Wed, 7 Aug 2013 19:25:09 +0800 Subject: clk: tegra: Set the clk parent of host1x to pll_p The power-on default parent for this clock is pll_m, which turns out to be wrong. Previously, bootloader reparented this clock. We'll do it in the kernel as well, so that there's one less thing that we depend on bootloader to initialize. Signed-off-by: Andrew Chew Signed-off-by: Mark Zhang --- drivers/clk/tegra/clk-tegra114.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index e3904923005b..9b8c938477de 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -2183,6 +2183,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { {TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, {TEGRA114_CLK_I2S3, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, {TEGRA114_CLK_I2S4, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_HOST1X, TEGRA114_CLK_PLL_P, 136000000, 0}, {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, {TEGRA114_CLK_GR_2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, -- cgit v1.2.3 From 642fb0cf517173948684122403d73513c8c8b033 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Thu, 26 Sep 2013 18:30:01 +0300 Subject: clk: tegra: PLLE spread spectrum control Add spread spectrum control for PLLE in Tegra114. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-pll.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 197074a57754..c9d1e5c68dbc 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -77,7 +77,23 @@ #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) #define PLLE_SS_CTRL 0x68 -#define PLLE_SS_DISABLE (7 << 10) +#define PLLE_SS_CNTL_BYPASS_SS BIT(10) +#define PLLE_SS_CNTL_INTERP_RESET BIT(11) +#define PLLE_SS_CNTL_SSC_BYP BIT(12) +#define PLLE_SS_CNTL_CENTER BIT(14) +#define PLLE_SS_CNTL_INVERT BIT(15) +#define PLLE_SS_DISABLE (PLLE_SS_CNTL_BYPASS_SS | PLLE_SS_CNTL_INTERP_RESET |\ + PLLE_SS_CNTL_SSC_BYP) +#define PLLE_SS_MAX_MASK 0x1ff +#define PLLE_SS_MAX_VAL 0x25 +#define PLLE_SS_INC_MASK (0xff << 16) +#define PLLE_SS_INC_VAL (0x1 << 16) +#define PLLE_SS_INCINTRV_MASK (0x3f << 24) +#define PLLE_SS_INCINTRV_VAL (0x20 << 24) +#define PLLE_SS_COEFFICIENTS_MASK \ + (PLLE_SS_MAX_MASK | PLLE_SS_INC_MASK | PLLE_SS_INCINTRV_MASK) +#define PLLE_SS_COEFFICIENTS_VAL \ + (PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL) #define PLLE_AUX_PLLP_SEL BIT(2) #define PLLE_AUX_ENABLE_SWCTL BIT(4) @@ -1217,6 +1233,18 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) if (ret < 0) goto out; + val = pll_readl(PLLE_SS_CTRL, pll); + val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT); + val &= ~PLLE_SS_COEFFICIENTS_MASK; + val |= PLLE_SS_COEFFICIENTS_VAL; + pll_writel(val, PLLE_SS_CTRL, pll); + val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS); + pll_writel(val, PLLE_SS_CTRL, pll); + udelay(1); + val &= ~PLLE_SS_CNTL_INTERP_RESET; + pll_writel(val, PLLE_SS_CTRL, pll); + udelay(1); + /* TODO: enable hw control of xusb brick pll */ out: -- cgit v1.2.3 From f67a8d21e63876a79f9f94b734049e789d594c7b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 2 Oct 2013 23:12:40 +0200 Subject: clk: tegra114: Rename gr_2d/gr_3d to gr2d/gr3d These clocks were named gr2d and gr3d on Tegra20 and Tegra30, so use the same names on Tegra114 for consistency. Signed-off-by: Thierry Reding Acked-by: Stephen Warren --- drivers/clk/tegra/clk-tegra114.c | 8 ++++---- include/dt-bindings/clock/tegra114-car.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9b8c938477de..2471742d68de 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1846,8 +1846,8 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, TEGRA114_CLK_UARTB), TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, TEGRA114_CLK_UARTC), TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, TEGRA114_CLK_UARTD), - TEGRA_INIT_DATA_INT8("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, TEGRA114_CLK_GR_3D), - TEGRA_INIT_DATA_INT8("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, TEGRA114_CLK_GR_2D), + TEGRA_INIT_DATA_INT8("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, TEGRA114_CLK_GR3D), + TEGRA_INIT_DATA_INT8("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, TEGRA114_CLK_GR2D), TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, TEGRA114_CLK_VI), TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, TEGRA114_CLK_EPP), @@ -2186,8 +2186,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { {TEGRA114_CLK_HOST1X, TEGRA114_CLK_PLL_P, 136000000, 0}, {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, - {TEGRA114_CLK_GR_2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, - {TEGRA114_CLK_GR_3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, + {TEGRA114_CLK_GR2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, + {TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, /* This MUST be the last entry. */ {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, diff --git a/include/dt-bindings/clock/tegra114-car.h b/include/dt-bindings/clock/tegra114-car.h index 5d4b90a2c023..6d0d8d8ef31e 100644 --- a/include/dt-bindings/clock/tegra114-car.h +++ b/include/dt-bindings/clock/tegra114-car.h @@ -37,10 +37,10 @@ #define TEGRA114_CLK_I2S2 18 #define TEGRA114_CLK_EPP 19 /* 20 (register bit affects vi and vi_sensor) */ -#define TEGRA114_CLK_GR_2D 21 +#define TEGRA114_CLK_GR2D 21 #define TEGRA114_CLK_USBD 22 #define TEGRA114_CLK_ISP 23 -#define TEGRA114_CLK_GR_3D 24 +#define TEGRA114_CLK_GR3D 24 /* 25 */ #define TEGRA114_CLK_DISP2 26 #define TEGRA114_CLK_DISP1 27 -- cgit v1.2.3 From 00c674e42c278e7af7b39b6c72dbbaa5e7ebd96c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 18 Nov 2013 16:11:35 +0100 Subject: clk: tegra: Fix clock rate computation The PLL output frequency is multiplied during the P-divider computation, so it needs to be divided by the P-divider again before returning. This fixes an issue where clk_round_rate() would return the multiplied frequency instead of the real one after the P-divider. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index c9d1e5c68dbc..25734348242f 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -411,6 +411,8 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, return -EINVAL; } + cfg->output_rate >>= p_div; + if (pll->params->pdiv_tohw) { ret = _p_div_to_hw(hw, 1 << p_div); if (ret < 0) -- cgit v1.2.3 From d5ff89a82a6d272d210db68a9487877682c94a24 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Thu, 22 Aug 2013 18:44:06 +0300 Subject: clk: tegra: simplify periph clock data This patch determines the register bank for clock enable/disable and reset based on the clock ID instead of hardcoding it in the tables describing the clocks. This results in less data to be maintained in the tables, making the code easier to understand. The full benefit of the change will be realized once also other clocktypes will be table based. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-periph-gate.c | 8 +- drivers/clk/tegra/clk-periph.c | 6 + drivers/clk/tegra/clk-tegra114.c | 376 ++++++++++++++---------------------- drivers/clk/tegra/clk-tegra20.c | 220 ++++++++------------- drivers/clk/tegra/clk-tegra30.c | 317 +++++++++++------------------- drivers/clk/tegra/clk.c | 104 ++++++++++ drivers/clk/tegra/clk.h | 17 +- 7 files changed, 464 insertions(+), 584 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index bafee9895a24..f38f33e3c65d 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -151,12 +151,16 @@ const struct clk_ops tegra_clk_periph_gate_ops = { struct clk *tegra_clk_register_periph_gate(const char *name, const char *parent_name, u8 gate_flags, void __iomem *clk_base, - unsigned long flags, int clk_num, - struct tegra_clk_periph_regs *pregs, int *enable_refcnt) + unsigned long flags, int clk_num, int *enable_refcnt) { struct tegra_clk_periph_gate *gate; struct clk *clk; struct clk_init_data init; + struct tegra_clk_periph_regs *pregs; + + pregs = get_reg_bank(clk_num); + if (!pregs) + return ERR_PTR(-EINVAL); gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) { diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index b2309d37a963..735b0243261c 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -178,6 +178,7 @@ static struct clk *_tegra_clk_register_periph(const char *name, { struct clk *clk; struct clk_init_data init; + struct tegra_clk_periph_regs *bank; init.name = name; init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; @@ -185,12 +186,17 @@ static struct clk *_tegra_clk_register_periph(const char *name, init.parent_names = parent_names; init.num_parents = num_parents; + bank = get_reg_bank(periph->gate.clk_num); + if (!bank) + return ERR_PTR(-EINVAL); + /* Data in .init is copied by clk_register(), so stack variable OK */ periph->hw.init = &init; periph->magic = TEGRA_CLK_PERIPH_MAGIC; periph->mux.reg = clk_base + offset; periph->divider.reg = div ? (clk_base + offset) : NULL; periph->gate.clk_base = clk_base; + periph->gate.regs = bank; clk = clk_register(NULL, &periph->hw); if (IS_ERR(clk)) diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 2471742d68de..8507067d5dd6 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -27,27 +27,10 @@ #include "clk.h" -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00C #define RST_DFLL_DVCO 0x2F4 -#define RST_DEVICES_V 0x358 -#define RST_DEVICES_W 0x35C -#define RST_DEVICES_X 0x28C -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_SET_V 0x430 -#define RST_DEVICES_CLR_V 0x434 -#define RST_DEVICES_SET_W 0x438 -#define RST_DEVICES_CLR_W 0x43c #define CPU_FINETRIM_SELECT 0x4d4 /* override default prop dlys */ #define CPU_FINETRIM_DR 0x4d8 /* rise->rise prop dly A */ #define CPU_FINETRIM_R 0x4e4 /* rise->rise prop dly inc A */ -#define RST_DEVICES_NUM 5 /* RST_DFLL_DVCO bitfields */ #define DVFS_DFLL_RESET_SHIFT 0 @@ -74,26 +57,10 @@ #define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ #define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_V 0x360 -#define CLK_OUT_ENB_W 0x364 -#define CLK_OUT_ENB_X 0x280 -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 -#define CLK_OUT_ENB_SET_V 0x440 -#define CLK_OUT_ENB_CLR_V 0x444 -#define CLK_OUT_ENB_SET_W 0x448 -#define CLK_OUT_ENB_CLR_W 0x44c -#define CLK_OUT_ENB_SET_X 0x284 -#define CLK_OUT_ENB_CLR_X 0x288 #define CLK_OUT_ENB_NUM 6 +#define TEGRA114_CLK_PERIPH_BANKS 5 + #define PLLC_BASE 0x80 #define PLLC_MISC2 0x88 #define PLLC_MISC 0x8c @@ -728,53 +695,6 @@ static struct tegra_clk_pll_params pll_re_vco_params = { .div_nmp = &pllre_nmp, }; -/* Peripheral clock registers */ - -static struct tegra_clk_periph_regs periph_l_regs = { - .enb_reg = CLK_OUT_ENB_L, - .enb_set_reg = CLK_OUT_ENB_SET_L, - .enb_clr_reg = CLK_OUT_ENB_CLR_L, - .rst_reg = RST_DEVICES_L, - .rst_set_reg = RST_DEVICES_SET_L, - .rst_clr_reg = RST_DEVICES_CLR_L, -}; - -static struct tegra_clk_periph_regs periph_h_regs = { - .enb_reg = CLK_OUT_ENB_H, - .enb_set_reg = CLK_OUT_ENB_SET_H, - .enb_clr_reg = CLK_OUT_ENB_CLR_H, - .rst_reg = RST_DEVICES_H, - .rst_set_reg = RST_DEVICES_SET_H, - .rst_clr_reg = RST_DEVICES_CLR_H, -}; - -static struct tegra_clk_periph_regs periph_u_regs = { - .enb_reg = CLK_OUT_ENB_U, - .enb_set_reg = CLK_OUT_ENB_SET_U, - .enb_clr_reg = CLK_OUT_ENB_CLR_U, - .rst_reg = RST_DEVICES_U, - .rst_set_reg = RST_DEVICES_SET_U, - .rst_clr_reg = RST_DEVICES_CLR_U, -}; - -static struct tegra_clk_periph_regs periph_v_regs = { - .enb_reg = CLK_OUT_ENB_V, - .enb_set_reg = CLK_OUT_ENB_SET_V, - .enb_clr_reg = CLK_OUT_ENB_CLR_V, - .rst_reg = RST_DEVICES_V, - .rst_set_reg = RST_DEVICES_SET_V, - .rst_clr_reg = RST_DEVICES_CLR_V, -}; - -static struct tegra_clk_periph_regs periph_w_regs = { - .enb_reg = CLK_OUT_ENB_W, - .enb_set_reg = CLK_OUT_ENB_SET_W, - .enb_clr_reg = CLK_OUT_ENB_CLR_W, - .rst_reg = RST_DEVICES_W, - .rst_set_reg = RST_DEVICES_SET_W, - .rst_clr_reg = RST_DEVICES_CLR_W, -}; - /* possible OSC frequencies in Hz */ static unsigned long tegra114_input_freq[] = { [0] = 13000000, @@ -789,77 +709,77 @@ static unsigned long tegra114_input_freq[] = { #define MASK(x) (BIT(x) - 1) #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _regs, _clk_num, periph_clk_enb_refcnt, _gate_flags,\ + _clk_num, periph_clk_enb_refcnt, _gate_flags,\ _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _gate_flags, _clk_id, flags)\ + _clk_num, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _regs, _clk_num, periph_clk_enb_refcnt, _gate_flags,\ + _clk_num, periph_clk_enb_refcnt, _gate_flags,\ _clk_id, _parents##_idx, flags) #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _regs, _clk_num, periph_clk_enb_refcnt, _gate_flags,\ + _clk_num, periph_clk_enb_refcnt, _gate_flags,\ _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _gate_flags, _clk_id, flags)\ + _clk_num, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ - TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ periph_clk_enb_refcnt, _gate_flags, _clk_id, \ _parents##_idx, flags) #define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ - TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ periph_clk_enb_refcnt, _gate_flags, _clk_id, \ _parents##_idx, 0) #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _clk_id) \ + _clk_num, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ - TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _clk_id) \ + _clk_num, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ - _regs, _clk_num, periph_clk_enb_refcnt, 0, _clk_id,\ + _clk_num, periph_clk_enb_refcnt, 0, _clk_id,\ _parents##_idx, 0) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_mask, _clk_num, _regs, \ + _mux_shift, _mux_mask, _clk_num, \ _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - _mux_shift, _mux_mask, 0, 0, 0, 0, 0, _regs, \ + _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ _clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ - TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ periph_clk_enb_refcnt, _gate_flags, _clk_id, \ _parents##_idx, 0) #define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ - _regs, _gate_flags, _clk_id) \ + _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ _offset, 16, 0xE01F, 0, 0, 8, 1, \ - TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ periph_clk_enb_refcnt, _gate_flags , _clk_id, \ mux_d_audio_clk_idx, 0) @@ -1612,7 +1532,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) 0, &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 113, &periph_v_regs, + CLK_SET_RATE_PARENT, 113, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio0_2x", NULL); clks[TEGRA114_CLK_AUDIO0_2X] = clk; @@ -1625,7 +1545,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) 0, &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 114, &periph_v_regs, + CLK_SET_RATE_PARENT, 114, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio1_2x", NULL); clks[TEGRA114_CLK_AUDIO1_2X] = clk; @@ -1638,7 +1558,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) 0, &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 115, &periph_v_regs, + CLK_SET_RATE_PARENT, 115, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio2_2x", NULL); clks[TEGRA114_CLK_AUDIO2_2X] = clk; @@ -1651,7 +1571,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) 0, &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 116, &periph_v_regs, + CLK_SET_RATE_PARENT, 116, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio3_2x", NULL); clks[TEGRA114_CLK_AUDIO3_2X] = clk; @@ -1664,7 +1584,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) 0, &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 117, &periph_v_regs, + CLK_SET_RATE_PARENT, 117, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio4_2x", NULL); clks[TEGRA114_CLK_AUDIO4_2X] = clk; @@ -1678,7 +1598,7 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 118, - &periph_v_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, "spdif_2x", NULL); clks[TEGRA114_CLK_SPDIF_2X] = clk; } @@ -1805,86 +1725,86 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) } static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S0), - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S2), - TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S3), - TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S4), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_OUT), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_IN), - TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_PWM), - TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_ADX), - TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_AMX), - TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA), - TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA2CODEC_2X), - TEGRA_INIT_DATA_MUX8("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), - TEGRA_INIT_DATA_MUX8("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), - TEGRA_INIT_DATA_MUX8("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), - TEGRA_INIT_DATA_MUX8("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), - TEGRA_INIT_DATA_MUX8("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), - TEGRA_INIT_DATA_MUX8("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), - TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), - TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_VFIR), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, TEGRA114_CLK_SDMMC1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, TEGRA114_CLK_SDMMC2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, TEGRA114_CLK_SDMMC3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, TEGRA114_CLK_SDMMC4), - TEGRA_INIT_DATA_INT8("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, TEGRA114_CLK_VDE), - TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_CSITE, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_LA), - TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TRACE), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_OWR), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, TEGRA114_CLK_NOR), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_MIPI), - TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA114_CLK_I2C1), - TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA114_CLK_I2C2), - TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA114_CLK_I2C3), - TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, TEGRA114_CLK_I2C4), - TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, TEGRA114_CLK_I2C5), - TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, TEGRA114_CLK_UARTA), - TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, TEGRA114_CLK_UARTB), - TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, TEGRA114_CLK_UARTC), - TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, TEGRA114_CLK_UARTD), - TEGRA_INIT_DATA_INT8("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, TEGRA114_CLK_GR3D), - TEGRA_INIT_DATA_INT8("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, TEGRA114_CLK_GR2D), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), - TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, TEGRA114_CLK_VI), - TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, TEGRA114_CLK_EPP), - TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_u_regs, TEGRA_PERIPH_WAR_1005168, TEGRA114_CLK_MSENC), - TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, TEGRA114_CLK_TSEC), - TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, TEGRA114_CLK_HOST1X), - TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, TEGRA114_CLK_HDMI), - TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, TEGRA114_CLK_CILAB), - TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, TEGRA114_CLK_CILCD), - TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, TEGRA114_CLK_CILE), - TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, TEGRA114_CLK_DSIALP), - TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, TEGRA114_CLK_DSIBLP), - TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TSENSOR), - TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, TEGRA114_CLK_ACTMON), - TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, TEGRA114_CLK_EXTERN1), - TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, TEGRA114_CLK_EXTERN2), - TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, TEGRA114_CLK_EXTERN3), - TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2CSLOW), - TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SE), - TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, TEGRA114_CLK_MSELECT, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_REF), - TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_SOC), - TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SOC_THERM), - TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_HOST_SRC), - TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FALCON_SRC), - TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FS_SRC), - TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_SS_SRC), - TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_DEV_SRC), - TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_D_AUDIO), - TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM0), - TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM1), - TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM2), + TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S0), + TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S1), + TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S2), + TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S3), + TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S4), + TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_OUT), + TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_IN), + TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_PWM), + TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_ADX), + TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_AMX), + TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA), + TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA2CODEC_2X), + TEGRA_INIT_DATA_MUX8("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), + TEGRA_INIT_DATA_MUX8("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), + TEGRA_INIT_DATA_MUX8("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), + TEGRA_INIT_DATA_MUX8("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), + TEGRA_INIT_DATA_MUX8("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), + TEGRA_INIT_DATA_MUX8("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), + TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), + TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), + TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_VFIR), + TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, TEGRA114_CLK_SDMMC1), + TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, TEGRA114_CLK_SDMMC2), + TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, TEGRA114_CLK_SDMMC3), + TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, TEGRA114_CLK_SDMMC4), + TEGRA_INIT_DATA_INT8("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, TEGRA114_CLK_VDE), + TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_CSITE, CLK_IGNORE_UNUSED), + TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_LA), + TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TRACE), + TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_OWR), + TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, TEGRA114_CLK_NOR), + TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_MIPI), + TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, TEGRA114_CLK_I2C1), + TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, TEGRA114_CLK_I2C2), + TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, TEGRA114_CLK_I2C3), + TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, TEGRA114_CLK_I2C4), + TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, TEGRA114_CLK_I2C5), + TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, TEGRA114_CLK_UARTA), + TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, TEGRA114_CLK_UARTB), + TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, TEGRA114_CLK_UARTC), + TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, TEGRA114_CLK_UARTD), + TEGRA_INIT_DATA_INT8("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, TEGRA114_CLK_GR3D), + TEGRA_INIT_DATA_INT8("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, TEGRA114_CLK_GR2D), + TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), + TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, TEGRA114_CLK_VI), + TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, TEGRA114_CLK_EPP), + TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, TEGRA114_CLK_MSENC), + TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, TEGRA114_CLK_TSEC), + TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, TEGRA114_CLK_HOST1X), + TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA114_CLK_HDMI), + TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, TEGRA114_CLK_CILAB), + TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, TEGRA114_CLK_CILCD), + TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, TEGRA114_CLK_CILE), + TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, 0, TEGRA114_CLK_DSIALP), + TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, 0, TEGRA114_CLK_DSIBLP), + TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TSENSOR), + TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, 0, TEGRA114_CLK_ACTMON), + TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, TEGRA114_CLK_EXTERN1), + TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, TEGRA114_CLK_EXTERN2), + TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, TEGRA114_CLK_EXTERN3), + TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2CSLOW), + TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SE), + TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, TEGRA114_CLK_MSELECT, CLK_IGNORE_UNUSED), + TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_REF), + TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_SOC), + TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SOC_THERM), + TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_HOST_SRC), + TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FALCON_SRC), + TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FS_SRC), + TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_SS_SRC), + TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_DEV_SRC), + TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_D_AUDIO), + TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM0), + TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM1), + TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM2), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, &periph_l_regs, 0, TEGRA114_CLK_DISP1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, &periph_l_regs, 0, TEGRA114_CLK_DISP2), + TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, TEGRA114_CLK_DISP1), + TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, TEGRA114_CLK_DISP2), }; static __init void tegra114_periph_clk_init(void __iomem *clk_base) @@ -1896,16 +1816,14 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) /* apbdma */ clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, - 0, 34, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 34, periph_clk_enb_refcnt); clks[TEGRA114_CLK_APBDMA] = clk; /* rtc */ clk = tegra_clk_register_periph_gate("rtc", "clk_32k", TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, clk_base, - 0, 4, &periph_l_regs, - periph_clk_enb_refcnt); + 0, 4, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "rtc-tegra"); clks[TEGRA114_CLK_RTC] = clk; @@ -1913,123 +1831,112 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) clk = tegra_clk_register_periph_gate("kbc", "clk_32k", TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, clk_base, - 0, 36, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 36, periph_clk_enb_refcnt); clks[TEGRA114_CLK_KBC] = clk; /* timer */ clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, - 0, 5, &periph_l_regs, - periph_clk_enb_refcnt); + 0, 5, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "timer"); clks[TEGRA114_CLK_TIMER] = clk; /* kfuse */ clk = tegra_clk_register_periph_gate("kfuse", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 40, - &periph_h_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_KFUSE] = clk; /* fuse */ clk = tegra_clk_register_periph_gate("fuse", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 39, - &periph_h_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_FUSE] = clk; /* fuse_burn */ clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 39, - &periph_h_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_FUSE_BURN] = clk; /* apbif */ clk = tegra_clk_register_periph_gate("apbif", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 107, - &periph_v_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_APBIF] = clk; /* hda2hdmi */ clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 128, - &periph_w_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_HDA2HDMI] = clk; /* vcp */ clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, - 29, &periph_l_regs, - periph_clk_enb_refcnt); + 29, periph_clk_enb_refcnt); clks[TEGRA114_CLK_VCP] = clk; /* bsea */ clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, - 0, 62, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 62, periph_clk_enb_refcnt); clks[TEGRA114_CLK_BSEA] = clk; /* bsev */ clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, - 0, 63, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 63, periph_clk_enb_refcnt); clks[TEGRA114_CLK_BSEV] = clk; /* mipi-cal */ clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, - 0, 56, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 56, periph_clk_enb_refcnt); clks[TEGRA114_CLK_MIPI_CAL] = clk; /* usbd */ clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, - 0, 22, &periph_l_regs, - periph_clk_enb_refcnt); + 0, 22, periph_clk_enb_refcnt); clks[TEGRA114_CLK_USBD] = clk; /* usb2 */ clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, - 0, 58, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 58, periph_clk_enb_refcnt); clks[TEGRA114_CLK_USB2] = clk; /* usb3 */ clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, - 0, 59, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 59, periph_clk_enb_refcnt); clks[TEGRA114_CLK_USB3] = clk; /* csi */ clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 52, periph_clk_enb_refcnt); clks[TEGRA114_CLK_CSI] = clk; /* isp */ clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, - 23, &periph_l_regs, - periph_clk_enb_refcnt); + 23, periph_clk_enb_refcnt); clks[TEGRA114_CLK_ISP] = clk; /* csus */ clk = tegra_clk_register_periph_gate("csus", "clk_m", TEGRA_PERIPH_NO_RESET, clk_base, 0, 92, - &periph_u_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_CSUS] = clk; /* dds */ clk = tegra_clk_register_periph_gate("dds", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 150, - &periph_w_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_DDS] = clk; /* dp2 */ clk = tegra_clk_register_periph_gate("dp2", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 152, - &periph_w_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_DP2] = clk; /* dtv */ clk = tegra_clk_register_periph_gate("dtv", "clk_m", TEGRA_PERIPH_ON_APB, clk_base, 0, 79, - &periph_u_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clks[TEGRA114_CLK_DTV] = clk; /* dsia */ @@ -2039,8 +1946,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); clks[TEGRA114_CLK_DSIA_MUX] = clk; clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, - 0, 48, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 48, periph_clk_enb_refcnt); clks[TEGRA114_CLK_DSIA] = clk; /* dsib */ @@ -2050,8 +1956,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); clks[TEGRA114_CLK_DSIB_MUX] = clk; clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, - 0, 82, &periph_u_regs, - periph_clk_enb_refcnt); + 0, 82, periph_clk_enb_refcnt); clks[TEGRA114_CLK_DSIB] = clk; /* xusb_hs_src */ @@ -2065,20 +1970,17 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) /* xusb_host */ clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, - clk_base, 0, 89, &periph_u_regs, - periph_clk_enb_refcnt); + clk_base, 0, 89, periph_clk_enb_refcnt); clks[TEGRA114_CLK_XUSB_HOST] = clk; /* xusb_ss */ clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, - clk_base, 0, 156, &periph_w_regs, - periph_clk_enb_refcnt); + clk_base, 0, 156, periph_clk_enb_refcnt); clks[TEGRA114_CLK_XUSB_HOST] = clk; /* xusb_dev */ clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, - clk_base, 0, 95, &periph_u_regs, - periph_clk_enb_refcnt); + clk_base, 0, 95, periph_clk_enb_refcnt); clks[TEGRA114_CLK_XUSB_DEV] = clk; /* emc */ @@ -2088,20 +1990,21 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) clk_base + CLK_SOURCE_EMC, 29, 3, 0, NULL); clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, - CLK_IGNORE_UNUSED, 57, &periph_h_regs, - periph_clk_enb_refcnt); + CLK_IGNORE_UNUSED, 57, periph_clk_enb_refcnt); clks[TEGRA114_CLK_EMC] = clk; for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; - clk = tegra_clk_register_periph(data->name, data->parent_names, - data->num_parents, &data->periph, - clk_base, data->offset, data->flags); + + clk = tegra_clk_register_periph(data->name, + data->parent_names, data->num_parents, &data->periph, + clk_base, data->offset, data->flags); clks[data->clk_id] = clk; } for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { data = &tegra_periph_nodiv_clk_list[i]; + clk = tegra_clk_register_periph_nodiv(data->name, data->parent_names, data->num_parents, &data->periph, clk_base, data->offset); @@ -2351,6 +2254,9 @@ static void __init tegra114_clock_init(struct device_node *np) if (tegra114_osc_clk_init(clk_base) < 0) return; + if (tegra_clk_set_periph_banks(TEGRA114_CLK_PERIPH_BANKS) < 0) + return; + tegra114_fixed_clk_init(clk_base); tegra114_pll_init(clk_base, pmc_base); tegra114_periph_clk_init(clk_base); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 056f649d0d89..929a46278d83 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -25,26 +25,6 @@ #include "clk.h" -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00c -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_NUM 3 - -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 #define CLK_OUT_ENB_NUM 3 #define OSC_CTRL 0x50 @@ -67,6 +47,8 @@ #define OSC_FREQ_DET_BUSY (1<<31) #define OSC_FREQ_DET_CNT_MASK 0xFFFF +#define TEGRA20_CLK_PERIPH_BANKS 3 + #define PLLS_BASE 0xf0 #define PLLS_MISC 0xf4 #define PLLC_BASE 0x80 @@ -197,31 +179,31 @@ static DEFINE_SPINLOCK(pll_div_lock); static DEFINE_SPINLOCK(sysrate_lock); #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _regs, _clk_num, periph_clk_enb_refcnt, \ + _clk_num, periph_clk_enb_refcnt, \ _gate_flags, _clk_id) #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ + 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \ _clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_id) #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, _regs, \ + 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_id) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, _clk_num, _regs, \ + _mux_shift, _mux_width, _clk_num, \ _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ + _mux_shift, _mux_width, 0, 0, 0, 0, 0, \ _clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_id) @@ -490,34 +472,6 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_delay = 0, }; -/* Peripheral clock registers */ -static struct tegra_clk_periph_regs periph_l_regs = { - .enb_reg = CLK_OUT_ENB_L, - .enb_set_reg = CLK_OUT_ENB_SET_L, - .enb_clr_reg = CLK_OUT_ENB_CLR_L, - .rst_reg = RST_DEVICES_L, - .rst_set_reg = RST_DEVICES_SET_L, - .rst_clr_reg = RST_DEVICES_CLR_L, -}; - -static struct tegra_clk_periph_regs periph_h_regs = { - .enb_reg = CLK_OUT_ENB_H, - .enb_set_reg = CLK_OUT_ENB_SET_H, - .enb_clr_reg = CLK_OUT_ENB_CLR_H, - .rst_reg = RST_DEVICES_H, - .rst_set_reg = RST_DEVICES_SET_H, - .rst_clr_reg = RST_DEVICES_CLR_H, -}; - -static struct tegra_clk_periph_regs periph_u_regs = { - .enb_reg = CLK_OUT_ENB_U, - .enb_set_reg = CLK_OUT_ENB_SET_U, - .enb_clr_reg = CLK_OUT_ENB_CLR_U, - .rst_reg = RST_DEVICES_U, - .rst_set_reg = RST_DEVICES_SET_U, - .rst_clr_reg = RST_DEVICES_CLR_U, -}; - static unsigned long tegra20_clk_measure_input_freq(void) { u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); @@ -792,7 +746,7 @@ static void __init tegra20_audio_clk_init(void) CLK_SET_RATE_PARENT, 2, 1); clk = tegra_clk_register_periph_gate("audio_2x", "audio_doubler", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 89, &periph_u_regs, + CLK_SET_RATE_PARENT, 89, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio_2x", NULL); clks[audio_2x] = clk; @@ -815,56 +769,56 @@ static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c", static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"}; static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra20-i2s.0", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra20-i2s.1", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra20-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra20-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("spi", NULL, "spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, &periph_h_regs, TEGRA_PERIPH_ON_APB, spi), - TEGRA_INIT_DATA_MUX("xio", NULL, "xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, &periph_h_regs, 0, xio), - TEGRA_INIT_DATA_MUX("twc", NULL, "twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, &periph_l_regs, TEGRA_PERIPH_ON_APB, twc), - TEGRA_INIT_DATA_MUX("ide", NULL, "ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, &periph_l_regs, 0, ide), - TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, 0, ndflash), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, 0, csite), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, 0, la), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_MUX("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), - TEGRA_INIT_DATA_MUX("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), - TEGRA_INIT_DATA_MUX("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), - TEGRA_INIT_DATA_MUX("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), - TEGRA_INIT_DATA_MUX("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), - TEGRA_INIT_DATA_MUX("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), - TEGRA_INIT_DATA_MUX("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), - TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), - TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), - TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), - TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), - TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), - TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, dvc), - TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), - TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm), + TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra20-i2s.0", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, i2s1), + TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra20-i2s.1", i2s2_parents, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, i2s2), + TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra20-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, spdif_out), + TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra20-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, spdif_in), + TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, sbc1), + TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, sbc2), + TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, sbc3), + TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, sbc4), + TEGRA_INIT_DATA_MUX("spi", NULL, "spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, TEGRA_PERIPH_ON_APB, spi), + TEGRA_INIT_DATA_MUX("xio", NULL, "xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, 0, xio), + TEGRA_INIT_DATA_MUX("twc", NULL, "twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, TEGRA_PERIPH_ON_APB, twc), + TEGRA_INIT_DATA_MUX("ide", NULL, "ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, 0, ide), + TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, 0, ndflash), + TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, vfir), + TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, 0, csite), + TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, 0, la), + TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, owr), + TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, mipi), + TEGRA_INIT_DATA_MUX("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, 0, vde), + TEGRA_INIT_DATA_MUX("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, 0, vi), + TEGRA_INIT_DATA_MUX("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, 0, epp), + TEGRA_INIT_DATA_MUX("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, 0, mpe), + TEGRA_INIT_DATA_MUX("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, 0, host1x), + TEGRA_INIT_DATA_MUX("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, TEGRA_PERIPH_MANUAL_RESET, gr3d), + TEGRA_INIT_DATA_MUX("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, 0, gr2d), + TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, 0, nor), + TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, 0, sdmmc1), + TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, 0, sdmmc2), + TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, 0, sdmmc3), + TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, 0, sdmmc4), + TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, 0, cve), + TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, 0, tvo), + TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, 0, tvdac), + TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, vi_sensor), + TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, TEGRA_PERIPH_ON_APB, i2c1), + TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, TEGRA_PERIPH_ON_APB, i2c2), + TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3), + TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, dvc), + TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi), + TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, &periph_l_regs, TEGRA_PERIPH_ON_APB, uarta), - TEGRA_INIT_DATA_NODIV("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, uartb), - TEGRA_INIT_DATA_NODIV("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, &periph_h_regs, TEGRA_PERIPH_ON_APB, uartc), - TEGRA_INIT_DATA_NODIV("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, &periph_u_regs, TEGRA_PERIPH_ON_APB, uartd), - TEGRA_INIT_DATA_NODIV("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, &periph_u_regs, TEGRA_PERIPH_ON_APB, uarte), - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, &periph_l_regs, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, &periph_l_regs, 0, disp2), + TEGRA_INIT_DATA_NODIV("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, TEGRA_PERIPH_ON_APB, uarta), + TEGRA_INIT_DATA_NODIV("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, TEGRA_PERIPH_ON_APB, uartb), + TEGRA_INIT_DATA_NODIV("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, TEGRA_PERIPH_ON_APB, uartc), + TEGRA_INIT_DATA_NODIV("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, TEGRA_PERIPH_ON_APB, uartd), + TEGRA_INIT_DATA_NODIV("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, TEGRA_PERIPH_ON_APB, uarte), + TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, 0, disp1), + TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, disp2), }; static void __init tegra20_periph_clk_init(void) @@ -876,67 +830,58 @@ static void __init tegra20_periph_clk_init(void) /* ac97 */ clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", TEGRA_PERIPH_ON_APB, - clk_base, 0, 3, &periph_l_regs, - periph_clk_enb_refcnt); + clk_base, 0, 3, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra20-ac97"); clks[ac97] = clk; /* apbdma */ clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, - 0, 34, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 34, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-apbdma"); clks[apbdma] = clk; /* rtc */ clk = tegra_clk_register_periph_gate("rtc", "clk_32k", TEGRA_PERIPH_NO_RESET, - clk_base, 0, 4, &periph_l_regs, - periph_clk_enb_refcnt); + clk_base, 0, 4, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "rtc-tegra"); clks[rtc] = clk; /* timer */ clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, - 0, 5, &periph_l_regs, - periph_clk_enb_refcnt); + 0, 5, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "timer"); clks[timer] = clk; /* kbc */ clk = tegra_clk_register_periph_gate("kbc", "clk_32k", TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 36, &periph_h_regs, - periph_clk_enb_refcnt); + clk_base, 0, 36, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-kbc"); clks[kbc] = clk; /* csus */ clk = tegra_clk_register_periph_gate("csus", "clk_m", TEGRA_PERIPH_NO_RESET, - clk_base, 0, 92, &periph_u_regs, - periph_clk_enb_refcnt); + clk_base, 0, 92, periph_clk_enb_refcnt); clk_register_clkdev(clk, "csus", "tengra_camera"); clks[csus] = clk; /* vcp */ clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, - clk_base, 0, 29, &periph_l_regs, - periph_clk_enb_refcnt); + clk_base, 0, 29, periph_clk_enb_refcnt); clk_register_clkdev(clk, "vcp", "tegra-avp"); clks[vcp] = clk; /* bsea */ clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, - clk_base, 0, 62, &periph_h_regs, - periph_clk_enb_refcnt); + clk_base, 0, 62, periph_clk_enb_refcnt); clk_register_clkdev(clk, "bsea", "tegra-avp"); clks[bsea] = clk; /* bsev */ clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, - clk_base, 0, 63, &periph_h_regs, - periph_clk_enb_refcnt); + clk_base, 0, 63, periph_clk_enb_refcnt); clk_register_clkdev(clk, "bsev", "tegra-aes"); clks[bsev] = clk; @@ -947,63 +892,61 @@ static void __init tegra20_periph_clk_init(void) clk_base + CLK_SOURCE_EMC, 30, 2, 0, NULL); clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, - 57, &periph_h_regs, periph_clk_enb_refcnt); + 57, periph_clk_enb_refcnt); clk_register_clkdev(clk, "emc", NULL); clks[emc] = clk; /* usbd */ clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, - 22, &periph_l_regs, periph_clk_enb_refcnt); + 22, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); clks[usbd] = clk; /* usb2 */ clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, - 58, &periph_h_regs, periph_clk_enb_refcnt); + 58, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-ehci.1"); clks[usb2] = clk; /* usb3 */ clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, - 59, &periph_h_regs, periph_clk_enb_refcnt); + 59, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-ehci.2"); clks[usb3] = clk; /* dsi */ clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, - 48, &periph_h_regs, periph_clk_enb_refcnt); + 48, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "dsi"); clks[dsi] = clk; /* csi */ clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 52, periph_clk_enb_refcnt); clk_register_clkdev(clk, "csi", "tegra_camera"); clks[csi] = clk; /* isp */ clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, - &periph_l_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, "isp", "tegra_camera"); clks[isp] = clk; /* pex */ clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70, - &periph_u_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, "pex", NULL); clks[pex] = clk; /* afi */ clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, - &periph_u_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, "afi", NULL); clks[afi] = clk; /* pcie_xclk */ clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base, - 0, 74, &periph_u_regs, - periph_clk_enb_refcnt); + 0, 74, periph_clk_enb_refcnt); clk_register_clkdev(clk, "pcie_xclk", NULL); clks[pcie_xclk] = clk; @@ -1011,8 +954,7 @@ static void __init tegra20_periph_clk_init(void) clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, 26000000); clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, - clk_base, 0, 94, &periph_u_regs, - periph_clk_enb_refcnt); + clk_base, 0, 94, periph_clk_enb_refcnt); clk_register_clkdev(clk, "cdev1", NULL); clks[cdev1] = clk; @@ -1020,8 +962,7 @@ static void __init tegra20_periph_clk_init(void) clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, 26000000); clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, - clk_base, 0, 93, &periph_u_regs, - periph_clk_enb_refcnt); + clk_base, 0, 93, periph_clk_enb_refcnt); clk_register_clkdev(clk, "cdev2", NULL); clks[cdev2] = clk; @@ -1312,6 +1253,9 @@ static void __init tegra20_clock_init(struct device_node *np) BUG(); } + if (tegra_clk_set_periph_banks(TEGRA20_CLK_PERIPH_BANKS) < 0) + return; + tegra20_osc_clk_init(); tegra20_pmc_clk_init(); tegra20_fixed_clk_init(); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 147f5b9fed11..a66bdabb5c5c 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -26,38 +26,6 @@ #include "clk.h" -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00c -#define RST_DEVICES_V 0x358 -#define RST_DEVICES_W 0x35c -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_SET_V 0x430 -#define RST_DEVICES_CLR_V 0x434 -#define RST_DEVICES_SET_W 0x438 -#define RST_DEVICES_CLR_W 0x43c -#define RST_DEVICES_NUM 5 - -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_V 0x360 -#define CLK_OUT_ENB_W 0x364 -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 -#define CLK_OUT_ENB_SET_V 0x440 -#define CLK_OUT_ENB_CLR_V 0x444 -#define CLK_OUT_ENB_SET_W 0x448 -#define CLK_OUT_ENB_CLR_W 0x44c #define CLK_OUT_ENB_NUM 5 #define OSC_CTRL 0x50 @@ -92,6 +60,8 @@ #define SYSTEM_CLK_RATE 0x030 +#define TEGRA30_CLK_PERIPH_BANKS 5 + #define PLLC_BASE 0x80 #define PLLC_MISC 0x8c #define PLLM_BASE 0x90 @@ -280,43 +250,43 @@ static DEFINE_SPINLOCK(pll_d_lock); static DEFINE_SPINLOCK(sysrate_lock); #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, _regs, \ + 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ - _regs, _clk_num, periph_clk_enb_refcnt, \ + _clk_num, periph_clk_enb_refcnt, \ _gate_flags, _clk_id) #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, _regs,\ + 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ - TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ periph_clk_enb_refcnt, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _clk_id) \ + _clk_num, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ - TEGRA_DIVIDER_ROUND_UP, _regs, _clk_num, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ periph_clk_enb_refcnt, 0, _clk_id) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, _clk_num, _regs, \ + _mux_shift, _mux_width, _clk_num, \ _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ + _mux_shift, _mux_width, 0, 0, 0, 0, 0,\ _clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_id) @@ -695,52 +665,6 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_delay = 300, }; -/* Peripheral clock registers */ -static struct tegra_clk_periph_regs periph_l_regs = { - .enb_reg = CLK_OUT_ENB_L, - .enb_set_reg = CLK_OUT_ENB_SET_L, - .enb_clr_reg = CLK_OUT_ENB_CLR_L, - .rst_reg = RST_DEVICES_L, - .rst_set_reg = RST_DEVICES_SET_L, - .rst_clr_reg = RST_DEVICES_CLR_L, -}; - -static struct tegra_clk_periph_regs periph_h_regs = { - .enb_reg = CLK_OUT_ENB_H, - .enb_set_reg = CLK_OUT_ENB_SET_H, - .enb_clr_reg = CLK_OUT_ENB_CLR_H, - .rst_reg = RST_DEVICES_H, - .rst_set_reg = RST_DEVICES_SET_H, - .rst_clr_reg = RST_DEVICES_CLR_H, -}; - -static struct tegra_clk_periph_regs periph_u_regs = { - .enb_reg = CLK_OUT_ENB_U, - .enb_set_reg = CLK_OUT_ENB_SET_U, - .enb_clr_reg = CLK_OUT_ENB_CLR_U, - .rst_reg = RST_DEVICES_U, - .rst_set_reg = RST_DEVICES_SET_U, - .rst_clr_reg = RST_DEVICES_CLR_U, -}; - -static struct tegra_clk_periph_regs periph_v_regs = { - .enb_reg = CLK_OUT_ENB_V, - .enb_set_reg = CLK_OUT_ENB_SET_V, - .enb_clr_reg = CLK_OUT_ENB_CLR_V, - .rst_reg = RST_DEVICES_V, - .rst_set_reg = RST_DEVICES_SET_V, - .rst_clr_reg = RST_DEVICES_CLR_V, -}; - -static struct tegra_clk_periph_regs periph_w_regs = { - .enb_reg = CLK_OUT_ENB_W, - .enb_set_reg = CLK_OUT_ENB_SET_W, - .enb_clr_reg = CLK_OUT_ENB_CLR_W, - .rst_reg = RST_DEVICES_W, - .rst_set_reg = RST_DEVICES_SET_W, - .rst_clr_reg = RST_DEVICES_CLR_W, -}; - static void tegra30_clk_measure_input_freq(void) { u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); @@ -1160,7 +1084,7 @@ static void __init tegra30_audio_clk_init(void) &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 113, &periph_v_regs, + CLK_SET_RATE_PARENT, 113, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio0_2x", NULL); clks[audio0_2x] = clk; @@ -1173,7 +1097,7 @@ static void __init tegra30_audio_clk_init(void) &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 114, &periph_v_regs, + CLK_SET_RATE_PARENT, 114, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio1_2x", NULL); clks[audio1_2x] = clk; @@ -1186,7 +1110,7 @@ static void __init tegra30_audio_clk_init(void) &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 115, &periph_v_regs, + CLK_SET_RATE_PARENT, 115, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio2_2x", NULL); clks[audio2_2x] = clk; @@ -1199,7 +1123,7 @@ static void __init tegra30_audio_clk_init(void) &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 116, &periph_v_regs, + CLK_SET_RATE_PARENT, 116, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio3_2x", NULL); clks[audio3_2x] = clk; @@ -1212,7 +1136,7 @@ static void __init tegra30_audio_clk_init(void) &clk_doubler_lock); clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 117, &periph_v_regs, + CLK_SET_RATE_PARENT, 117, periph_clk_enb_refcnt); clk_register_clkdev(clk, "audio4_2x", NULL); clks[audio4_2x] = clk; @@ -1225,7 +1149,7 @@ static void __init tegra30_audio_clk_init(void) &clk_doubler_lock); clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 118, &periph_v_regs, + CLK_SET_RATE_PARENT, 118, periph_clk_enb_refcnt); clk_register_clkdev(clk, "spdif_2x", NULL); clks[spdif_2x] = clk; @@ -1444,77 +1368,77 @@ static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", "pll_d2_out0" }; static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", i2s0_parents, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", i2s3_parents, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), - TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", i2s4_parents, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("d_audio", "d_audio", "tegra30-ahub", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, 0, d_audio), - TEGRA_INIT_DATA_MUX("dam0", NULL, "tegra30-dam.0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, &periph_v_regs, 0, dam0), - TEGRA_INIT_DATA_MUX("dam1", NULL, "tegra30-dam.1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, &periph_v_regs, 0, dam1), - TEGRA_INIT_DATA_MUX("dam2", NULL, "tegra30-dam.2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, &periph_v_regs, 0, dam2), - TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, 0, hda), - TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, 0, hda2codec_2x), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("sbc5", NULL, "spi_tegra.4", mux_pllpcm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), - TEGRA_INIT_DATA_MUX("sbc6", NULL, "spi_tegra.5", mux_pllpcm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), - TEGRA_INIT_DATA_MUX("sata_oob", NULL, "tegra_sata_oob", mux_pllpcm_clkm, CLK_SOURCE_SATA_OOB, 123, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata_oob), - TEGRA_INIT_DATA_MUX("sata", NULL, "tegra_sata", mux_pllpcm_clkm, CLK_SOURCE_SATA, 124, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata), - TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, TEGRA_PERIPH_ON_APB, ndflash), - TEGRA_INIT_DATA_MUX("ndspeed", NULL, "tegra_nand_speed", mux_pllpcm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllpc_clkm_clk32k, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), - TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllpc_clk32k_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), - TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), - TEGRA_INIT_DATA_INT("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), - TEGRA_INIT_DATA_INT("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), - TEGRA_INIT_DATA_INT("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), - TEGRA_INIT_DATA_INT("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), - TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), - TEGRA_INIT_DATA_INT("3d2", NULL, "3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, &periph_v_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d2), - TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), - TEGRA_INIT_DATA_INT("se", NULL, "se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, 0, se), - TEGRA_INIT_DATA_MUX("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), - TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), - TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), - TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), - TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllpc_clk32k_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), - TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), - TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), - TEGRA_INIT_DATA_DIV16("i2c4", "div-clk", "tegra-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2c4), - TEGRA_INIT_DATA_DIV16("i2c5", "div-clk", "tegra-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c5), - TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), - TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), - TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), - TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), - TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 66, &periph_u_regs, uarte), - TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), - TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), - TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), - TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), - TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, 0, pwm), + TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", i2s0_parents, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, i2s0), + TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, i2s1), + TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", i2s2_parents, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, i2s2), + TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", i2s3_parents, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, i2s3), + TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", i2s4_parents, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, i2s4), + TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, spdif_out), + TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, spdif_in), + TEGRA_INIT_DATA_MUX("d_audio", "d_audio", "tegra30-ahub", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, 0, d_audio), + TEGRA_INIT_DATA_MUX("dam0", NULL, "tegra30-dam.0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, 0, dam0), + TEGRA_INIT_DATA_MUX("dam1", NULL, "tegra30-dam.1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, 0, dam1), + TEGRA_INIT_DATA_MUX("dam2", NULL, "tegra30-dam.2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, 0, dam2), + TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA, 125, 0, hda), + TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, 0, hda2codec_2x), + TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, sbc1), + TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, sbc2), + TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, sbc3), + TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, sbc4), + TEGRA_INIT_DATA_MUX("sbc5", NULL, "spi_tegra.4", mux_pllpcm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, sbc5), + TEGRA_INIT_DATA_MUX("sbc6", NULL, "spi_tegra.5", mux_pllpcm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, sbc6), + TEGRA_INIT_DATA_MUX("sata_oob", NULL, "tegra_sata_oob", mux_pllpcm_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, sata_oob), + TEGRA_INIT_DATA_MUX("sata", NULL, "tegra_sata", mux_pllpcm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, sata), + TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, ndflash), + TEGRA_INIT_DATA_MUX("ndspeed", NULL, "tegra_nand_speed", mux_pllpcm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, ndspeed), + TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, vfir), + TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, csite), + TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, la), + TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, owr), + TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, mipi), + TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllpc_clkm_clk32k, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, tsensor), + TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllpc_clk32k_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, i2cslow), + TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, 0, vde), + TEGRA_INIT_DATA_INT("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, 0, vi), + TEGRA_INIT_DATA_INT("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, 0, epp), + TEGRA_INIT_DATA_INT("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, 0, mpe), + TEGRA_INIT_DATA_INT("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, 0, host1x), + TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, TEGRA_PERIPH_MANUAL_RESET, gr3d), + TEGRA_INIT_DATA_INT("3d2", NULL, "3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, TEGRA_PERIPH_MANUAL_RESET, gr3d2), + TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, 0, gr2d), + TEGRA_INIT_DATA_INT("se", NULL, "se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, 0, se), + TEGRA_INIT_DATA_MUX("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, mselect), + TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, 0, nor), + TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, 0, sdmmc1), + TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, 0, sdmmc2), + TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, 0, sdmmc3), + TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, 0, sdmmc4), + TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, 0, cve), + TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, 0, tvo), + TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, 0, tvdac), + TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllpc_clk32k_clkm, CLK_SOURCE_ACTMON, 119, 0, actmon), + TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, vi_sensor), + TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, TEGRA_PERIPH_ON_APB, i2c1), + TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, TEGRA_PERIPH_ON_APB, i2c2), + TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3), + TEGRA_INIT_DATA_DIV16("i2c4", "div-clk", "tegra-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, TEGRA_PERIPH_ON_APB, i2c4), + TEGRA_INIT_DATA_DIV16("i2c5", "div-clk", "tegra-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, TEGRA_PERIPH_ON_APB, i2c5), + TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 6, uarta), + TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 7, uartb), + TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 55, uartc), + TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 65, uartd), + TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 66, uarte), + TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi), + TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, extern1), + TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, extern2), + TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, extern3), + TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, 0, pwm), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, &periph_l_regs, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, &periph_l_regs, 0, disp2), - TEGRA_INIT_DATA_NODIV("dsib", NULL, "tegradc.1", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, &periph_u_regs, 0, dsib), + TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, 0, disp1), + TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, 0, disp2), + TEGRA_INIT_DATA_NODIV("dsib", NULL, "tegradc.1", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, 0, dsib), }; static void __init tegra30_periph_clk_init(void) @@ -1525,166 +1449,154 @@ static void __init tegra30_periph_clk_init(void) /* apbdma */ clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, 0, 34, - &periph_h_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-apbdma"); clks[apbdma] = clk; /* rtc */ clk = tegra_clk_register_periph_gate("rtc", "clk_32k", TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 4, &periph_l_regs, - periph_clk_enb_refcnt); + clk_base, 0, 4, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "rtc-tegra"); clks[rtc] = clk; /* timer */ clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0, - 5, &periph_l_regs, periph_clk_enb_refcnt); + 5, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "timer"); clks[timer] = clk; /* kbc */ clk = tegra_clk_register_periph_gate("kbc", "clk_32k", TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 36, &periph_h_regs, - periph_clk_enb_refcnt); + clk_base, 0, 36, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-kbc"); clks[kbc] = clk; /* csus */ clk = tegra_clk_register_periph_gate("csus", "clk_m", TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 92, &periph_u_regs, - periph_clk_enb_refcnt); + clk_base, 0, 92, periph_clk_enb_refcnt); clk_register_clkdev(clk, "csus", "tengra_camera"); clks[csus] = clk; /* vcp */ clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, 29, - &periph_l_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, "vcp", "tegra-avp"); clks[vcp] = clk; /* bsea */ clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, 0, - 62, &periph_h_regs, periph_clk_enb_refcnt); + 62, periph_clk_enb_refcnt); clk_register_clkdev(clk, "bsea", "tegra-avp"); clks[bsea] = clk; /* bsev */ clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, 0, - 63, &periph_h_regs, periph_clk_enb_refcnt); + 63, periph_clk_enb_refcnt); clk_register_clkdev(clk, "bsev", "tegra-aes"); clks[bsev] = clk; /* usbd */ clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, - 22, &periph_l_regs, periph_clk_enb_refcnt); + 22, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); clks[usbd] = clk; /* usb2 */ clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, - 58, &periph_h_regs, periph_clk_enb_refcnt); + 58, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-ehci.1"); clks[usb2] = clk; /* usb3 */ clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, - 59, &periph_h_regs, periph_clk_enb_refcnt); + 59, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra-ehci.2"); clks[usb3] = clk; /* dsia */ clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base, - 0, 48, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 48, periph_clk_enb_refcnt); clk_register_clkdev(clk, "dsia", "tegradc.0"); clks[dsia] = clk; /* csi */ clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, &periph_h_regs, - periph_clk_enb_refcnt); + 0, 52, periph_clk_enb_refcnt); clk_register_clkdev(clk, "csi", "tegra_camera"); clks[csi] = clk; /* isp */ clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, - &periph_l_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, "isp", "tegra_camera"); clks[isp] = clk; /* pcie */ clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, - 70, &periph_u_regs, periph_clk_enb_refcnt); + 70, periph_clk_enb_refcnt); clk_register_clkdev(clk, "pcie", "tegra-pcie"); clks[pcie] = clk; /* afi */ clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, - &periph_u_regs, periph_clk_enb_refcnt); + periph_clk_enb_refcnt); clk_register_clkdev(clk, "afi", "tegra-pcie"); clks[afi] = clk; /* pciex */ clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0, - 74, &periph_u_regs, periph_clk_enb_refcnt); + 74, periph_clk_enb_refcnt); clk_register_clkdev(clk, "pciex", "tegra-pcie"); clks[pciex] = clk; /* kfuse */ clk = tegra_clk_register_periph_gate("kfuse", "clk_m", TEGRA_PERIPH_ON_APB, - clk_base, 0, 40, &periph_h_regs, - periph_clk_enb_refcnt); + clk_base, 0, 40, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "kfuse-tegra"); clks[kfuse] = clk; /* fuse */ clk = tegra_clk_register_periph_gate("fuse", "clk_m", TEGRA_PERIPH_ON_APB, - clk_base, 0, 39, &periph_h_regs, - periph_clk_enb_refcnt); + clk_base, 0, 39, periph_clk_enb_refcnt); clk_register_clkdev(clk, "fuse", "fuse-tegra"); clks[fuse] = clk; /* fuse_burn */ clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", TEGRA_PERIPH_ON_APB, - clk_base, 0, 39, &periph_h_regs, - periph_clk_enb_refcnt); + clk_base, 0, 39, periph_clk_enb_refcnt); clk_register_clkdev(clk, "fuse_burn", "fuse-tegra"); clks[fuse_burn] = clk; /* apbif */ clk = tegra_clk_register_periph_gate("apbif", "clk_m", 0, - clk_base, 0, 107, &periph_v_regs, - periph_clk_enb_refcnt); + clk_base, 0, 107, periph_clk_enb_refcnt); clk_register_clkdev(clk, "apbif", "tegra30-ahub"); clks[apbif] = clk; /* hda2hdmi */ clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", TEGRA_PERIPH_ON_APB, - clk_base, 0, 128, &periph_w_regs, - periph_clk_enb_refcnt); + clk_base, 0, 128, periph_clk_enb_refcnt); clk_register_clkdev(clk, "hda2hdmi", "tegra30-hda"); clks[hda2hdmi] = clk; /* sata_cold */ clk = tegra_clk_register_periph_gate("sata_cold", "clk_m", TEGRA_PERIPH_ON_APB, - clk_base, 0, 129, &periph_w_regs, - periph_clk_enb_refcnt); + clk_base, 0, 129, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "tegra_sata_cold"); clks[sata_cold] = clk; /* dtv */ clk = tegra_clk_register_periph_gate("dtv", "clk_m", TEGRA_PERIPH_ON_APB, - clk_base, 0, 79, &periph_u_regs, - periph_clk_enb_refcnt); + clk_base, 0, 79, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "dtv"); clks[dtv] = clk; @@ -1695,7 +1607,7 @@ static void __init tegra30_periph_clk_init(void) clk_base + CLK_SOURCE_EMC, 30, 2, 0, NULL); clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, - 57, &periph_h_regs, periph_clk_enb_refcnt); + 57, periph_clk_enb_refcnt); clk_register_clkdev(clk, "emc", NULL); clks[emc] = clk; @@ -2007,6 +1919,9 @@ static void __init tegra30_clock_init(struct device_node *np) BUG(); } + if (tegra_clk_set_periph_banks(TEGRA30_CLK_PERIPH_BANKS) < 0) + return; + tegra30_osc_clk_init(); tegra30_fixed_clk_init(); tegra30_pll_init(); diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 86581ac1fd69..07f76df2583b 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -21,10 +21,114 @@ #include "clk.h" +#define CLK_OUT_ENB_L 0x010 +#define CLK_OUT_ENB_H 0x014 +#define CLK_OUT_ENB_U 0x018 +#define CLK_OUT_ENB_V 0x360 +#define CLK_OUT_ENB_W 0x364 +#define CLK_OUT_ENB_X 0x280 +#define CLK_OUT_ENB_SET_L 0x320 +#define CLK_OUT_ENB_CLR_L 0x324 +#define CLK_OUT_ENB_SET_H 0x328 +#define CLK_OUT_ENB_CLR_H 0x32c +#define CLK_OUT_ENB_SET_U 0x330 +#define CLK_OUT_ENB_CLR_U 0x334 +#define CLK_OUT_ENB_SET_V 0x440 +#define CLK_OUT_ENB_CLR_V 0x444 +#define CLK_OUT_ENB_SET_W 0x448 +#define CLK_OUT_ENB_CLR_W 0x44c +#define CLK_OUT_ENB_SET_X 0x284 +#define CLK_OUT_ENB_CLR_X 0x288 + +#define RST_DEVICES_L 0x004 +#define RST_DEVICES_H 0x008 +#define RST_DEVICES_U 0x00C +#define RST_DFLL_DVCO 0x2F4 +#define RST_DEVICES_V 0x358 +#define RST_DEVICES_W 0x35C +#define RST_DEVICES_X 0x28C +#define RST_DEVICES_SET_L 0x300 +#define RST_DEVICES_CLR_L 0x304 +#define RST_DEVICES_SET_H 0x308 +#define RST_DEVICES_CLR_H 0x30c +#define RST_DEVICES_SET_U 0x310 +#define RST_DEVICES_CLR_U 0x314 +#define RST_DEVICES_SET_V 0x430 +#define RST_DEVICES_CLR_V 0x434 +#define RST_DEVICES_SET_W 0x438 +#define RST_DEVICES_CLR_W 0x43c + /* Global data of Tegra CPU CAR ops */ static struct tegra_cpu_car_ops dummy_car_ops; struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; +static int periph_banks; + +static struct tegra_clk_periph_regs periph_regs[] = { + [0] = { + .enb_reg = CLK_OUT_ENB_L, + .enb_set_reg = CLK_OUT_ENB_SET_L, + .enb_clr_reg = CLK_OUT_ENB_CLR_L, + .rst_reg = RST_DEVICES_L, + .rst_set_reg = RST_DEVICES_SET_L, + .rst_clr_reg = RST_DEVICES_CLR_L, + }, + [1] = { + .enb_reg = CLK_OUT_ENB_H, + .enb_set_reg = CLK_OUT_ENB_SET_H, + .enb_clr_reg = CLK_OUT_ENB_CLR_H, + .rst_reg = RST_DEVICES_H, + .rst_set_reg = RST_DEVICES_SET_H, + .rst_clr_reg = RST_DEVICES_CLR_H, + }, + [2] = { + .enb_reg = CLK_OUT_ENB_U, + .enb_set_reg = CLK_OUT_ENB_SET_U, + .enb_clr_reg = CLK_OUT_ENB_CLR_U, + .rst_reg = RST_DEVICES_U, + .rst_set_reg = RST_DEVICES_SET_U, + .rst_clr_reg = RST_DEVICES_CLR_U, + }, + [3] = { + .enb_reg = CLK_OUT_ENB_V, + .enb_set_reg = CLK_OUT_ENB_SET_V, + .enb_clr_reg = CLK_OUT_ENB_CLR_V, + .rst_reg = RST_DEVICES_V, + .rst_set_reg = RST_DEVICES_SET_V, + .rst_clr_reg = RST_DEVICES_CLR_V, + }, + [4] = { + .enb_reg = CLK_OUT_ENB_W, + .enb_set_reg = CLK_OUT_ENB_SET_W, + .enb_clr_reg = CLK_OUT_ENB_CLR_W, + .rst_reg = RST_DEVICES_W, + .rst_set_reg = RST_DEVICES_SET_W, + .rst_clr_reg = RST_DEVICES_CLR_W, + }, +}; + +struct tegra_clk_periph_regs *get_reg_bank(int clkid) +{ + int reg_bank = clkid / 32; + + if (reg_bank < periph_banks) + return &periph_regs[reg_bank]; + else { + WARN_ON(1); + return NULL; + } +} + +int __init tegra_clk_set_periph_banks(int num) +{ + if (num > ARRAY_SIZE(periph_regs)) + return -EINVAL; + + periph_banks = num; + + return 0; +} + void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, struct clk *clks[], int clk_max) { diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 07cfacd91686..730d37b39488 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -400,8 +400,7 @@ void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); extern const struct clk_ops tegra_clk_periph_gate_ops; struct clk *tegra_clk_register_periph_gate(const char *name, const char *parent_name, u8 gate_flags, void __iomem *clk_base, - unsigned long flags, int clk_num, - struct tegra_clk_periph_regs *pregs, int *enable_refcnt); + unsigned long flags, int clk_num, int *enable_refcnt); /** * struct clk-periph - peripheral clock @@ -443,7 +442,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ _div_shift, _div_width, _div_frac_width, \ - _div_flags, _clk_num, _enb_refcnt, _regs, \ + _div_flags, _clk_num, _enb_refcnt, \ _gate_flags, _table) \ { \ .mux = { \ @@ -462,7 +461,6 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, .flags = _gate_flags, \ .clk_num = _clk_num, \ .enable_refcnt = _enb_refcnt, \ - .regs = _regs, \ }, \ .mux_ops = &clk_mux_ops, \ .div_ops = &tegra_clk_frac_div_ops, \ @@ -483,7 +481,7 @@ struct tegra_periph_init_data { #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, _mux_mask, _mux_flags, _div_shift, \ - _div_width, _div_frac_width, _div_flags, _regs, \ + _div_width, _div_frac_width, _div_flags, \ _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ _flags) \ { \ @@ -495,7 +493,7 @@ struct tegra_periph_init_data { _mux_flags, _div_shift, \ _div_width, _div_frac_width, \ _div_flags, _clk_num, \ - _enb_refcnt, _regs, \ + _enb_refcnt, \ _gate_flags, _table), \ .offset = _offset, \ .con_id = _con_id, \ @@ -505,12 +503,12 @@ struct tegra_periph_init_data { #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, _mux_width, _mux_flags, _div_shift, \ - _div_width, _div_frac_width, _div_flags, _regs, \ + _div_width, _div_frac_width, _div_flags, \ _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ _div_shift, _div_width, _div_frac_width, _div_flags, \ - _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ + _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ NULL, 0) /** @@ -587,6 +585,9 @@ void tegra_init_from_table(struct tegra_clk_init_table *tbl, void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, struct clk *clks[], int clk_max); +struct tegra_clk_periph_regs *get_reg_bank(int clkid); +int tegra_clk_set_periph_banks(int num); + void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); void tegra114_clock_tune_cpu_trimmers_init(void); -- cgit v1.2.3 From 343a607cb79259429afbb9820bf524d33084e66c Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 2 Sep 2013 15:22:02 +0300 Subject: clk: tegra: common periph_clk_enb_refcnt and clks This patch makes periph_clk_enb_refcnt a global array, dynamically allocated at boottime. It simplifies the macros somewhat and allows clocks common to several Tegra SoCs to be defined in a separate files. Also the clks array becomes global and dynamically allocated which allows the DT registration to be moved to a generic funcion. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-periph.c | 1 + drivers/clk/tegra/clk-tegra114.c | 57 +++++++++++----------------------------- drivers/clk/tegra/clk-tegra20.c | 36 +++++++------------------ drivers/clk/tegra/clk-tegra30.c | 39 ++++++++------------------- drivers/clk/tegra/clk.c | 44 +++++++++++++++++++++++++++---- drivers/clk/tegra/clk.h | 16 ++++++----- 6 files changed, 85 insertions(+), 108 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 735b0243261c..5102d5e58c04 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -197,6 +197,7 @@ static struct clk *_tegra_clk_register_periph(const char *name, periph->divider.reg = div ? (clk_base + offset) : NULL; periph->gate.clk_base = clk_base; periph->gate.regs = bank; + periph->gate.enable_refcnt = periph_clk_enb_refcnt; clk = clk_register(NULL, &periph->hw); if (IS_ERR(clk)) diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 8507067d5dd6..9729af823eaf 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -57,8 +57,6 @@ #define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ #define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) -#define CLK_OUT_ENB_NUM 6 - #define TEGRA114_CLK_PERIPH_BANKS 5 #define PLLC_BASE 0x80 @@ -266,8 +264,6 @@ static struct cpu_clk_suspend_context { } tegra114_cpu_clk_sctx; #endif -static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; - static void __iomem *clk_base; static void __iomem *pmc_base; @@ -712,59 +708,53 @@ static unsigned long tegra114_input_freq[] = { _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags,\ - _clk_id, _parents##_idx, 0) + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags,\ - _clk_id, _parents##_idx, flags) + _clk_num, _gate_flags, _clk_id, _parents##_idx, flags) #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags,\ - _clk_id, _parents##_idx, 0) + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, flags) + _gate_flags, _clk_id, _parents##_idx, flags) #define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, 0) + _gate_flags, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) + 0, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, periph_clk_enb_refcnt, 0, _clk_id,\ - _parents##_idx, 0) + _clk_num, 0, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ _mux_shift, _mux_mask, _clk_num, \ _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_num, _gate_flags, \ _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ @@ -772,16 +762,14 @@ static unsigned long tegra114_input_freq[] = { TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, 0) + _gate_flags, _clk_id, _parents##_idx, 0) #define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ _offset, 16, 0xE01F, 0, 0, 8, 1, \ - TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags , _clk_id, \ - mux_d_audio_clk_idx, 0) + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ + _gate_flags , _clk_id, mux_d_audio_clk_idx, 0) struct utmi_clk_param { /* Oscillator Frequency in KHz */ @@ -946,8 +934,7 @@ static const struct clk_div_table pll_re_div_table[] = { { .val = 0, .div = 0 }, }; -static struct clk *clks[TEGRA114_CLK_CLK_MAX]; -static struct clk_onecell_data clk_data; +static struct clk **clks; static unsigned long osc_freq; static unsigned long pll_ref_freq; @@ -2229,7 +2216,6 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset); static void __init tegra114_clock_init(struct device_node *np) { struct device_node *node; - int i; clk_base = of_iomap(np, 0); if (!clk_base) { @@ -2251,10 +2237,11 @@ static void __init tegra114_clock_init(struct device_node *np) return; } - if (tegra114_osc_clk_init(clk_base) < 0) + clks = tegra_clk_init(TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_PERIPH_BANKS); + if (!clks) return; - if (tegra_clk_set_periph_banks(TEGRA114_CLK_PERIPH_BANKS) < 0) + if (tegra114_osc_clk_init(clk_base) < 0) return; tegra114_fixed_clk_init(clk_base); @@ -2264,19 +2251,7 @@ static void __init tegra114_clock_init(struct device_node *np) tegra114_pmc_clk_init(pmc_base); tegra114_super_clk_init(clk_base); - for (i = 0; i < ARRAY_SIZE(clks); i++) { - if (IS_ERR(clks[i])) { - pr_err - ("Tegra114 clk %d: register failed with %ld\n", - i, PTR_ERR(clks[i])); - } - if (!clks[i]) - clks[i] = ERR_PTR(-EINVAL); - } - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + tegra_add_of_provider(np); tegra_clk_apply_init_table = tegra114_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 929a46278d83..6bf5c339ab43 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -25,8 +25,6 @@ #include "clk.h" -#define CLK_OUT_ENB_NUM 3 - #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (3<<30) #define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) @@ -170,8 +168,6 @@ static struct cpu_clk_suspend_context { } tegra20_cpu_clk_sctx; #endif -static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; - static void __iomem *clk_base; static void __iomem *pmc_base; @@ -182,21 +178,21 @@ static DEFINE_SPINLOCK(sysrate_lock); _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, periph_clk_enb_refcnt, \ + _clk_num, \ _gate_flags, _clk_id) #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_num, _gate_flags, \ _clk_id) #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_num, _gate_flags, \ _clk_id) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ @@ -204,7 +200,7 @@ static DEFINE_SPINLOCK(sysrate_lock); _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ _mux_shift, _mux_width, 0, 0, 0, 0, 0, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_num, _gate_flags, \ _clk_id) /* IDs assigned here must be in sync with DT bindings definition @@ -226,8 +222,7 @@ enum tegra20_clk { pll_x, cop, audio, pll_ref, twd, clk_max, }; -static struct clk *clks[clk_max]; -static struct clk_onecell_data clk_data; +static struct clk **clks; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { { 12000000, 600000000, 600, 12, 0, 8 }, @@ -808,7 +803,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3), TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, dvc), TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi), - TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm), + TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, pwm), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { @@ -1232,7 +1227,6 @@ static const struct of_device_id pmc_match[] __initconst = { static void __init tegra20_clock_init(struct device_node *np) { - int i; struct device_node *node; clk_base = of_iomap(np, 0); @@ -1253,7 +1247,8 @@ static void __init tegra20_clock_init(struct device_node *np) BUG(); } - if (tegra_clk_set_periph_banks(TEGRA20_CLK_PERIPH_BANKS) < 0) + clks = tegra_clk_init(clk_max, TEGRA20_CLK_PERIPH_BANKS); + if (!clks) return; tegra20_osc_clk_init(); @@ -1264,22 +1259,9 @@ static void __init tegra20_clock_init(struct device_node *np) tegra20_periph_clk_init(); tegra20_audio_clk_init(); - - for (i = 0; i < ARRAY_SIZE(clks); i++) { - if (IS_ERR(clks[i])) { - pr_err("Tegra20 clk %d: register failed with %ld\n", - i, PTR_ERR(clks[i])); - BUG(); - } - if (!clks[i]) - clks[i] = ERR_PTR(-EINVAL); - } - tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + tegra_add_of_provider(np); tegra_clk_apply_init_table = tegra20_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index a66bdabb5c5c..c5db42217ba8 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -26,8 +26,6 @@ #include "clk.h" -#define CLK_OUT_ENB_NUM 5 - #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) #define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28) @@ -236,8 +234,6 @@ static struct cpu_clk_suspend_context { } tegra30_cpu_clk_sctx; #endif -static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; - static void __iomem *clk_base; static void __iomem *pmc_base; static unsigned long input_freq; @@ -253,41 +249,41 @@ static DEFINE_SPINLOCK(sysrate_lock); _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) + _clk_num, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, periph_clk_enb_refcnt, \ + _clk_num, \ _gate_flags, _clk_id) #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) + _clk_num, _gate_flags, _clk_id) #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id) + _gate_flags, _clk_id) #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ _clk_num, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - periph_clk_enb_refcnt, 0, _clk_id) + 0, _clk_id) #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ _mux_shift, _mux_width, _clk_num, \ _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ _mux_shift, _mux_width, 0, 0, 0, 0, 0,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_num, _gate_flags, \ _clk_id) /* @@ -318,8 +314,7 @@ enum tegra30_clk { hclk, pclk, clk_out_1_mux = 300, clk_max }; -static struct clk *clks[clk_max]; -static struct clk_onecell_data clk_data; +static struct clk **clks; /* * Structure defining the fields for USB UTMI clocks Parameters. @@ -1432,7 +1427,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, extern1), TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, extern2), TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, extern3), - TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, 0, pwm), + TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, 0, pwm), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { @@ -1899,7 +1894,6 @@ static const struct of_device_id pmc_match[] __initconst = { static void __init tegra30_clock_init(struct device_node *np) { struct device_node *node; - int i; clk_base = of_iomap(np, 0); if (!clk_base) { @@ -1919,7 +1913,8 @@ static void __init tegra30_clock_init(struct device_node *np) BUG(); } - if (tegra_clk_set_periph_banks(TEGRA30_CLK_PERIPH_BANKS) < 0) + clks = tegra_clk_init(clk_max, TEGRA30_CLK_PERIPH_BANKS); + if (!clks) return; tegra30_osc_clk_init(); @@ -1930,21 +1925,9 @@ static void __init tegra30_clock_init(struct device_node *np) tegra30_audio_clk_init(); tegra30_pmc_clk_init(); - for (i = 0; i < ARRAY_SIZE(clks); i++) { - if (IS_ERR(clks[i])) { - pr_err("Tegra30 clk %d: register failed with %ld\n", - i, PTR_ERR(clks[i])); - BUG(); - } - if (!clks[i]) - clks[i] = ERR_PTR(-EINVAL); - } - tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + tegra_add_of_provider(np); tegra_clk_apply_init_table = tegra30_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 07f76df2583b..3a95a8757ebc 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -62,7 +62,11 @@ static struct tegra_cpu_car_ops dummy_car_ops; struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; +int *periph_clk_enb_refcnt; static int periph_banks; +static struct clk **clks; +static int clk_num; +static struct clk_onecell_data clk_data; static struct tegra_clk_periph_regs periph_regs[] = { [0] = { @@ -119,14 +123,25 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid) } } -int __init tegra_clk_set_periph_banks(int num) +struct clk ** __init tegra_clk_init(int num, int banks) { - if (num > ARRAY_SIZE(periph_regs)) - return -EINVAL; + if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) + return NULL; + + periph_clk_enb_refcnt = kzalloc(32 * banks * + sizeof(*periph_clk_enb_refcnt), GFP_KERNEL); + if (!periph_clk_enb_refcnt) + return NULL; - periph_banks = num; + periph_banks = banks; - return 0; + clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL); + if (!clks) + kfree(periph_clk_enb_refcnt); + + clk_num = num; + + return clks; } void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, @@ -178,6 +193,25 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, } } +void __init tegra_add_of_provider(struct device_node *np) +{ + int i; + + for (i = 0; i < clk_num; i++) { + if (IS_ERR(clks[i])) { + pr_err + ("Tegra clk %d: register failed with %ld\n", + i, PTR_ERR(clks[i])); + } + if (!clks[i]) + clks[i] = ERR_PTR(-EINVAL); + } + + clk_data.clks = clks; + clk_data.clk_num = clk_num; + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +} + tegra_clk_apply_init_table_func tegra_clk_apply_init_table; void __init tegra_clocks_apply_init_table(void) diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 730d37b39488..997357ef059e 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -37,6 +37,8 @@ struct tegra_clk_sync_source { container_of(_hw, struct tegra_clk_sync_source, hw) extern const struct clk_ops tegra_clk_sync_source_ops; +extern int *periph_clk_enb_refcnt; + struct clk *tegra_clk_register_sync_source(const char *name, unsigned long fixed_rate, unsigned long max_rate); @@ -442,7 +444,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ _div_shift, _div_width, _div_frac_width, \ - _div_flags, _clk_num, _enb_refcnt, \ + _div_flags, _clk_num,\ _gate_flags, _table) \ { \ .mux = { \ @@ -460,7 +462,6 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, .gate = { \ .flags = _gate_flags, \ .clk_num = _clk_num, \ - .enable_refcnt = _enb_refcnt, \ }, \ .mux_ops = &clk_mux_ops, \ .div_ops = &tegra_clk_frac_div_ops, \ @@ -482,7 +483,7 @@ struct tegra_periph_init_data { #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, _mux_mask, _mux_flags, _div_shift, \ _div_width, _div_frac_width, _div_flags, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ + _clk_num, _gate_flags, _clk_id, _table, \ _flags) \ { \ .name = _name, \ @@ -493,7 +494,6 @@ struct tegra_periph_init_data { _mux_flags, _div_shift, \ _div_width, _div_frac_width, \ _div_flags, _clk_num, \ - _enb_refcnt, \ _gate_flags, _table), \ .offset = _offset, \ .con_id = _con_id, \ @@ -504,11 +504,11 @@ struct tegra_periph_init_data { #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, _mux_width, _mux_flags, _div_shift, \ _div_width, _div_frac_width, _div_flags, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ _div_shift, _div_width, _div_frac_width, _div_flags, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ + _clk_num, _gate_flags, _clk_id,\ NULL, 0) /** @@ -586,7 +586,9 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, struct clk *clks[], int clk_max); struct tegra_clk_periph_regs *get_reg_bank(int clkid); -int tegra_clk_set_periph_banks(int num); +struct clk **tegra_clk_init(int num, int periph_banks); + +void tegra_add_of_provider(struct device_node *np); void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); -- cgit v1.2.3 From 5bb9d26700c3db54d5a4346c3b6621b8889f3813 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 2 Sep 2013 18:43:56 +0300 Subject: clk: tegra: Add TEGRA_PERIPH_NO_DIV flag This flag indicates the peripheral clock does not have a divider. It will simplify the initialization tables and avoids some very similar code. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-periph.c | 11 ++++++++--- drivers/clk/tegra/clk.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 5102d5e58c04..b5feccca2f1e 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -173,12 +173,16 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = { static struct clk *_tegra_clk_register_periph(const char *name, const char **parent_names, int num_parents, struct tegra_clk_periph *periph, - void __iomem *clk_base, u32 offset, bool div, + void __iomem *clk_base, u32 offset, unsigned long flags) { struct clk *clk; struct clk_init_data init; struct tegra_clk_periph_regs *bank; + bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); + + flags |= periph->gate.flags & TEGRA_PERIPH_NO_DIV ? + CLK_SET_RATE_PARENT : 0; init.name = name; init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; @@ -216,7 +220,7 @@ struct clk *tegra_clk_register_periph(const char *name, u32 offset, unsigned long flags) { return _tegra_clk_register_periph(name, parent_names, num_parents, - periph, clk_base, offset, true, flags); + periph, clk_base, offset, flags); } struct clk *tegra_clk_register_periph_nodiv(const char *name, @@ -224,6 +228,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, struct tegra_clk_periph *periph, void __iomem *clk_base, u32 offset) { + periph->gate.flags |= TEGRA_PERIPH_NO_DIV; return _tegra_clk_register_periph(name, parent_names, num_parents, - periph, clk_base, offset, false, CLK_SET_RATE_PARENT); + periph, clk_base, offset, CLK_SET_RATE_PARENT); } diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 997357ef059e..a82672084718 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -397,6 +397,7 @@ struct tegra_clk_periph_gate { #define TEGRA_PERIPH_MANUAL_RESET BIT(1) #define TEGRA_PERIPH_ON_APB BIT(2) #define TEGRA_PERIPH_WAR_1005168 BIT(3) +#define TEGRA_PERIPH_NO_DIV BIT(4) void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); extern const struct clk_ops tegra_clk_periph_gate_ops; -- cgit v1.2.3 From 04edb099a4a7e774a98b241dc016957922cbfb44 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Fri, 6 Sep 2013 14:37:37 +0300 Subject: clk: tegra: move some PLLC and PLLXC init to clk-pll.c VCO min clipping, dynamic ramp setup and IDDQ init can be done in the respective PLL clk_register functions if the parent is already registered. This is done for other some PLLs already. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-pll.c | 95 ++++++++++++++++++++++++++++++++-- drivers/clk/tegra/clk-tegra114.c | 109 +++++++-------------------------------- 2 files changed, 111 insertions(+), 93 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 25734348242f..8f51147185db 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -773,6 +773,48 @@ static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, return 1; } +static unsigned long _clip_vco_min(unsigned long vco_min, + unsigned long parent_rate) +{ + return DIV_ROUND_UP(vco_min, parent_rate) * parent_rate; +} + +static int _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, + void __iomem *clk_base, + unsigned long parent_rate) +{ + u32 val; + u32 step_a, step_b; + + switch (parent_rate) { + case 12000000: + case 13000000: + case 26000000: + step_a = 0x2B; + step_b = 0x0B; + break; + case 16800000: + step_a = 0x1A; + step_b = 0x09; + break; + case 19200000: + step_a = 0x12; + step_b = 0x08; + break; + default: + pr_err("%s: Unexpected reference rate %lu\n", + __func__, parent_rate); + WARN_ON(1); + return -EINVAL; + } + + val = step_a << pll_params->stepa_shift; + val |= step_b << pll_params->stepb_shift; + writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); + + return 0; +} + static int clk_pll_iddq_enable(struct clk_hw *hw) { struct tegra_clk_pll *pll = to_clk_pll(hw); @@ -1423,11 +1465,39 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, spinlock_t *lock) { struct tegra_clk_pll *pll; - struct clk *clk; + struct clk *clk, *parent; + unsigned long parent_rate; + int err; + u32 val, val_iddq; + + parent = __clk_lookup(parent_name); + if (IS_ERR(parent)) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } if (!pll_params->pdiv_tohw) return ERR_PTR(-EINVAL); + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate); + if (err) + return ERR_PTR(err); + + val = readl_relaxed(clk_base + pll_params->base_reg); + val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); + + if (val & PLL_BASE_ENABLE) + WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); + else { + val_iddq |= BIT(pll_params->iddq_bit_idx); + writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); + } + pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, freq_table, lock); @@ -1455,6 +1525,9 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, struct clk *clk; pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, freq_table, lock); if (IS_ERR(pll)) @@ -1498,11 +1571,23 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, spinlock_t *lock) { struct tegra_clk_pll *pll; - struct clk *clk; + struct clk *clk, *parent; + unsigned long parent_rate; if (!pll_params->pdiv_tohw) return ERR_PTR(-EINVAL); + parent = __clk_lookup(parent_name); + if (IS_ERR(parent)) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } + + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + pll_flags |= TEGRA_PLL_BYPASS; pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; pll_flags |= TEGRA_PLLM; @@ -1543,14 +1628,16 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); } + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + pll_flags |= TEGRA_PLL_BYPASS; pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, freq_table, lock); if (IS_ERR(pll)) return ERR_CAST(pll); - parent_rate = __clk_get_rate(parent); - /* * Most of PLLC register fields are shadowed, and can not be read * directly from PLL h/w. Hence, actual PLLC boot state is unknown. diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9729af823eaf..fa562e3e8f19 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1077,63 +1077,6 @@ static __init void tegra114_utmi_param_configure(void __iomem *clk_base) writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); } -static void __init _clip_vco_min(struct tegra_clk_pll_params *pll_params) -{ - pll_params->vco_min = - DIV_ROUND_UP(pll_params->vco_min, pll_ref_freq) * pll_ref_freq; -} - -static int __init _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, - void __iomem *clk_base) -{ - u32 val; - u32 step_a, step_b; - - switch (pll_ref_freq) { - case 12000000: - case 13000000: - case 26000000: - step_a = 0x2B; - step_b = 0x0B; - break; - case 16800000: - step_a = 0x1A; - step_b = 0x09; - break; - case 19200000: - step_a = 0x12; - step_b = 0x08; - break; - default: - pr_err("%s: Unexpected reference rate %lu\n", - __func__, pll_ref_freq); - WARN_ON(1); - return -EINVAL; - } - - val = step_a << pll_params->stepa_shift; - val |= step_b << pll_params->stepb_shift; - writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); - - return 0; -} - -static void __init _init_iddq(struct tegra_clk_pll_params *pll_params, - void __iomem *clk_base) -{ - u32 val, val_iddq; - - val = readl_relaxed(clk_base + pll_params->base_reg); - val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); - - if (val & BIT(30)) - WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); - else { - val_iddq |= BIT(pll_params->iddq_bit_idx); - writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); - } -} - static void __init tegra114_pll_init(void __iomem *clk_base, void __iomem *pmc) { @@ -1141,28 +1084,23 @@ static void __init tegra114_pll_init(void __iomem *clk_base, struct clk *clk; /* PLLC */ - _clip_vco_min(&pll_c_params); - if (_setup_dynamic_ramp(&pll_c_params, clk_base) >= 0) { - _init_iddq(&pll_c_params, clk_base); - clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, - pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, - pll_c_freq_table, NULL); - clk_register_clkdev(clk, "pll_c", NULL); - clks[TEGRA114_CLK_PLL_C] = clk; - - /* PLLC_OUT1 */ - clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", - clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, NULL); - clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", - clk_base + PLLC_OUT, 1, 0, - CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_c_out1", NULL); - clks[TEGRA114_CLK_PLL_C_OUT1] = clk; - } + clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, + pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, + pll_c_freq_table, NULL); + clk_register_clkdev(clk, "pll_c", NULL); + clks[TEGRA114_CLK_PLL_C] = clk; + + /* PLLC_OUT1 */ + clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", + clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", + clk_base + PLLC_OUT, 1, 0, + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_c_out1", NULL); + clks[TEGRA114_CLK_PLL_C_OUT1] = clk; /* PLLC2 */ - _clip_vco_min(&pll_c2_params); clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0, &pll_c2_params, TEGRA_PLL_USE_LOCK, pll_cx_freq_table, NULL); @@ -1170,7 +1108,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_C2] = clk; /* PLLC3 */ - _clip_vco_min(&pll_c3_params); clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0, &pll_c3_params, TEGRA_PLL_USE_LOCK, pll_cx_freq_table, NULL); @@ -1232,7 +1169,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_P_OUT4] = clk; /* PLLM */ - _clip_vco_min(&pll_m_params); clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, &pll_m_params, TEGRA_PLL_USE_LOCK, @@ -1255,15 +1191,11 @@ static void __init tegra114_pll_init(void __iomem *clk_base, CLK_SET_RATE_PARENT, 1, 1); /* PLLX */ - _clip_vco_min(&pll_x_params); - if (_setup_dynamic_ramp(&pll_x_params, clk_base) >= 0) { - _init_iddq(&pll_x_params, clk_base); - clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, - pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, - TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[TEGRA114_CLK_PLL_X] = clk; - } + clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, + pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, + TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL); + clk_register_clkdev(clk, "pll_x", NULL); + clks[TEGRA114_CLK_PLL_X] = clk; /* PLLX_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", @@ -1356,7 +1288,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_A_OUT0] = clk; /* PLLRE */ - _clip_vco_min(&pll_re_vco_params); clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK, NULL, &pll_re_lock, pll_ref_freq); -- cgit v1.2.3 From 8e9cc80aa348938078c3c1a7ab55efb3c40990e3 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 25 Nov 2013 14:44:13 +0200 Subject: clk: tegra: use pll_ref as the pll_e parent Use pll_ref instead of pll_re_vco as the pll_e parent on Tegra114. Also add a 12Mhz pll_ref table entry for pll_e for Tegra114. This prevents the system from crashing at bootup because of an unsupported pll_re_vco rate. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-pll.c | 8 +++++--- drivers/clk/tegra/clk-tegra114.c | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 8f51147185db..48f6bffc1cee 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1704,11 +1704,13 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, val_aux = pll_readl(pll_params->aux_reg, pll); if (val & PLL_BASE_ENABLE) { - if (!(val_aux & PLLE_AUX_PLLRE_SEL)) + if ((val_aux & PLLE_AUX_PLLRE_SEL) || + (val_aux & PLLE_AUX_PLLP_SEL)) WARN(1, "pll_e enabled with unsupported parent %s\n", - (val & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : "pll_ref"); + (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : + "pll_re_vco"); } else { - val_aux |= PLLE_AUX_PLLRE_SEL; + val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); pll_writel(val, pll_params->aux_reg, pll); } diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index fa562e3e8f19..e62e4764131c 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -637,6 +637,7 @@ static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { /* PLLE special case: use cpcon field to store cml divider value */ {336000000, 100000000, 100, 21, 16, 11}, {312000000, 100000000, 200, 26, 24, 13}, + {12000000, 100000000, 200, 1, 24, 13}, {0, 0, 0, 0, 0, 0}, }; @@ -1301,7 +1302,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_RE_OUT] = clk; /* PLLE */ - clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_re_vco", + clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_ref", clk_base, 0, 100000000, &pll_e_params, pll_e_freq_table, NULL); clk_register_clkdev(clk, "pll_e_out0", NULL); -- cgit v1.2.3 From ebe142b2ad35d5656caae35d5deefdbebe847d3b Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Fri, 4 Oct 2013 17:28:34 +0300 Subject: clk: tegra: move fields to tegra_clk_pll_params Move some fields related to the PLL HW description to the tegra_clk_pll_params. This allows some PLL code to be moved to common files later. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-pll.c | 138 +++++++++++++++++---------------------- drivers/clk/tegra/clk-tegra114.c | 74 ++++++++++++--------- drivers/clk/tegra/clk-tegra20.c | 44 ++++++++----- drivers/clk/tegra/clk-tegra30.c | 62 ++++++++++-------- drivers/clk/tegra/clk.h | 34 ++++------ 5 files changed, 175 insertions(+), 177 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 48f6bffc1cee..3aa85bf2f425 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -150,7 +150,7 @@ #define mask(w) ((1 << (w)) - 1) #define divm_mask(p) mask(p->params->div_nmp->divm_width) #define divn_mask(p) mask(p->params->div_nmp->divn_width) -#define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ +#define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ mask(p->params->div_nmp->divp_width)) #define divm_max(p) (divm_mask(p)) @@ -170,10 +170,10 @@ static void clk_pll_enable_lock(struct tegra_clk_pll *pll) { u32 val; - if (!(pll->flags & TEGRA_PLL_USE_LOCK)) + if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) return; - if (!(pll->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) + if (!(pll->params->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) return; val = pll_readl_misc(pll); @@ -187,13 +187,13 @@ static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) u32 val, lock_mask; void __iomem *lock_addr; - if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { + if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) { udelay(pll->params->lock_delay); return 0; } lock_addr = pll->clk_base; - if (pll->flags & TEGRA_PLL_LOCK_MISC) + if (pll->params->flags & TEGRA_PLL_LOCK_MISC) lock_addr += pll->params->misc_reg; else lock_addr += pll->params->base_reg; @@ -220,7 +220,7 @@ static int clk_pll_is_enabled(struct clk_hw *hw) struct tegra_clk_pll *pll = to_clk_pll(hw); u32 val; - if (pll->flags & TEGRA_PLLM) { + if (pll->params->flags & TEGRA_PLLM) { val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; @@ -239,12 +239,12 @@ static void _clk_pll_enable(struct clk_hw *hw) clk_pll_enable_lock(pll); val = pll_readl_base(pll); - if (pll->flags & TEGRA_PLL_BYPASS) + if (pll->params->flags & TEGRA_PLL_BYPASS) val &= ~PLL_BASE_BYPASS; val |= PLL_BASE_ENABLE; pll_writel_base(val, pll); - if (pll->flags & TEGRA_PLLM) { + if (pll->params->flags & TEGRA_PLLM) { val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); @@ -257,12 +257,12 @@ static void _clk_pll_disable(struct clk_hw *hw) u32 val; val = pll_readl_base(pll); - if (pll->flags & TEGRA_PLL_BYPASS) + if (pll->params->flags & TEGRA_PLL_BYPASS) val &= ~PLL_BASE_BYPASS; val &= ~PLL_BASE_ENABLE; pll_writel_base(val, pll); - if (pll->flags & TEGRA_PLLM) { + if (pll->params->flags & TEGRA_PLLM) { val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); @@ -342,7 +342,7 @@ static int _get_table_rate(struct clk_hw *hw, struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table *sel; - for (sel = pll->freq_table; sel->input_rate != 0; sel++) + for (sel = pll->params->freq_table; sel->input_rate != 0; sel++) if (sel->input_rate == parent_rate && sel->output_rate == rate) break; @@ -432,7 +432,7 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, struct tegra_clk_pll_params *params = pll->params; struct div_nmp *div_nmp = params->div_nmp; - if ((pll->flags & TEGRA_PLLM) && + if ((params->flags & TEGRA_PLLM) && (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { val = pll_override_readl(params->pmc_divp_reg, pll); @@ -468,7 +468,7 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, struct tegra_clk_pll_params *params = pll->params; struct div_nmp *div_nmp = params->div_nmp; - if ((pll->flags & TEGRA_PLLM) && + if ((params->flags & TEGRA_PLLM) && (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { val = pll_override_readl(params->pmc_divp_reg, pll); @@ -497,11 +497,11 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; - if (pll->flags & TEGRA_PLL_SET_LFCON) { + if (pll->params->flags & TEGRA_PLL_SET_LFCON) { val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); if (cfg->n >= PLLDU_LFCON_SET_DIVN) val |= 1 << PLL_MISC_LFCON_SHIFT; - } else if (pll->flags & TEGRA_PLL_SET_DCCON) { + } else if (pll->params->flags & TEGRA_PLL_SET_DCCON) { val &= ~(1 << PLL_MISC_DCCON_SHIFT); if (rate >= (pll->params->vco_max >> 1)) val |= 1 << PLL_MISC_DCCON_SHIFT; @@ -523,7 +523,7 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, _update_pll_mnp(pll, cfg); - if (pll->flags & TEGRA_PLL_HAS_CPCON) + if (pll->params->flags & TEGRA_PLL_HAS_CPCON) _update_pll_cpcon(pll, cfg, rate); if (state) { @@ -542,11 +542,11 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long flags = 0; int ret = 0; - if (pll->flags & TEGRA_PLL_FIXED) { - if (rate != pll->fixed_rate) { + if (pll->params->flags & TEGRA_PLL_FIXED) { + if (rate != pll->params->fixed_rate) { pr_err("%s: Can not change %s fixed rate %lu to %lu\n", __func__, __clk_get_name(hw->clk), - pll->fixed_rate, rate); + pll->params->fixed_rate, rate); return -EINVAL; } return 0; @@ -577,11 +577,11 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; - if (pll->flags & TEGRA_PLL_FIXED) - return pll->fixed_rate; + if (pll->params->flags & TEGRA_PLL_FIXED) + return pll->params->fixed_rate; /* PLLM is used for memory; we do not change rate */ - if (pll->flags & TEGRA_PLLM) + if (pll->params->flags & TEGRA_PLLM) return __clk_get_rate(hw->clk); if (_get_table_rate(hw, &cfg, rate, *prate) && @@ -604,17 +604,19 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, val = pll_readl_base(pll); - if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) + if ((pll->params->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) return parent_rate; - if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { + if ((pll->params->flags & TEGRA_PLL_FIXED) && + !(val & PLL_BASE_OVERRIDE)) { struct tegra_clk_pll_freq_table sel; - if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) { + if (_get_table_rate(hw, &sel, pll->params->fixed_rate, + parent_rate)) { pr_err("Clock %s has unknown fixed frequency\n", __clk_get_name(hw->clk)); BUG(); } - return pll->fixed_rate; + return pll->params->fixed_rate; } _get_pll_mnp(pll, &cfg); @@ -682,7 +684,7 @@ static int clk_plle_enable(struct clk_hw *hw) u32 val; int err; - if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) + if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) return -EINVAL; clk_pll_disable(hw); @@ -698,7 +700,7 @@ static int clk_plle_enable(struct clk_hw *hw) return err; } - if (pll->flags & TEGRA_PLLE_CONFIGURE) { + if (pll->params->flags & TEGRA_PLLE_CONFIGURE) { /* configure dividers */ val = pll_readl_base(pll); val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); @@ -1233,7 +1235,7 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) unsigned long flags = 0; unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); - if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) + if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) return -EINVAL; if (pll->lock) @@ -1320,9 +1322,8 @@ static void clk_plle_tegra114_disable(struct clk_hw *hw) #endif static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, - void __iomem *pmc, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) + void __iomem *pmc, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) { struct tegra_clk_pll *pll; @@ -1333,10 +1334,7 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, pll->clk_base = clk_base; pll->pmc = pmc; - pll->freq_table = freq_table; pll->params = pll_params; - pll->fixed_rate = fixed_rate; - pll->flags = pll_flags; pll->lock = lock; if (!pll_params->div_nmp) @@ -1365,17 +1363,15 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) { struct tegra_clk_pll *pll; struct clk *clk; - pll_flags |= TEGRA_PLL_BYPASS; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_BYPASS; + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1389,17 +1385,15 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) { struct tegra_clk_pll *pll; struct clk *clk; - pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1458,10 +1452,8 @@ const struct clk_ops tegra_clk_plle_tegra114_ops = { struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct tegra_clk_pll *pll; @@ -1498,9 +1490,8 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); } - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1514,22 +1505,19 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock, unsigned long parent_rate) { u32 val; struct tegra_clk_pll *pll; struct clk *clk; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1564,10 +1552,8 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct tegra_clk_pll *pll; @@ -1588,11 +1574,10 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); - pll_flags |= TEGRA_PLL_BYPASS; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll_flags |= TEGRA_PLLM; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_BYPASS; + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll_params->flags |= TEGRA_PLLM; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1606,10 +1591,8 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct clk *parent, *clk; @@ -1632,9 +1615,8 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); - pll_flags |= TEGRA_PLL_BYPASS; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_BYPASS; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1684,17 +1666,15 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, struct clk *tegra_clk_register_plle_tegra114(const char *name, const char *parent_name, void __iomem *clk_base, unsigned long flags, - unsigned long fixed_rate, struct tegra_clk_pll_params *pll_params, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct tegra_clk_pll *pll; struct clk *clk; u32 val, val_aux; - pll = _tegra_init_pll(clk_base, NULL, fixed_rate, pll_params, - TEGRA_PLL_HAS_LOCK_ENABLE, freq_table, lock); + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index e62e4764131c..8f2ab376c53d 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -334,6 +334,8 @@ static struct tegra_clk_pll_params pll_c_params = { .stepb_shift = 9, .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllcx_nmp = { @@ -381,6 +383,8 @@ static struct tegra_clk_pll_params pll_c2_params = { .ext_misc_reg[0] = 0x4f0, .ext_misc_reg[1] = 0x4f4, .ext_misc_reg[2] = 0x4f8, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_c3_params = { @@ -401,6 +405,8 @@ static struct tegra_clk_pll_params pll_c3_params = { .ext_misc_reg[0] = 0x504, .ext_misc_reg[1] = 0x508, .ext_misc_reg[2] = 0x50c, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllm_nmp = { @@ -447,6 +453,8 @@ static struct tegra_clk_pll_params pll_m_params = { .div_nmp = &pllm_nmp, .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllp_nmp = { @@ -480,6 +488,9 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .div_nmp = &pllp_nmp, + .freq_table = pll_p_freq_table, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, + .fixed_rate = 408000000, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { @@ -507,6 +518,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .div_nmp = &pllp_nmp, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { @@ -543,6 +556,9 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .div_nmp = &pllp_nmp, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_d2_params = { @@ -558,6 +574,9 @@ static struct tegra_clk_pll_params pll_d2_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .div_nmp = &pllp_nmp, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct pdiv_map pllu_p[] = { @@ -598,6 +617,9 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_delay = 1000, .pdiv_tohw = pllu_p, .div_nmp = &pllu_nmp, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { @@ -631,6 +653,8 @@ static struct tegra_clk_pll_params pll_x_params = { .stepb_shift = 24, .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { @@ -664,6 +688,9 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, .div_nmp = &plle_nmp, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLL_FIXED, + .fixed_rate = 100000000, }; static struct div_nmp pllre_nmp = { @@ -690,6 +717,7 @@ static struct tegra_clk_pll_params pll_re_vco_params = { .iddq_reg = PLLRE_MISC, .iddq_bit_idx = PLLRE_IDDQ_BIT, .div_nmp = &pllre_nmp, + .flags = TEGRA_PLL_USE_LOCK, }; /* possible OSC frequencies in Hz */ @@ -1086,8 +1114,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLC */ clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, - pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, - pll_c_freq_table, NULL); + pmc, 0, &pll_c_params, NULL); clk_register_clkdev(clk, "pll_c", NULL); clks[TEGRA114_CLK_PLL_C] = clk; @@ -1102,24 +1129,20 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_C_OUT1] = clk; /* PLLC2 */ - clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0, - &pll_c2_params, TEGRA_PLL_USE_LOCK, - pll_cx_freq_table, NULL); + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, + &pll_c2_params, NULL); clk_register_clkdev(clk, "pll_c2", NULL); clks[TEGRA114_CLK_PLL_C2] = clk; /* PLLC3 */ - clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0, - &pll_c3_params, TEGRA_PLL_USE_LOCK, - pll_cx_freq_table, NULL); + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, + &pll_c3_params, NULL); clk_register_clkdev(clk, "pll_c3", NULL); clks[TEGRA114_CLK_PLL_C3] = clk; /* PLLP */ clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0, - 408000000, &pll_p_params, - TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, - pll_p_freq_table, NULL); + &pll_p_params, NULL); clk_register_clkdev(clk, "pll_p", NULL); clks[TEGRA114_CLK_PLL_P] = clk; @@ -1171,9 +1194,8 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLM */ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, - &pll_m_params, TEGRA_PLL_USE_LOCK, - pll_m_freq_table, NULL); + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); clk_register_clkdev(clk, "pll_m", NULL); clks[TEGRA114_CLK_PLL_M] = clk; @@ -1193,8 +1215,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLX */ clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, - pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, - TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL); + pmc, CLK_IGNORE_UNUSED, &pll_x_params, NULL); clk_register_clkdev(clk, "pll_x", NULL); clks[TEGRA114_CLK_PLL_X] = clk; @@ -1210,9 +1231,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, writel(val, clk_base + pll_u_params.base_reg); clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, - 0, &pll_u_params, TEGRA_PLLU | - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, pll_u_freq_table, &pll_u_lock); + &pll_u_params, &pll_u_lock); clk_register_clkdev(clk, "pll_u", NULL); clks[TEGRA114_CLK_PLL_U] = clk; @@ -1245,9 +1264,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, - 0, &pll_d_params, - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d_lock); + &pll_d_params, &pll_d_lock); clk_register_clkdev(clk, "pll_d", NULL); clks[TEGRA114_CLK_PLL_D] = clk; @@ -1259,9 +1276,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0, - 0, &pll_d2_params, - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d2_lock); + &pll_d2_params, &pll_d2_lock); clk_register_clkdev(clk, "pll_d2", NULL); clks[TEGRA114_CLK_PLL_D2] = clk; @@ -1273,8 +1288,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLA */ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0, - 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); + &pll_a_params, NULL); clk_register_clkdev(clk, "pll_a", NULL); clks[TEGRA114_CLK_PLL_A] = clk; @@ -1290,8 +1304,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLRE */ clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, - 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK, - NULL, &pll_re_lock, pll_ref_freq); + 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); clk_register_clkdev(clk, "pll_re_vco", NULL); clks[TEGRA114_CLK_PLL_RE_VCO] = clk; @@ -1303,8 +1316,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLE */ clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_ref", - clk_base, 0, 100000000, &pll_e_params, - pll_e_freq_table, NULL); + clk_base, 0, &pll_e_params, NULL); clk_register_clkdev(clk, "pll_e_out0", NULL); clks[TEGRA114_CLK_PLL_E_OUT0] = clk; } diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 6bf5c339ab43..31547fde92e4 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -360,6 +360,8 @@ static struct tegra_clk_pll_params pll_c_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_m_params = { @@ -374,6 +376,8 @@ static struct tegra_clk_pll_params pll_m_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_p_params = { @@ -388,6 +392,9 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_p_freq_table, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON, + .fixed_rate = 216000000, }; static struct tegra_clk_pll_params pll_a_params = { @@ -402,6 +409,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_d_params = { @@ -416,6 +425,8 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct pdiv_map pllu_p[] = { @@ -437,6 +448,8 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .pdiv_tohw = pllu_p, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_x_params = { @@ -451,6 +464,8 @@ static struct tegra_clk_pll_params pll_x_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_e_params = { @@ -465,6 +480,9 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 0, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLL_FIXED, + .fixed_rate = 100000000, }; static unsigned long tegra20_clk_measure_input_freq(void) @@ -526,8 +544,7 @@ static void tegra20_pll_init(void) /* PLLC */ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0, - 0, &pll_c_params, TEGRA_PLL_HAS_CPCON, - pll_c_freq_table, NULL); + &pll_c_params, NULL); clk_register_clkdev(clk, "pll_c", NULL); clks[pll_c] = clk; @@ -543,8 +560,7 @@ static void tegra20_pll_init(void) /* PLLP */ clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, NULL, 0, - 216000000, &pll_p_params, TEGRA_PLL_FIXED | - TEGRA_PLL_HAS_CPCON, pll_p_freq_table, NULL); + &pll_p_params, NULL); clk_register_clkdev(clk, "pll_p", NULL); clks[pll_p] = clk; @@ -598,9 +614,8 @@ static void tegra20_pll_init(void) /* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, - &pll_m_params, TEGRA_PLL_HAS_CPCON, - pll_m_freq_table, NULL); + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); clk_register_clkdev(clk, "pll_m", NULL); clks[pll_m] = clk; @@ -616,22 +631,19 @@ static void tegra20_pll_init(void) /* PLLX */ clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0, - 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, - pll_x_freq_table, NULL); + &pll_x_params, NULL); clk_register_clkdev(clk, "pll_x", NULL); clks[pll_x] = clk; /* PLLU */ clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0, - 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, - pll_u_freq_table, NULL); + &pll_u_params, NULL); clk_register_clkdev(clk, "pll_u", NULL); clks[pll_u] = clk; /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0, - 0, &pll_d_params, TEGRA_PLL_HAS_CPCON, - pll_d_freq_table, NULL); + &pll_d_params, NULL); clk_register_clkdev(clk, "pll_d", NULL); clks[pll_d] = clk; @@ -643,8 +655,7 @@ static void tegra20_pll_init(void) /* PLLA */ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0, - 0, &pll_a_params, TEGRA_PLL_HAS_CPCON, - pll_a_freq_table, NULL); + &pll_a_params, NULL); clk_register_clkdev(clk, "pll_a", NULL); clks[pll_a] = clk; @@ -660,8 +671,7 @@ static void tegra20_pll_init(void) /* PLLE */ clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, - 0, 100000000, &pll_e_params, - 0, pll_e_freq_table, NULL); + 0, &pll_e_params, NULL); clk_register_clkdev(clk, "pll_e", NULL); clks[pll_e] = clk; } diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index c5db42217ba8..da540f6dc9c9 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -530,6 +530,8 @@ static struct tegra_clk_pll_params pll_c_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllm_nmp = { @@ -559,6 +561,9 @@ static struct tegra_clk_pll_params pll_m_params = { .div_nmp = &pllm_nmp, .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | + TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_p_params = { @@ -573,6 +578,9 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_p_freq_table, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, + .fixed_rate = 408000000, }; static struct tegra_clk_pll_params pll_a_params = { @@ -587,6 +595,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_d_params = { @@ -601,6 +611,10 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, + }; static struct tegra_clk_pll_params pll_d2_params = { @@ -615,6 +629,9 @@ static struct tegra_clk_pll_params pll_d2_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_u_params = { @@ -630,6 +647,8 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .pdiv_tohw = pllu_p, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON, }; static struct tegra_clk_pll_params pll_x_params = { @@ -644,6 +663,9 @@ static struct tegra_clk_pll_params pll_x_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_e_params = { @@ -658,6 +680,9 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLLE_CONFIGURE | TEGRA_PLL_FIXED, + .fixed_rate = 100000000, }; static void tegra30_clk_measure_input_freq(void) @@ -783,9 +808,7 @@ static void __init tegra30_pll_init(void) /* PLLC */ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_c_params, - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, - pll_c_freq_table, NULL); + &pll_c_params, NULL); clk_register_clkdev(clk, "pll_c", NULL); clks[pll_c] = clk; @@ -801,9 +824,7 @@ static void __init tegra30_pll_init(void) /* PLLP */ clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc_base, 0, - 408000000, &pll_p_params, - TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_USE_LOCK, pll_p_freq_table, NULL); + &pll_p_params, NULL); clk_register_clkdev(clk, "pll_p", NULL); clks[pll_p] = clk; @@ -857,10 +878,8 @@ static void __init tegra30_pll_init(void) /* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, - &pll_m_params, TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, - pll_m_freq_table, NULL); + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); clk_register_clkdev(clk, "pll_m", NULL); clks[pll_m] = clk; @@ -876,9 +895,7 @@ static void __init tegra30_pll_init(void) /* PLLX */ clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_x_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, - pll_x_freq_table, NULL); + &pll_x_params, NULL); clk_register_clkdev(clk, "pll_x", NULL); clks[pll_x] = clk; @@ -890,10 +907,7 @@ static void __init tegra30_pll_init(void) /* PLLU */ clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON, - pll_u_freq_table, - NULL); + &pll_u_params, NULL); clk_register_clkdev(clk, "pll_u", NULL); clks[pll_u] = clk; @@ -901,9 +915,7 @@ static void __init tegra30_pll_init(void) /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_d_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, - pll_d_freq_table, &pll_d_lock); + &pll_d_params, &pll_d_lock); clk_register_clkdev(clk, "pll_d", NULL); clks[pll_d] = clk; @@ -915,9 +927,7 @@ static void __init tegra30_pll_init(void) /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_d2_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, - pll_d_freq_table, NULL); + &pll_d2_params, NULL); clk_register_clkdev(clk, "pll_d2", NULL); clks[pll_d2] = clk; @@ -929,8 +939,7 @@ static void __init tegra30_pll_init(void) /* PLLA */ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc_base, - 0, 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); + 0, &pll_a_params, NULL); clk_register_clkdev(clk, "pll_a", NULL); clks[pll_a] = clk; @@ -950,8 +959,7 @@ static void __init tegra30_pll_init(void) CLK_SET_RATE_NO_REPARENT, clk_base + PLLE_AUX, 2, 1, 0, NULL); clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, - CLK_GET_RATE_NOCACHE, 100000000, &pll_e_params, - TEGRA_PLLE_CONFIGURE, pll_e_freq_table, NULL); + CLK_GET_RATE_NOCACHE, &pll_e_params, NULL); clk_register_clkdev(clk, "pll_e", NULL); clks[pll_e] = clk; } diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index a82672084718..c49df4dc5ac6 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -190,12 +190,15 @@ struct tegra_clk_pll_params { u32 ext_misc_reg[3]; u32 pmc_divnm_reg; u32 pmc_divp_reg; + u32 flags; int stepa_shift; int stepb_shift; int lock_delay; int max_p; struct pdiv_map *pdiv_tohw; struct div_nmp *div_nmp; + struct tegra_clk_pll_freq_table *freq_table; + unsigned long fixed_rate; }; /** @@ -235,10 +238,7 @@ struct tegra_clk_pll { struct clk_hw hw; void __iomem *clk_base; void __iomem *pmc; - u32 flags; - unsigned long fixed_rate; spinlock_t *lock; - struct tegra_clk_pll_freq_table *freq_table; struct tegra_clk_pll_params *params; }; @@ -260,54 +260,42 @@ extern const struct clk_ops tegra_clk_pll_ops; extern const struct clk_ops tegra_clk_plle_ops; struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock, unsigned long parent_rate); struct clk *tegra_clk_register_plle_tegra114(const char *name, const char *parent_name, void __iomem *clk_base, unsigned long flags, - unsigned long fixed_rate, struct tegra_clk_pll_params *pll_params, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); /** -- cgit v1.2.3 From a59ba9565ee20d162e858de03b9eebc0b9dbd8b6 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 2 Sep 2013 15:09:08 +0300 Subject: clk: tegra: add header for common tegra clock IDs Many clocks are common between several Tegra SoCs. Define an enum to list them so we can move them to separate files which can be shared between SoCs. Each SoC specific file will provide an array with the common clocks which are present on the SoC and their DT binding ID. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-id.h | 213 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 drivers/clk/tegra/clk-id.h (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h new file mode 100644 index 000000000000..22e2e8e67b2f --- /dev/null +++ b/drivers/clk/tegra/clk-id.h @@ -0,0 +1,213 @@ +/* + * This header provides IDs for clocks common between several Tegra SoCs + */ +#ifndef _TEGRA_CLK_ID_H +#define _TEGRA_CLK_ID_H + +enum clk_id { + tegra_clk_actmon, + tegra_clk_adx, + tegra_clk_afi, + tegra_clk_amx, + tegra_clk_apbdma, + tegra_clk_apbif, + tegra_clk_audio0, + tegra_clk_audio0_2x, + tegra_clk_audio0_mux, + tegra_clk_audio1, + tegra_clk_audio1_2x, + tegra_clk_audio1_mux, + tegra_clk_audio2, + tegra_clk_audio2_2x, + tegra_clk_audio2_mux, + tegra_clk_audio3, + tegra_clk_audio3_2x, + tegra_clk_audio3_mux, + tegra_clk_audio4, + tegra_clk_audio4_2x, + tegra_clk_audio4_mux, + tegra_clk_blink, + tegra_clk_bsea, + tegra_clk_bsev, + tegra_clk_cclk_g, + tegra_clk_cclk_lp, + tegra_clk_cilab, + tegra_clk_cilcd, + tegra_clk_cile, + tegra_clk_clk_32k, + tegra_clk_clk_m, + tegra_clk_clk_m_div2, + tegra_clk_clk_m_div4, + tegra_clk_clk_out_1, + tegra_clk_clk_out_1_mux, + tegra_clk_clk_out_2, + tegra_clk_clk_out_2_mux, + tegra_clk_clk_out_3, + tegra_clk_clk_out_3_mux, + tegra_clk_csi, + tegra_clk_csite, + tegra_clk_csus, + tegra_clk_cve, + tegra_clk_dam0, + tegra_clk_dam1, + tegra_clk_dam2, + tegra_clk_d_audio, + tegra_clk_dds, + tegra_clk_dfll_ref, + tegra_clk_dfll_soc, + tegra_clk_disp1, + tegra_clk_disp2, + tegra_clk_dp2, + tegra_clk_dsia, + tegra_clk_dsialp, + tegra_clk_dsia_mux, + tegra_clk_dsib, + tegra_clk_dsiblp, + tegra_clk_dsib_mux, + tegra_clk_dtv, + tegra_clk_emc, + tegra_clk_epp, + tegra_clk_epp_8, + tegra_clk_extern1, + tegra_clk_extern2, + tegra_clk_extern3, + tegra_clk_fuse, + tegra_clk_fuse_burn, + tegra_clk_gr2d, + tegra_clk_gr2d_8, + tegra_clk_gr3d, + tegra_clk_gr3d_8, + tegra_clk_hclk, + tegra_clk_hda, + tegra_clk_hda2codec_2x, + tegra_clk_hda2hdmi, + tegra_clk_hdmi, + tegra_clk_host1x, + tegra_clk_host1x_8, + tegra_clk_i2c1, + tegra_clk_i2c2, + tegra_clk_i2c3, + tegra_clk_i2c4, + tegra_clk_i2c5, + tegra_clk_i2cslow, + tegra_clk_i2s0, + tegra_clk_i2s0_sync, + tegra_clk_i2s1, + tegra_clk_i2s1_sync, + tegra_clk_i2s2, + tegra_clk_i2s2_sync, + tegra_clk_i2s3, + tegra_clk_i2s3_sync, + tegra_clk_i2s4, + tegra_clk_i2s4_sync, + tegra_clk_isp, + tegra_clk_kbc, + tegra_clk_kfuse, + tegra_clk_la, + tegra_clk_mipi, + tegra_clk_mipi_cal, + tegra_clk_mpe, + tegra_clk_mselect, + tegra_clk_msenc, + tegra_clk_ndflash, + tegra_clk_ndflash_8, + tegra_clk_ndspeed, + tegra_clk_ndspeed_8, + tegra_clk_nor, + tegra_clk_owr, + tegra_clk_pclk, + tegra_clk_pll_a, + tegra_clk_pll_a_out0, + tegra_clk_pll_c, + tegra_clk_pll_c2, + tegra_clk_pll_c3, + tegra_clk_pll_c_out1, + tegra_clk_pll_d, + tegra_clk_pll_d2, + tegra_clk_pll_d2_out0, + tegra_clk_pll_d_out0, + tegra_clk_pll_e_out0, + tegra_clk_pll_m, + tegra_clk_pll_m_out1, + tegra_clk_pll_p, + tegra_clk_pll_p_out1, + tegra_clk_pll_p_out2, + tegra_clk_pll_p_out2_int, + tegra_clk_pll_p_out3, + tegra_clk_pll_p_out4, + tegra_clk_pll_ref, + tegra_clk_pll_re_out, + tegra_clk_pll_re_vco, + tegra_clk_pll_u, + tegra_clk_pll_u_12m, + tegra_clk_pll_u_480m, + tegra_clk_pll_u_48m, + tegra_clk_pll_u_60m, + tegra_clk_pll_x, + tegra_clk_pll_x_out0, + tegra_clk_pwm, + tegra_clk_rtc, + tegra_clk_sata, + tegra_clk_sata_cold, + tegra_clk_sata_oob, + tegra_clk_sbc1, + tegra_clk_sbc1_8, + tegra_clk_sbc2, + tegra_clk_sbc2_8, + tegra_clk_sbc3, + tegra_clk_sbc3_8, + tegra_clk_sbc4, + tegra_clk_sbc4_8, + tegra_clk_sbc5, + tegra_clk_sbc5_8, + tegra_clk_sbc6, + tegra_clk_sbc6_8, + tegra_clk_sclk, + tegra_clk_sdmmc1, + tegra_clk_sdmmc2, + tegra_clk_sdmmc3, + tegra_clk_sdmmc4, + tegra_clk_se, + tegra_clk_soc_therm, + tegra_clk_spdif, + tegra_clk_spdif_2x, + tegra_clk_spdif_in, + tegra_clk_spdif_in_sync, + tegra_clk_spdif_mux, + tegra_clk_spdif_out, + tegra_clk_timer, + tegra_clk_trace, + tegra_clk_tsec, + tegra_clk_tsensor, + tegra_clk_tvdac, + tegra_clk_tvo, + tegra_clk_uarta, + tegra_clk_uartb, + tegra_clk_uartc, + tegra_clk_uartd, + tegra_clk_uarte, + tegra_clk_usb2, + tegra_clk_usb3, + tegra_clk_usbd, + tegra_clk_vcp, + tegra_clk_vde, + tegra_clk_vde_8, + tegra_clk_vfir, + tegra_clk_vi, + tegra_clk_vi_8, + tegra_clk_vimclk_sync, + tegra_clk_vi_sensor, + tegra_clk_vi_sensor_8, + tegra_clk_xusb_dev, + tegra_clk_xusb_dev_src, + tegra_clk_xusb_falcon_src, + tegra_clk_xusb_fs_src, + tegra_clk_xusb_host, + tegra_clk_xusb_host_src, + tegra_clk_xusb_hs_src, + tegra_clk_xusb_ss, + tegra_clk_xusb_ss_src, + tegra_clk_max, +}; + +#endif /* _TEGRA_CLK_ID_H */ -- cgit v1.2.3 From b8700d506ac4050fd96ce9305df04df811365326 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 14 Oct 2013 16:47:37 +0300 Subject: clk: tegra: add common infra for DT clocks Introduce a common infrastructure for sharing clock initialization between SoCs. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk.c | 9 +++++++++ drivers/clk/tegra/clk.h | 7 +++++++ 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 3a95a8757ebc..a0430cd65d7c 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -212,6 +212,15 @@ void __init tegra_add_of_provider(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); } +struct clk ** __init tegra_lookup_dt_id(int clk_id, + struct tegra_clk *tegra_clk) +{ + if (tegra_clk[clk_id].present) + return &clks[tegra_clk[clk_id].dt_id]; + else + return NULL; +} + tegra_clk_apply_init_table_func tegra_clk_apply_init_table; void __init tegra_clocks_apply_init_table(void) diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index c49df4dc5ac6..489dad59d1d5 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -568,6 +568,11 @@ struct tegra_clk_duplicate { }, \ } +struct tegra_clk { + int dt_id; + bool present; +}; + void tegra_init_from_table(struct tegra_clk_init_table *tbl, struct clk *clks[], int clk_max); @@ -577,6 +582,8 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, struct tegra_clk_periph_regs *get_reg_bank(int clkid); struct clk **tegra_clk_init(int num, int periph_banks); +struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); + void tegra_add_of_provider(struct device_node *np); void tegra114_clock_tune_cpu_trimmers_high(void); -- cgit v1.2.3 From 73d37e4c7c4b9db26c9e4e1479e00996caa8e3f2 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Wed, 9 Oct 2013 14:47:57 +0300 Subject: clk: tegra: add clkdev registration infra Add a common infra for registering clkdev. This allows decoupling clk registration from clkdev registration. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra114.c | 322 ++++++++++++++++++++------------------- drivers/clk/tegra/clk.c | 9 ++ drivers/clk/tegra/clk.h | 7 + 3 files changed, 179 insertions(+), 159 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 8f2ab376c53d..48d4381357bb 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -733,69 +733,69 @@ static unsigned long tegra114_input_freq[] = { #define MASK(x) (BIT(x) - 1) -#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) -#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ +#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _parents, _offset,\ _clk_num, _gate_flags, _clk_id, flags)\ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ _clk_num, _gate_flags, _clk_id, _parents##_idx, flags) -#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_MUX8(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) -#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ +#define TEGRA_INIT_DATA_INT_FLAGS(_name, _parents, _offset,\ _clk_num, _gate_flags, _clk_id, flags)\ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ _gate_flags, _clk_id, _parents##_idx, flags) -#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ +#define TEGRA_INIT_DATA_INT8(_name, _parents, _offset,\ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ _gate_flags, _clk_id, _parents##_idx, 0) -#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ +#define TEGRA_INIT_DATA_UART(_name, _parents, _offset,\ _clk_num, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 0, _clk_id, _parents##_idx, 0) -#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ +#define TEGRA_INIT_DATA_I2C(_name, _parents, _offset,\ _clk_num, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ _clk_num, 0, _clk_id, _parents##_idx, 0) -#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ _mux_shift, _mux_mask, _clk_num, \ _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ _clk_num, _gate_flags, \ _clk_id, _parents##_idx, 0) -#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_XUSB(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ _gate_flags, _clk_id, _parents##_idx, 0) -#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ +#define TEGRA_INIT_DATA_AUDIO(_name, _offset, _clk_num,\ _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, mux_d_audio_clk, \ _offset, 16, 0xE01F, 0, 0, 8, 1, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ _gate_flags , _clk_id, mux_d_audio_clk_idx, 0) @@ -963,6 +963,71 @@ static const struct clk_div_table pll_re_div_table[] = { { .val = 0, .div = 0 }, }; +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "clk_m", .dt_id = TEGRA114_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA114_CLK_PLL_REF }, + { .con_id = "clk_32k", .dt_id = TEGRA114_CLK_CLK_32K }, + { .con_id = "clk_m_div2", .dt_id = TEGRA114_CLK_CLK_M_DIV2 }, + { .con_id = "clk_m_div4", .dt_id = TEGRA114_CLK_CLK_M_DIV4 }, + { .con_id = "pll_c", .dt_id = TEGRA114_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA114_CLK_PLL_C_OUT1 }, + { .con_id = "pll_c2", .dt_id = TEGRA114_CLK_PLL_C2 }, + { .con_id = "pll_c3", .dt_id = TEGRA114_CLK_PLL_C3 }, + { .con_id = "pll_p", .dt_id = TEGRA114_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA114_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA114_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA114_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA114_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA114_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA114_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA114_CLK_PLL_X }, + { .con_id = "pll_x_out0", .dt_id = TEGRA114_CLK_PLL_X_OUT0 }, + { .con_id = "pll_u", .dt_id = TEGRA114_CLK_PLL_U }, + { .con_id = "pll_u_480M", .dt_id = TEGRA114_CLK_PLL_U_480M }, + { .con_id = "pll_u_60M", .dt_id = TEGRA114_CLK_PLL_U_60M }, + { .con_id = "pll_u_48M", .dt_id = TEGRA114_CLK_PLL_U_48M }, + { .con_id = "pll_u_12M", .dt_id = TEGRA114_CLK_PLL_U_12M }, + { .con_id = "pll_d", .dt_id = TEGRA114_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA114_CLK_PLL_D_OUT0 }, + { .con_id = "pll_d2", .dt_id = TEGRA114_CLK_PLL_D2 }, + { .con_id = "pll_d2_out0", .dt_id = TEGRA114_CLK_PLL_D2_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA114_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA114_CLK_PLL_A_OUT0 }, + { .con_id = "pll_re_vco", .dt_id = TEGRA114_CLK_PLL_RE_VCO }, + { .con_id = "pll_re_out", .dt_id = TEGRA114_CLK_PLL_RE_OUT }, + { .con_id = "pll_e_out0", .dt_id = TEGRA114_CLK_PLL_E_OUT0 }, + { .con_id = "spdif_in_sync", .dt_id = TEGRA114_CLK_SPDIF_IN_SYNC }, + { .con_id = "i2s0_sync", .dt_id = TEGRA114_CLK_I2S0_SYNC }, + { .con_id = "i2s1_sync", .dt_id = TEGRA114_CLK_I2S1_SYNC }, + { .con_id = "i2s2_sync", .dt_id = TEGRA114_CLK_I2S2_SYNC }, + { .con_id = "i2s3_sync", .dt_id = TEGRA114_CLK_I2S3_SYNC }, + { .con_id = "i2s4_sync", .dt_id = TEGRA114_CLK_I2S4_SYNC }, + { .con_id = "vimclk_sync", .dt_id = TEGRA114_CLK_VIMCLK_SYNC }, + { .con_id = "audio0", .dt_id = TEGRA114_CLK_AUDIO0 }, + { .con_id = "audio1", .dt_id = TEGRA114_CLK_AUDIO1 }, + { .con_id = "audio2", .dt_id = TEGRA114_CLK_AUDIO2 }, + { .con_id = "audio3", .dt_id = TEGRA114_CLK_AUDIO3 }, + { .con_id = "audio4", .dt_id = TEGRA114_CLK_AUDIO4 }, + { .con_id = "spdif", .dt_id = TEGRA114_CLK_SPDIF }, + { .con_id = "audio0_2x", .dt_id = TEGRA114_CLK_AUDIO0_2X }, + { .con_id = "audio1_2x", .dt_id = TEGRA114_CLK_AUDIO1_2X }, + { .con_id = "audio2_2x", .dt_id = TEGRA114_CLK_AUDIO2_2X }, + { .con_id = "audio3_2x", .dt_id = TEGRA114_CLK_AUDIO3_2X }, + { .con_id = "audio4_2x", .dt_id = TEGRA114_CLK_AUDIO4_2X }, + { .con_id = "spdif_2x", .dt_id = TEGRA114_CLK_SPDIF_2X }, + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA114_CLK_EXTERN1 }, + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA114_CLK_EXTERN2 }, + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA114_CLK_EXTERN3 }, + { .con_id = "blink", .dt_id = TEGRA114_CLK_BLINK }, + { .con_id = "cclk_g", .dt_id = TEGRA114_CLK_CCLK_G }, + { .con_id = "cclk_lp", .dt_id = TEGRA114_CLK_CCLK_LP }, + { .con_id = "sclk", .dt_id = TEGRA114_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA114_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA114_CLK_PCLK }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA114_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA114_CLK_TIMER }, +}; + static struct clk **clks; static unsigned long osc_freq; @@ -984,7 +1049,6 @@ static int __init tegra114_osc_clk_init(void __iomem *clk_base) /* clk_m */ clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, osc_freq); - clk_register_clkdev(clk, "clk_m", NULL); clks[TEGRA114_CLK_CLK_M] = clk; /* pll_ref */ @@ -992,7 +1056,6 @@ static int __init tegra114_osc_clk_init(void __iomem *clk_base) pll_ref_div = 1 << val; clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", CLK_SET_RATE_PARENT, 1, pll_ref_div); - clk_register_clkdev(clk, "pll_ref", NULL); clks[TEGRA114_CLK_PLL_REF] = clk; pll_ref_freq = osc_freq / pll_ref_div; @@ -1007,19 +1070,16 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) /* clk_32k */ clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, 32768); - clk_register_clkdev(clk, "clk_32k", NULL); clks[TEGRA114_CLK_CLK_32K] = clk; /* clk_m_div2 */ clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "clk_m_div2", NULL); clks[TEGRA114_CLK_CLK_M_DIV2] = clk; /* clk_m_div4 */ clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", CLK_SET_RATE_PARENT, 1, 4); - clk_register_clkdev(clk, "clk_m_div4", NULL); clks[TEGRA114_CLK_CLK_M_DIV4] = clk; } @@ -1115,7 +1175,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLC */ clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, pmc, 0, &pll_c_params, NULL); - clk_register_clkdev(clk, "pll_c", NULL); clks[TEGRA114_CLK_PLL_C] = clk; /* PLLC_OUT1 */ @@ -1125,25 +1184,21 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_c_out1", NULL); clks[TEGRA114_CLK_PLL_C_OUT1] = clk; /* PLLC2 */ clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, &pll_c2_params, NULL); - clk_register_clkdev(clk, "pll_c2", NULL); clks[TEGRA114_CLK_PLL_C2] = clk; /* PLLC3 */ clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, &pll_c3_params, NULL); - clk_register_clkdev(clk, "pll_c3", NULL); clks[TEGRA114_CLK_PLL_C3] = clk; /* PLLP */ clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0, &pll_p_params, NULL); - clk_register_clkdev(clk, "pll_p", NULL); clks[TEGRA114_CLK_PLL_P] = clk; /* PLLP_OUT1 */ @@ -1154,7 +1209,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk_base + PLLP_OUTA, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out1", NULL); clks[TEGRA114_CLK_PLL_P_OUT1] = clk; /* PLLP_OUT2 */ @@ -1166,7 +1220,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk_base + PLLP_OUTA, 17, 16, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out2", NULL); clks[TEGRA114_CLK_PLL_P_OUT2] = clk; /* PLLP_OUT3 */ @@ -1177,7 +1230,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk_base + PLLP_OUTB, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out3", NULL); clks[TEGRA114_CLK_PLL_P_OUT3] = clk; /* PLLP_OUT4 */ @@ -1189,14 +1241,12 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk_base + PLLP_OUTB, 17, 16, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out4", NULL); clks[TEGRA114_CLK_PLL_P_OUT4] = clk; /* PLLM */ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, &pll_m_params, NULL); - clk_register_clkdev(clk, "pll_m", NULL); clks[TEGRA114_CLK_PLL_M] = clk; /* PLLM_OUT1 */ @@ -1206,7 +1256,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_m_out1", NULL); clks[TEGRA114_CLK_PLL_M_OUT1] = clk; /* PLLM_UD */ @@ -1216,13 +1265,11 @@ static void __init tegra114_pll_init(void __iomem *clk_base, /* PLLX */ clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, pmc, CLK_IGNORE_UNUSED, &pll_x_params, NULL); - clk_register_clkdev(clk, "pll_x", NULL); clks[TEGRA114_CLK_PLL_X] = clk; /* PLLX_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_x_out0", NULL); clks[TEGRA114_CLK_PLL_X_OUT0] = clk; /* PLLU */ @@ -1232,7 +1279,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, &pll_u_params, &pll_u_lock); - clk_register_clkdev(clk, "pll_u", NULL); clks[TEGRA114_CLK_PLL_U] = clk; tegra114_utmi_param_configure(clk_base); @@ -1241,55 +1287,46 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, 22, 0, &pll_u_lock); - clk_register_clkdev(clk, "pll_u_480M", NULL); clks[TEGRA114_CLK_PLL_U_480M] = clk; /* PLLU_60M */ clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", CLK_SET_RATE_PARENT, 1, 8); - clk_register_clkdev(clk, "pll_u_60M", NULL); clks[TEGRA114_CLK_PLL_U_60M] = clk; /* PLLU_48M */ clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", CLK_SET_RATE_PARENT, 1, 10); - clk_register_clkdev(clk, "pll_u_48M", NULL); clks[TEGRA114_CLK_PLL_U_48M] = clk; /* PLLU_12M */ clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", CLK_SET_RATE_PARENT, 1, 40); - clk_register_clkdev(clk, "pll_u_12M", NULL); clks[TEGRA114_CLK_PLL_U_12M] = clk; /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, &pll_d_params, &pll_d_lock); - clk_register_clkdev(clk, "pll_d", NULL); clks[TEGRA114_CLK_PLL_D] = clk; /* PLLD_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d_out0", NULL); clks[TEGRA114_CLK_PLL_D_OUT0] = clk; /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0, &pll_d2_params, &pll_d2_lock); - clk_register_clkdev(clk, "pll_d2", NULL); clks[TEGRA114_CLK_PLL_D2] = clk; /* PLLD2_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d2_out0", NULL); clks[TEGRA114_CLK_PLL_D2_OUT0] = clk; /* PLLA */ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0, &pll_a_params, NULL); - clk_register_clkdev(clk, "pll_a", NULL); clks[TEGRA114_CLK_PLL_A] = clk; /* PLLA_OUT0 */ @@ -1299,25 +1336,21 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_a_out0", NULL); clks[TEGRA114_CLK_PLL_A_OUT0] = clk; /* PLLRE */ clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); - clk_register_clkdev(clk, "pll_re_vco", NULL); clks[TEGRA114_CLK_PLL_RE_VCO] = clk; clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, clk_base + PLLRE_BASE, 16, 4, 0, pll_re_div_table, &pll_re_lock); - clk_register_clkdev(clk, "pll_re_out", NULL); clks[TEGRA114_CLK_PLL_RE_OUT] = clk; /* PLLE */ clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_ref", clk_base, 0, &pll_e_params, NULL); - clk_register_clkdev(clk, "pll_e_out0", NULL); clks[TEGRA114_CLK_PLL_E_OUT0] = clk; } @@ -1344,37 +1377,30 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) /* spdif_in_sync */ clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, 24000000); - clk_register_clkdev(clk, "spdif_in_sync", NULL); clks[TEGRA114_CLK_SPDIF_IN_SYNC] = clk; /* i2s0_sync */ clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s0_sync", NULL); clks[TEGRA114_CLK_I2S0_SYNC] = clk; /* i2s1_sync */ clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s1_sync", NULL); clks[TEGRA114_CLK_I2S1_SYNC] = clk; /* i2s2_sync */ clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s2_sync", NULL); clks[TEGRA114_CLK_I2S2_SYNC] = clk; /* i2s3_sync */ clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s3_sync", NULL); clks[TEGRA114_CLK_I2S3_SYNC] = clk; /* i2s4_sync */ clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s4_sync", NULL); clks[TEGRA114_CLK_I2S4_SYNC] = clk; /* vimclk_sync */ clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); - clk_register_clkdev(clk, "vimclk_sync", NULL); clks[TEGRA114_CLK_VIMCLK_SYNC] = clk; /* audio0 */ @@ -1387,7 +1413,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S0, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio0", NULL); clks[TEGRA114_CLK_AUDIO0] = clk; /* audio1 */ @@ -1400,7 +1425,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S1, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio1", NULL); clks[TEGRA114_CLK_AUDIO1] = clk; /* audio2 */ @@ -1413,7 +1437,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S2, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio2", NULL); clks[TEGRA114_CLK_AUDIO2] = clk; /* audio3 */ @@ -1426,7 +1449,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S3, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio3", NULL); clks[TEGRA114_CLK_AUDIO3] = clk; /* audio4 */ @@ -1439,7 +1461,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, clk_base + AUDIO_SYNC_CLK_I2S4, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio4", NULL); clks[TEGRA114_CLK_AUDIO4] = clk; /* spdif */ @@ -1452,7 +1473,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, clk_base + AUDIO_SYNC_CLK_SPDIF, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "spdif", NULL); clks[TEGRA114_CLK_SPDIF] = clk; /* audio0_2x */ @@ -1465,7 +1485,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 113, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio0_2x", NULL); clks[TEGRA114_CLK_AUDIO0_2X] = clk; /* audio1_2x */ @@ -1478,7 +1497,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 114, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio1_2x", NULL); clks[TEGRA114_CLK_AUDIO1_2X] = clk; /* audio2_2x */ @@ -1491,7 +1509,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 115, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio2_2x", NULL); clks[TEGRA114_CLK_AUDIO2_2X] = clk; /* audio3_2x */ @@ -1504,7 +1521,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 116, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio3_2x", NULL); clks[TEGRA114_CLK_AUDIO3_2X] = clk; /* audio4_2x */ @@ -1517,7 +1533,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 117, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio4_2x", NULL); clks[TEGRA114_CLK_AUDIO4_2X] = clk; /* spdif_2x */ @@ -1530,7 +1545,6 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base) TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 118, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "spdif_2x", NULL); clks[TEGRA114_CLK_SPDIF_2X] = clk; } @@ -1548,7 +1562,6 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, &clk_out_lock); - clk_register_clkdev(clk, "extern1", "clk_out_1"); clks[TEGRA114_CLK_CLK_OUT_1] = clk; /* clk_out_2 */ @@ -1561,7 +1574,6 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, &clk_out_lock); - clk_register_clkdev(clk, "extern2", "clk_out_2"); clks[TEGRA114_CLK_CLK_OUT_2] = clk; /* clk_out_3 */ @@ -1574,7 +1586,6 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, &clk_out_lock); - clk_register_clkdev(clk, "extern3", "clk_out_3"); clks[TEGRA114_CLK_CLK_OUT_3] = clk; /* blink */ @@ -1586,7 +1597,6 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) clk = clk_register_gate(NULL, "blink", "blink_override", 0, pmc_base + PMC_CTRL, PMC_CTRL_BLINK_ENB, 0, NULL); - clk_register_clkdev(clk, "blink", NULL); clks[TEGRA114_CLK_BLINK] = clk; } @@ -1613,7 +1623,6 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, clk_base + CCLKG_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "cclk_g", NULL); clks[TEGRA114_CLK_CCLK_G] = clk; /* CCLKLP */ @@ -1622,7 +1631,6 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, clk_base + CCLKLP_BURST_POLICY, 0, 4, 8, 9, NULL); - clk_register_clkdev(clk, "cclk_lp", NULL); clks[TEGRA114_CLK_CCLK_LP] = clk; /* SCLK */ @@ -1631,7 +1639,6 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) CLK_SET_RATE_PARENT, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "sclk", NULL); clks[TEGRA114_CLK_SCLK] = clk; /* HCLK */ @@ -1641,7 +1648,6 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "hclk", NULL); clks[TEGRA114_CLK_HCLK] = clk; /* PCLK */ @@ -1651,91 +1657,90 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "pclk", NULL); clks[TEGRA114_CLK_PCLK] = clk; } static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S0), - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S2), - TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S3), - TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S4), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_OUT), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_IN), - TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_PWM), - TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_ADX), - TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_AMX), - TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA), - TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA2CODEC_2X), - TEGRA_INIT_DATA_MUX8("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), - TEGRA_INIT_DATA_MUX8("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), - TEGRA_INIT_DATA_MUX8("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), - TEGRA_INIT_DATA_MUX8("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), - TEGRA_INIT_DATA_MUX8("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), - TEGRA_INIT_DATA_MUX8("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), - TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), - TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_VFIR), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, TEGRA114_CLK_SDMMC1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, TEGRA114_CLK_SDMMC2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, TEGRA114_CLK_SDMMC3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, TEGRA114_CLK_SDMMC4), - TEGRA_INIT_DATA_INT8("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, TEGRA114_CLK_VDE), - TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_CSITE, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_LA), - TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TRACE), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_OWR), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, TEGRA114_CLK_NOR), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_MIPI), - TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, TEGRA114_CLK_I2C1), - TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, TEGRA114_CLK_I2C2), - TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, TEGRA114_CLK_I2C3), - TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, TEGRA114_CLK_I2C4), - TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, TEGRA114_CLK_I2C5), - TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, TEGRA114_CLK_UARTA), - TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, TEGRA114_CLK_UARTB), - TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, TEGRA114_CLK_UARTC), - TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, TEGRA114_CLK_UARTD), - TEGRA_INIT_DATA_INT8("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, TEGRA114_CLK_GR3D), - TEGRA_INIT_DATA_INT8("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, TEGRA114_CLK_GR2D), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), - TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, TEGRA114_CLK_VI), - TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, TEGRA114_CLK_EPP), - TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, TEGRA114_CLK_MSENC), - TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, TEGRA114_CLK_TSEC), - TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, TEGRA114_CLK_HOST1X), - TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA114_CLK_HDMI), - TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, TEGRA114_CLK_CILAB), - TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, TEGRA114_CLK_CILCD), - TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, TEGRA114_CLK_CILE), - TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, 0, TEGRA114_CLK_DSIALP), - TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, 0, TEGRA114_CLK_DSIBLP), - TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TSENSOR), - TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, 0, TEGRA114_CLK_ACTMON), - TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, TEGRA114_CLK_EXTERN1), - TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, TEGRA114_CLK_EXTERN2), - TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, TEGRA114_CLK_EXTERN3), - TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2CSLOW), - TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SE), - TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, TEGRA114_CLK_MSELECT, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_REF), - TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_SOC), - TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SOC_THERM), - TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_HOST_SRC), - TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FALCON_SRC), - TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FS_SRC), - TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_SS_SRC), - TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_DEV_SRC), - TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_D_AUDIO), - TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM0), - TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM1), - TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM2), + TEGRA_INIT_DATA_MUX("i2s0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S0), + TEGRA_INIT_DATA_MUX("i2s1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S1), + TEGRA_INIT_DATA_MUX("i2s2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S2), + TEGRA_INIT_DATA_MUX("i2s3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S3), + TEGRA_INIT_DATA_MUX("i2s4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S4), + TEGRA_INIT_DATA_MUX("spdif_out", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_OUT), + TEGRA_INIT_DATA_MUX("spdif_in", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_IN), + TEGRA_INIT_DATA_MUX("pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_PWM), + TEGRA_INIT_DATA_MUX("adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_ADX), + TEGRA_INIT_DATA_MUX("amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_AMX), + TEGRA_INIT_DATA_MUX("hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA), + TEGRA_INIT_DATA_MUX("hda2codec_2x", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA2CODEC_2X), + TEGRA_INIT_DATA_MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), + TEGRA_INIT_DATA_MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), + TEGRA_INIT_DATA_MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), + TEGRA_INIT_DATA_MUX8("sbc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), + TEGRA_INIT_DATA_MUX8("sbc5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), + TEGRA_INIT_DATA_MUX8("sbc6", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), + TEGRA_INIT_DATA_MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), + TEGRA_INIT_DATA_MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), + TEGRA_INIT_DATA_MUX("vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_VFIR), + TEGRA_INIT_DATA_MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, TEGRA114_CLK_SDMMC1), + TEGRA_INIT_DATA_MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, TEGRA114_CLK_SDMMC2), + TEGRA_INIT_DATA_MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, TEGRA114_CLK_SDMMC3), + TEGRA_INIT_DATA_MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, TEGRA114_CLK_SDMMC4), + TEGRA_INIT_DATA_INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, TEGRA114_CLK_VDE), + TEGRA_INIT_DATA_MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_CSITE, CLK_IGNORE_UNUSED), + TEGRA_INIT_DATA_MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_LA), + TEGRA_INIT_DATA_MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TRACE), + TEGRA_INIT_DATA_MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_OWR), + TEGRA_INIT_DATA_MUX("nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, TEGRA114_CLK_NOR), + TEGRA_INIT_DATA_MUX("mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_MIPI), + TEGRA_INIT_DATA_I2C("i2c1", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, TEGRA114_CLK_I2C1), + TEGRA_INIT_DATA_I2C("i2c2", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, TEGRA114_CLK_I2C2), + TEGRA_INIT_DATA_I2C("i2c3", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, TEGRA114_CLK_I2C3), + TEGRA_INIT_DATA_I2C("i2c4", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, TEGRA114_CLK_I2C4), + TEGRA_INIT_DATA_I2C("i2c5", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, TEGRA114_CLK_I2C5), + TEGRA_INIT_DATA_UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, TEGRA114_CLK_UARTA), + TEGRA_INIT_DATA_UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, TEGRA114_CLK_UARTB), + TEGRA_INIT_DATA_UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, TEGRA114_CLK_UARTC), + TEGRA_INIT_DATA_UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, TEGRA114_CLK_UARTD), + TEGRA_INIT_DATA_INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, TEGRA114_CLK_GR3D), + TEGRA_INIT_DATA_INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, TEGRA114_CLK_GR2D), + TEGRA_INIT_DATA_MUX("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), + TEGRA_INIT_DATA_INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, TEGRA114_CLK_VI), + TEGRA_INIT_DATA_INT8("epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, TEGRA114_CLK_EPP), + TEGRA_INIT_DATA_INT8("msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, TEGRA114_CLK_MSENC), + TEGRA_INIT_DATA_INT8("tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, TEGRA114_CLK_TSEC), + TEGRA_INIT_DATA_INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, TEGRA114_CLK_HOST1X), + TEGRA_INIT_DATA_MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA114_CLK_HDMI), + TEGRA_INIT_DATA_MUX("cilab", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, TEGRA114_CLK_CILAB), + TEGRA_INIT_DATA_MUX("cilcd", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, TEGRA114_CLK_CILCD), + TEGRA_INIT_DATA_MUX("cile", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, TEGRA114_CLK_CILE), + TEGRA_INIT_DATA_MUX("dsialp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, 0, TEGRA114_CLK_DSIALP), + TEGRA_INIT_DATA_MUX("dsiblp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, 0, TEGRA114_CLK_DSIBLP), + TEGRA_INIT_DATA_MUX("tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TSENSOR), + TEGRA_INIT_DATA_MUX("actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, 0, TEGRA114_CLK_ACTMON), + TEGRA_INIT_DATA_MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, TEGRA114_CLK_EXTERN1), + TEGRA_INIT_DATA_MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, TEGRA114_CLK_EXTERN2), + TEGRA_INIT_DATA_MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, TEGRA114_CLK_EXTERN3), + TEGRA_INIT_DATA_MUX("i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2CSLOW), + TEGRA_INIT_DATA_INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SE), + TEGRA_INIT_DATA_INT_FLAGS("mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, TEGRA114_CLK_MSELECT, CLK_IGNORE_UNUSED), + TEGRA_INIT_DATA_MUX("dfll_ref", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_REF), + TEGRA_INIT_DATA_MUX("dfll_soc", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_SOC), + TEGRA_INIT_DATA_MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SOC_THERM), + TEGRA_INIT_DATA_XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_HOST_SRC), + TEGRA_INIT_DATA_XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FALCON_SRC), + TEGRA_INIT_DATA_XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FS_SRC), + TEGRA_INIT_DATA_XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_SS_SRC), + TEGRA_INIT_DATA_XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_DEV_SRC), + TEGRA_INIT_DATA_AUDIO("d_audio", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_D_AUDIO), + TEGRA_INIT_DATA_AUDIO("dam0", CLK_SOURCE_DAM0, 108, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM0), + TEGRA_INIT_DATA_AUDIO("dam1", CLK_SOURCE_DAM1, 109, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM1), + TEGRA_INIT_DATA_AUDIO("dam2", CLK_SOURCE_DAM2, 110, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM2), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, TEGRA114_CLK_DISP1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, TEGRA114_CLK_DISP2), + TEGRA_INIT_DATA_NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, TEGRA114_CLK_DISP1), + TEGRA_INIT_DATA_NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, TEGRA114_CLK_DISP2), }; static __init void tegra114_periph_clk_init(void __iomem *clk_base) @@ -1755,7 +1760,6 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, clk_base, 0, 4, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "rtc-tegra"); clks[TEGRA114_CLK_RTC] = clk; /* kbc */ @@ -1768,7 +1772,6 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base) /* timer */ clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0, 5, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "timer"); clks[TEGRA114_CLK_TIMER] = clk; /* kfuse */ @@ -2196,6 +2199,7 @@ static void __init tegra114_clock_init(struct device_node *np) tegra114_super_clk_init(clk_base); tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra114_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index a0430cd65d7c..14d25322aec5 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -212,6 +212,15 @@ void __init tegra_add_of_provider(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); } +void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) +{ + int i; + + for (i = 0; i < num; i++, dev_clks++) + clk_register_clkdev(clks[dev_clks->dt_id], dev_clks->con_id, + dev_clks->dev_id); +} + struct clk ** __init tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk) { diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 489dad59d1d5..f742c7dda4cc 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -573,6 +573,12 @@ struct tegra_clk { bool present; }; +struct tegra_devclk { + int dt_id; + char *dev_id; + char *con_id; +}; + void tegra_init_from_table(struct tegra_clk_init_table *tbl, struct clk *clks[], int clk_max); @@ -585,6 +591,7 @@ struct clk **tegra_clk_init(int num, int periph_banks); struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); void tegra_add_of_provider(struct device_node *np); +void tegra_register_devclks(struct tegra_devclk *dev_clks, int num); void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); -- cgit v1.2.3 From 6609dbe40e199ca8b1e99513d0e4bbc32b0d53b7 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Tue, 17 Sep 2013 15:42:24 +0300 Subject: clk: tegra: move audio clk to common file Move audio clocks and PLLA initialization to a common file so it can be used by multiple Tegra SoCs. Also a new array tegra114_clks is introduced for Tegra114 which specifies which common clocks are available on Tegra114 and what their DT IDs are. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/Makefile | 1 + drivers/clk/tegra/clk-tegra-audio.c | 215 ++++++++++++++++++++ drivers/clk/tegra/clk-tegra114.c | 390 +++++++++++++++++------------------- drivers/clk/tegra/clk.h | 4 + 4 files changed, 402 insertions(+), 208 deletions(-) create mode 100644 drivers/clk/tegra/clk-tegra-audio.c (limited to 'drivers') diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index f49fac2d193a..796ff9aa3899 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -6,6 +6,7 @@ obj-y += clk-periph-gate.o obj-y += clk-pll.o obj-y += clk-pll-out.o obj-y += clk-super.o +obj-y += clk-tegra-audio.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o diff --git a/drivers/clk/tegra/clk-tegra-audio.c b/drivers/clk/tegra/clk-tegra-audio.c new file mode 100644 index 000000000000..5c38aab2c5b8 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-audio.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2012, 2013, 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-id.h" + +#define AUDIO_SYNC_CLK_I2S0 0x4a0 +#define AUDIO_SYNC_CLK_I2S1 0x4a4 +#define AUDIO_SYNC_CLK_I2S2 0x4a8 +#define AUDIO_SYNC_CLK_I2S3 0x4ac +#define AUDIO_SYNC_CLK_I2S4 0x4b0 +#define AUDIO_SYNC_CLK_SPDIF 0x4b4 + +#define AUDIO_SYNC_DOUBLER 0x49c + +#define PLLA_OUT 0xb4 + +struct tegra_sync_source_initdata { + char *name; + unsigned long rate; + unsigned long max_rate; + int clk_id; +}; + +#define SYNC(_name) \ + {\ + .name = #_name,\ + .rate = 24000000,\ + .max_rate = 24000000,\ + .clk_id = tegra_clk_ ## _name,\ + } + +struct tegra_audio_clk_initdata { + char *gate_name; + char *mux_name; + u32 offset; + int gate_clk_id; + int mux_clk_id; +}; + +#define AUDIO(_name, _offset) \ + {\ + .gate_name = #_name,\ + .mux_name = #_name"_mux",\ + .offset = _offset,\ + .gate_clk_id = tegra_clk_ ## _name,\ + .mux_clk_id = tegra_clk_ ## _name ## _mux,\ + } + +struct tegra_audio2x_clk_initdata { + char *parent; + char *gate_name; + char *name_2x; + char *div_name; + int clk_id; + int clk_num; + u8 div_offset; +}; + +#define AUDIO2X(_name, _num, _offset) \ + {\ + .parent = #_name,\ + .gate_name = #_name"_2x",\ + .name_2x = #_name"_doubler",\ + .div_name = #_name"_div",\ + .clk_id = tegra_clk_ ## _name ## _2x,\ + .clk_num = _num,\ + .div_offset = _offset,\ + } + +static DEFINE_SPINLOCK(clk_doubler_lock); + +static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", + "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", +}; + +static struct tegra_sync_source_initdata sync_source_clks[] __initdata = { + SYNC(spdif_in_sync), + SYNC(i2s0_sync), + SYNC(i2s1_sync), + SYNC(i2s2_sync), + SYNC(i2s3_sync), + SYNC(i2s4_sync), + SYNC(vimclk_sync), +}; + +static struct tegra_audio_clk_initdata audio_clks[] = { + AUDIO(audio0, AUDIO_SYNC_CLK_I2S0), + AUDIO(audio1, AUDIO_SYNC_CLK_I2S1), + AUDIO(audio2, AUDIO_SYNC_CLK_I2S2), + AUDIO(audio3, AUDIO_SYNC_CLK_I2S3), + AUDIO(audio4, AUDIO_SYNC_CLK_I2S4), + AUDIO(spdif, AUDIO_SYNC_CLK_SPDIF), +}; + +static struct tegra_audio2x_clk_initdata audio2x_clks[] = { + AUDIO2X(audio0, 113, 24), + AUDIO2X(audio1, 114, 25), + AUDIO2X(audio2, 115, 26), + AUDIO2X(audio3, 116, 27), + AUDIO2X(audio4, 117, 28), + AUDIO2X(spdif, 118, 29), +}; + +void __init tegra_audio_clk_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_a_params) +{ + struct clk *clk; + struct clk **dt_clk; + int i; + + /* PLLA */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, + pmc_base, 0, pll_a_params, NULL); + *dt_clk = clk; + } + + /* PLLA_OUT0 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a_out0, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", + clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", + clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0, NULL); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(sync_source_clks); i++) { + struct tegra_sync_source_initdata *data; + + data = &sync_source_clks[i]; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = tegra_clk_register_sync_source(data->name, + data->rate, data->max_rate); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(audio_clks); i++) { + struct tegra_audio_clk_initdata *data; + + data = &audio_clks[i]; + dt_clk = tegra_lookup_dt_id(data->mux_clk_id, tegra_clks); + + if (!dt_clk) + continue; + clk = clk_register_mux(NULL, data->mux_name, mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), + CLK_SET_RATE_NO_REPARENT, + clk_base + data->offset, 0, 3, 0, + NULL); + *dt_clk = clk; + + dt_clk = tegra_lookup_dt_id(data->gate_clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_gate(NULL, data->gate_name, data->mux_name, + 0, clk_base + data->offset, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(audio2x_clks); i++) { + struct tegra_audio2x_clk_initdata *data; + + data = &audio2x_clks[i]; + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_fixed_factor(NULL, data->name_2x, + data->parent, CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider(data->div_name, + data->name_2x, clk_base + AUDIO_SYNC_DOUBLER, + 0, 0, data->div_offset, 1, 0, + &clk_doubler_lock); + clk = tegra_clk_register_periph_gate(data->gate_name, + data->div_name, TEGRA_PERIPH_NO_RESET, + clk_base, CLK_SET_RATE_PARENT, data->clk_num, + periph_clk_enb_refcnt); + *dt_clk = clk; + } +} + diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 48d4381357bb..8bb9a226d05c 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -26,6 +26,7 @@ #include #include "clk.h" +#include "clk-id.h" #define RST_DFLL_DVCO 0x2F4 #define CPU_FINETRIM_SELECT 0x4d4 /* override default prop dlys */ @@ -107,16 +108,6 @@ #define PLLM_OUT 0x94 #define PLLP_OUTA 0xa4 #define PLLP_OUTB 0xa8 -#define PLLA_OUT 0xb4 - -#define AUDIO_SYNC_CLK_I2S0 0x4a0 -#define AUDIO_SYNC_CLK_I2S1 0x4a4 -#define AUDIO_SYNC_CLK_I2S2 0x4a8 -#define AUDIO_SYNC_CLK_I2S3 0x4ac -#define AUDIO_SYNC_CLK_I2S4 0x4b0 -#define AUDIO_SYNC_CLK_SPDIF 0x4b4 - -#define AUDIO_SYNC_DOUBLER 0x49c #define PMC_CLK_OUT_CNTRL 0x1a8 #define PMC_DPD_PADS_ORIDE 0x1c @@ -272,7 +263,6 @@ static DEFINE_SPINLOCK(pll_d2_lock); static DEFINE_SPINLOCK(pll_u_lock); static DEFINE_SPINLOCK(pll_div_lock); static DEFINE_SPINLOCK(pll_re_lock); -static DEFINE_SPINLOCK(clk_doubler_lock); static DEFINE_SPINLOCK(clk_out_lock); static DEFINE_SPINLOCK(sysrate_lock); @@ -963,6 +953,186 @@ static const struct clk_div_table pll_re_div_table[] = { { .val = 0, .div = 0 }, }; +static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { + [tegra_clk_rtc] = { .dt_id = TEGRA114_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA114_CLK_TIMER, .present = true }, + [tegra_clk_uarta] = { .dt_id = TEGRA114_CLK_UARTA, .present = true }, + [tegra_clk_uartd] = { .dt_id = TEGRA114_CLK_UARTD, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA114_CLK_SDMMC2, .present = true }, + [tegra_clk_i2s1] = { .dt_id = TEGRA114_CLK_I2S1, .present = true }, + [tegra_clk_i2c1] = { .dt_id = TEGRA114_CLK_I2C1, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA114_CLK_NDFLASH, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA114_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA114_CLK_SDMMC4, .present = true }, + [tegra_clk_pwm] = { .dt_id = TEGRA114_CLK_PWM, .present = true }, + [tegra_clk_i2s0] = { .dt_id = TEGRA114_CLK_I2S0, .present = true }, + [tegra_clk_i2s2] = { .dt_id = TEGRA114_CLK_I2S2, .present = true }, + [tegra_clk_epp_8] = { .dt_id = TEGRA114_CLK_EPP, .present = true }, + [tegra_clk_gr2d_8] = { .dt_id = TEGRA114_CLK_GR2D, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA114_CLK_USBD, .present = true }, + [tegra_clk_isp] = { .dt_id = TEGRA114_CLK_ISP, .present = true }, + [tegra_clk_gr3d_8] = { .dt_id = TEGRA114_CLK_GR3D, .present = true }, + [tegra_clk_disp2] = { .dt_id = TEGRA114_CLK_DISP2, .present = true }, + [tegra_clk_disp1] = { .dt_id = TEGRA114_CLK_DISP1, .present = true }, + [tegra_clk_host1x_8] = { .dt_id = TEGRA114_CLK_HOST1X, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA114_CLK_VCP, .present = true }, + [tegra_clk_apbdma] = { .dt_id = TEGRA114_CLK_APBDMA, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA114_CLK_KBC, .present = true }, + [tegra_clk_kfuse] = { .dt_id = TEGRA114_CLK_KFUSE, .present = true }, + [tegra_clk_sbc1_8] = { .dt_id = TEGRA114_CLK_SBC1, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA114_CLK_NOR, .present = true }, + [tegra_clk_sbc2_8] = { .dt_id = TEGRA114_CLK_SBC2, .present = true }, + [tegra_clk_sbc3_8] = { .dt_id = TEGRA114_CLK_SBC3, .present = true }, + [tegra_clk_i2c5] = { .dt_id = TEGRA114_CLK_I2C5, .present = true }, + [tegra_clk_dsia] = { .dt_id = TEGRA114_CLK_DSIA, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA114_CLK_MIPI, .present = true }, + [tegra_clk_hdmi] = { .dt_id = TEGRA114_CLK_HDMI, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, + [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, + [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, + [tegra_clk_mipi_cal] = { .dt_id = TEGRA114_CLK_MIPI_CAL, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, + [tegra_clk_vde_8] = { .dt_id = TEGRA114_CLK_VDE, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA114_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA114_CLK_BSEV, .present = true }, + [tegra_clk_i2c3] = { .dt_id = TEGRA114_CLK_I2C3, .present = true }, + [tegra_clk_sbc4_8] = { .dt_id = TEGRA114_CLK_SBC4, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA114_CLK_SDMMC3, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA114_CLK_OWR, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA114_CLK_CSITE, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA114_CLK_LA, .present = true }, + [tegra_clk_trace] = { .dt_id = TEGRA114_CLK_TRACE, .present = true }, + [tegra_clk_soc_therm] = { .dt_id = TEGRA114_CLK_SOC_THERM, .present = true }, + [tegra_clk_dtv] = { .dt_id = TEGRA114_CLK_DTV, .present = true }, + [tegra_clk_ndspeed] = { .dt_id = TEGRA114_CLK_NDSPEED, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA114_CLK_I2CSLOW, .present = true }, + [tegra_clk_dsib] = { .dt_id = TEGRA114_CLK_DSIB, .present = true }, + [tegra_clk_tsec] = { .dt_id = TEGRA114_CLK_TSEC, .present = true }, + [tegra_clk_xusb_host] = { .dt_id = TEGRA114_CLK_XUSB_HOST, .present = true }, + [tegra_clk_msenc] = { .dt_id = TEGRA114_CLK_MSENC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA114_CLK_CSUS, .present = true }, + [tegra_clk_mselect] = { .dt_id = TEGRA114_CLK_MSELECT, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA114_CLK_TSENSOR, .present = true }, + [tegra_clk_i2s3] = { .dt_id = TEGRA114_CLK_I2S3, .present = true }, + [tegra_clk_i2s4] = { .dt_id = TEGRA114_CLK_I2S4, .present = true }, + [tegra_clk_i2c4] = { .dt_id = TEGRA114_CLK_I2C4, .present = true }, + [tegra_clk_sbc5_8] = { .dt_id = TEGRA114_CLK_SBC5, .present = true }, + [tegra_clk_sbc6_8] = { .dt_id = TEGRA114_CLK_SBC6, .present = true }, + [tegra_clk_d_audio] = { .dt_id = TEGRA114_CLK_D_AUDIO, .present = true }, + [tegra_clk_apbif] = { .dt_id = TEGRA114_CLK_APBIF, .present = true }, + [tegra_clk_dam0] = { .dt_id = TEGRA114_CLK_DAM0, .present = true }, + [tegra_clk_dam1] = { .dt_id = TEGRA114_CLK_DAM1, .present = true }, + [tegra_clk_dam2] = { .dt_id = TEGRA114_CLK_DAM2, .present = true }, + [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA114_CLK_HDA2CODEC_2X, .present = true }, + [tegra_clk_audio0_2x] = { .dt_id = TEGRA114_CLK_AUDIO0_2X, .present = true }, + [tegra_clk_audio1_2x] = { .dt_id = TEGRA114_CLK_AUDIO1_2X, .present = true }, + [tegra_clk_audio2_2x] = { .dt_id = TEGRA114_CLK_AUDIO2_2X, .present = true }, + [tegra_clk_audio3_2x] = { .dt_id = TEGRA114_CLK_AUDIO3_2X, .present = true }, + [tegra_clk_audio4_2x] = { .dt_id = TEGRA114_CLK_AUDIO4_2X, .present = true }, + [tegra_clk_spdif_2x] = { .dt_id = TEGRA114_CLK_SPDIF_2X, .present = true }, + [tegra_clk_actmon] = { .dt_id = TEGRA114_CLK_ACTMON, .present = true }, + [tegra_clk_extern1] = { .dt_id = TEGRA114_CLK_EXTERN1, .present = true }, + [tegra_clk_extern2] = { .dt_id = TEGRA114_CLK_EXTERN2, .present = true }, + [tegra_clk_extern3] = { .dt_id = TEGRA114_CLK_EXTERN3, .present = true }, + [tegra_clk_hda] = { .dt_id = TEGRA114_CLK_HDA, .present = true }, + [tegra_clk_se] = { .dt_id = TEGRA114_CLK_SE, .present = true }, + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA114_CLK_HDA2HDMI, .present = true }, + [tegra_clk_cilab] = { .dt_id = TEGRA114_CLK_CILAB, .present = true }, + [tegra_clk_cilcd] = { .dt_id = TEGRA114_CLK_CILCD, .present = true }, + [tegra_clk_cile] = { .dt_id = TEGRA114_CLK_CILE, .present = true }, + [tegra_clk_dsialp] = { .dt_id = TEGRA114_CLK_DSIALP, .present = true }, + [tegra_clk_dsiblp] = { .dt_id = TEGRA114_CLK_DSIBLP, .present = true }, + [tegra_clk_dds] = { .dt_id = TEGRA114_CLK_DDS, .present = true }, + [tegra_clk_dp2] = { .dt_id = TEGRA114_CLK_DP2, .present = true }, + [tegra_clk_amx] = { .dt_id = TEGRA114_CLK_AMX, .present = true }, + [tegra_clk_adx] = { .dt_id = TEGRA114_CLK_ADX, .present = true }, + [tegra_clk_xusb_ss] = { .dt_id = TEGRA114_CLK_XUSB_SS, .present = true }, + [tegra_clk_uartb] = { .dt_id = TEGRA114_CLK_UARTB, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA114_CLK_VFIR, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA114_CLK_SPDIF_IN, .present = true }, + [tegra_clk_spdif_out] = { .dt_id = TEGRA114_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_vi_8] = { .dt_id = TEGRA114_CLK_VI, .present = true }, + [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA114_CLK_VI_SENSOR, .present = true }, + [tegra_clk_fuse] = { .dt_id = TEGRA114_CLK_FUSE, .present = true }, + [tegra_clk_fuse_burn] = { .dt_id = TEGRA114_CLK_FUSE_BURN, .present = true }, + [tegra_clk_clk_32k] = { .dt_id = TEGRA114_CLK_CLK_32K, .present = true }, + [tegra_clk_clk_m] = { .dt_id = TEGRA114_CLK_CLK_M, .present = true }, + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA114_CLK_CLK_M_DIV2, .present = true }, + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA114_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_pll_ref] = { .dt_id = TEGRA114_CLK_PLL_REF, .present = true }, + [tegra_clk_pll_c] = { .dt_id = TEGRA114_CLK_PLL_C, .present = true }, + [tegra_clk_pll_c_out1] = { .dt_id = TEGRA114_CLK_PLL_C_OUT1, .present = true }, + [tegra_clk_pll_c2] = { .dt_id = TEGRA114_CLK_PLL_C2, .present = true }, + [tegra_clk_pll_c3] = { .dt_id = TEGRA114_CLK_PLL_C3, .present = true }, + [tegra_clk_pll_m] = { .dt_id = TEGRA114_CLK_PLL_M, .present = true }, + [tegra_clk_pll_m_out1] = { .dt_id = TEGRA114_CLK_PLL_M_OUT1, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA114_CLK_PLL_P, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA114_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2_int] = { .dt_id = TEGRA114_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA114_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA114_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_a] = { .dt_id = TEGRA114_CLK_PLL_A, .present = true }, + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA114_CLK_PLL_A_OUT0, .present = true }, + [tegra_clk_pll_d] = { .dt_id = TEGRA114_CLK_PLL_D, .present = true }, + [tegra_clk_pll_d_out0] = { .dt_id = TEGRA114_CLK_PLL_D_OUT0, .present = true }, + [tegra_clk_pll_d2] = { .dt_id = TEGRA114_CLK_PLL_D2, .present = true }, + [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA114_CLK_PLL_D2_OUT0, .present = true }, + [tegra_clk_pll_u] = { .dt_id = TEGRA114_CLK_PLL_U, .present = true }, + [tegra_clk_pll_u_480m] = { .dt_id = TEGRA114_CLK_PLL_U_480M, .present = true }, + [tegra_clk_pll_u_60m] = { .dt_id = TEGRA114_CLK_PLL_U_60M, .present = true }, + [tegra_clk_pll_u_48m] = { .dt_id = TEGRA114_CLK_PLL_U_48M, .present = true }, + [tegra_clk_pll_u_12m] = { .dt_id = TEGRA114_CLK_PLL_U_12M, .present = true }, + [tegra_clk_pll_x] = { .dt_id = TEGRA114_CLK_PLL_X, .present = true }, + [tegra_clk_pll_x_out0] = { .dt_id = TEGRA114_CLK_PLL_X_OUT0, .present = true }, + [tegra_clk_pll_re_vco] = { .dt_id = TEGRA114_CLK_PLL_RE_VCO, .present = true }, + [tegra_clk_pll_re_out] = { .dt_id = TEGRA114_CLK_PLL_RE_OUT, .present = true }, + [tegra_clk_pll_e_out0] = { .dt_id = TEGRA114_CLK_PLL_E_OUT0, .present = true }, + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA114_CLK_SPDIF_IN_SYNC, .present = true }, + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA114_CLK_I2S0_SYNC, .present = true }, + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA114_CLK_I2S1_SYNC, .present = true }, + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA114_CLK_I2S2_SYNC, .present = true }, + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA114_CLK_I2S3_SYNC, .present = true }, + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA114_CLK_I2S4_SYNC, .present = true }, + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA114_CLK_VIMCLK_SYNC, .present = true }, + [tegra_clk_audio0] = { .dt_id = TEGRA114_CLK_AUDIO0, .present = true }, + [tegra_clk_audio1] = { .dt_id = TEGRA114_CLK_AUDIO1, .present = true }, + [tegra_clk_audio2] = { .dt_id = TEGRA114_CLK_AUDIO2, .present = true }, + [tegra_clk_audio3] = { .dt_id = TEGRA114_CLK_AUDIO3, .present = true }, + [tegra_clk_audio4] = { .dt_id = TEGRA114_CLK_AUDIO4, .present = true }, + [tegra_clk_spdif] = { .dt_id = TEGRA114_CLK_SPDIF, .present = true }, + [tegra_clk_clk_out_1] = { .dt_id = TEGRA114_CLK_CLK_OUT_1, .present = true }, + [tegra_clk_clk_out_2] = { .dt_id = TEGRA114_CLK_CLK_OUT_2, .present = true }, + [tegra_clk_clk_out_3] = { .dt_id = TEGRA114_CLK_CLK_OUT_3, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA114_CLK_BLINK, .present = true }, + [tegra_clk_xusb_host_src] = { .dt_id = TEGRA114_CLK_XUSB_HOST_SRC, .present = true }, + [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA114_CLK_XUSB_FALCON_SRC, .present = true }, + [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA114_CLK_XUSB_FS_SRC, .present = true }, + [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA114_CLK_XUSB_SS_SRC, .present = true }, + [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA114_CLK_XUSB_DEV_SRC, .present = true }, + [tegra_clk_xusb_dev] = { .dt_id = TEGRA114_CLK_XUSB_DEV, .present = true }, + [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA114_CLK_XUSB_HS_SRC, .present = true }, + [tegra_clk_sclk] = { .dt_id = TEGRA114_CLK_SCLK, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA114_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA114_CLK_PCLK, .present = true }, + [tegra_clk_cclk_g] = { .dt_id = TEGRA114_CLK_CCLK_G, .present = true }, + [tegra_clk_cclk_lp] = { .dt_id = TEGRA114_CLK_CCLK_LP, .present = true }, + [tegra_clk_dfll_ref] = { .dt_id = TEGRA114_CLK_DFLL_REF, .present = true }, + [tegra_clk_dfll_soc] = { .dt_id = TEGRA114_CLK_DFLL_SOC, .present = true }, + [tegra_clk_audio0_mux] = { .dt_id = TEGRA114_CLK_AUDIO0_MUX, .present = true }, + [tegra_clk_audio1_mux] = { .dt_id = TEGRA114_CLK_AUDIO1_MUX, .present = true }, + [tegra_clk_audio2_mux] = { .dt_id = TEGRA114_CLK_AUDIO2_MUX, .present = true }, + [tegra_clk_audio3_mux] = { .dt_id = TEGRA114_CLK_AUDIO3_MUX, .present = true }, + [tegra_clk_audio4_mux] = { .dt_id = TEGRA114_CLK_AUDIO4_MUX, .present = true }, + [tegra_clk_spdif_mux] = { .dt_id = TEGRA114_CLK_SPDIF_MUX, .present = true }, + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_1_MUX, .present = true }, + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_2_MUX, .present = true }, + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_3_MUX, .present = true }, + [tegra_clk_dsia_mux] = { .dt_id = TEGRA114_CLK_DSIA_MUX, .present = true }, + [tegra_clk_dsib_mux] = { .dt_id = TEGRA114_CLK_DSIB_MUX, .present = true }, +}; + static struct tegra_devclk devclks[] __initdata = { { .con_id = "clk_m", .dt_id = TEGRA114_CLK_CLK_M }, { .con_id = "pll_ref", .dt_id = TEGRA114_CLK_PLL_REF }, @@ -1324,20 +1494,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, CLK_SET_RATE_PARENT, 1, 2); clks[TEGRA114_CLK_PLL_D2_OUT0] = clk; - /* PLLA */ - clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0, - &pll_a_params, NULL); - clks[TEGRA114_CLK_PLL_A] = clk; - - /* PLLA_OUT0 */ - clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", - clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, NULL); - clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", - clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | - CLK_SET_RATE_PARENT, 0, NULL); - clks[TEGRA114_CLK_PLL_A_OUT0] = clk; - /* PLLRE */ clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); @@ -1354,10 +1510,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_E_OUT0] = clk; } -static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", - "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", -}; - static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", "clk_m_div4", "extern1", }; @@ -1370,184 +1522,6 @@ static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", "clk_m_div4", "extern3", }; -static void __init tegra114_audio_clk_init(void __iomem *clk_base) -{ - struct clk *clk; - - /* spdif_in_sync */ - clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, - 24000000); - clks[TEGRA114_CLK_SPDIF_IN_SYNC] = clk; - - /* i2s0_sync */ - clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); - clks[TEGRA114_CLK_I2S0_SYNC] = clk; - - /* i2s1_sync */ - clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); - clks[TEGRA114_CLK_I2S1_SYNC] = clk; - - /* i2s2_sync */ - clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); - clks[TEGRA114_CLK_I2S2_SYNC] = clk; - - /* i2s3_sync */ - clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); - clks[TEGRA114_CLK_I2S3_SYNC] = clk; - - /* i2s4_sync */ - clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); - clks[TEGRA114_CLK_I2S4_SYNC] = clk; - - /* vimclk_sync */ - clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); - clks[TEGRA114_CLK_VIMCLK_SYNC] = clk; - - /* audio0 */ - clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, - NULL); - clks[TEGRA114_CLK_AUDIO0_MUX] = clk; - clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S0, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clks[TEGRA114_CLK_AUDIO0] = clk; - - /* audio1 */ - clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, - NULL); - clks[TEGRA114_CLK_AUDIO1_MUX] = clk; - clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S1, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clks[TEGRA114_CLK_AUDIO1] = clk; - - /* audio2 */ - clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, - NULL); - clks[TEGRA114_CLK_AUDIO2_MUX] = clk; - clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S2, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clks[TEGRA114_CLK_AUDIO2] = clk; - - /* audio3 */ - clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, - NULL); - clks[TEGRA114_CLK_AUDIO3_MUX] = clk; - clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S3, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clks[TEGRA114_CLK_AUDIO3] = clk; - - /* audio4 */ - clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, - NULL); - clks[TEGRA114_CLK_AUDIO4_MUX] = clk; - clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S4, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clks[TEGRA114_CLK_AUDIO4] = clk; - - /* spdif */ - clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, - NULL); - clks[TEGRA114_CLK_SPDIF_MUX] = clk; - clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, - clk_base + AUDIO_SYNC_CLK_SPDIF, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clks[TEGRA114_CLK_SPDIF] = clk; - - /* audio0_2x */ - clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 113, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_AUDIO0_2X] = clk; - - /* audio1_2x */ - clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 114, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_AUDIO1_2X] = clk; - - /* audio2_2x */ - clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 115, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_AUDIO2_2X] = clk; - - /* audio3_2x */ - clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 116, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_AUDIO3_2X] = clk; - - /* audio4_2x */ - clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 117, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_AUDIO4_2X] = clk; - - /* spdif_2x */ - clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 118, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_SPDIF_2X] = clk; -} - static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) { struct clk *clk; @@ -2194,7 +2168,7 @@ static void __init tegra114_clock_init(struct device_node *np) tegra114_fixed_clk_init(clk_base); tegra114_pll_init(clk_base, pmc_base); tegra114_periph_clk_init(clk_base); - tegra114_audio_clk_init(clk_base); + tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); tegra114_pmc_clk_init(pmc_base); tegra114_super_clk_init(clk_base); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index f742c7dda4cc..3306e41e6270 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -593,6 +593,10 @@ struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); void tegra_add_of_provider(struct device_node *np); void tegra_register_devclks(struct tegra_devclk *dev_clks, int num); +void tegra_audio_clk_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params); + void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); void tegra114_clock_tune_cpu_trimmers_init(void); -- cgit v1.2.3 From 76ebc134d45d7e6e1dc29fdcef4e539c5bc76eb8 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Wed, 4 Sep 2013 17:04:19 +0300 Subject: clk: tegra: move periph clocks to common file Introduce a new file for peripheral clocks common between several Tegra SoCs and move Tegra114 to this new infrastructure. Also PLLP and the PLLP_OUT clocks will be initialized here. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/Makefile | 2 +- drivers/clk/tegra/clk-tegra-periph.c | 596 +++++++++++++++++++++++++++++++++++ drivers/clk/tegra/clk-tegra114.c | 591 +--------------------------------- drivers/clk/tegra/clk-tegra20.c | 4 +- drivers/clk/tegra/clk-tegra30.c | 4 +- drivers/clk/tegra/clk.h | 11 +- 6 files changed, 627 insertions(+), 581 deletions(-) create mode 100644 drivers/clk/tegra/clk-tegra-periph.c (limited to 'drivers') diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 796ff9aa3899..304ea5df63eb 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -7,7 +7,7 @@ obj-y += clk-pll.o obj-y += clk-pll-out.o obj-y += clk-super.o obj-y += clk-tegra-audio.o - +obj-y += clk-tegra-periph.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c new file mode 100644 index 000000000000..9b04139f331d --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2012, 2013, 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-id.h" + +#define CLK_SOURCE_I2S0 0x1d8 +#define CLK_SOURCE_I2S1 0x100 +#define CLK_SOURCE_I2S2 0x104 +#define CLK_SOURCE_NDFLASH 0x160 +#define CLK_SOURCE_I2S3 0x3bc +#define CLK_SOURCE_I2S4 0x3c0 +#define CLK_SOURCE_SPDIF_OUT 0x108 +#define CLK_SOURCE_SPDIF_IN 0x10c +#define CLK_SOURCE_PWM 0x110 +#define CLK_SOURCE_ADX 0x638 +#define CLK_SOURCE_AMX 0x63c +#define CLK_SOURCE_HDA 0x428 +#define CLK_SOURCE_HDA2CODEC_2X 0x3e4 +#define CLK_SOURCE_SBC1 0x134 +#define CLK_SOURCE_SBC2 0x118 +#define CLK_SOURCE_SBC3 0x11c +#define CLK_SOURCE_SBC4 0x1b4 +#define CLK_SOURCE_SBC5 0x3c8 +#define CLK_SOURCE_SBC6 0x3cc +#define CLK_SOURCE_SATA_OOB 0x420 +#define CLK_SOURCE_SATA 0x424 +#define CLK_SOURCE_NDSPEED 0x3f8 +#define CLK_SOURCE_VFIR 0x168 +#define CLK_SOURCE_SDMMC1 0x150 +#define CLK_SOURCE_SDMMC2 0x154 +#define CLK_SOURCE_SDMMC3 0x1bc +#define CLK_SOURCE_SDMMC4 0x164 +#define CLK_SOURCE_CVE 0x140 +#define CLK_SOURCE_TVO 0x188 +#define CLK_SOURCE_TVDAC 0x194 +#define CLK_SOURCE_VDE 0x1c8 +#define CLK_SOURCE_CSITE 0x1d4 +#define CLK_SOURCE_LA 0x1f8 +#define CLK_SOURCE_TRACE 0x634 +#define CLK_SOURCE_OWR 0x1cc +#define CLK_SOURCE_NOR 0x1d0 +#define CLK_SOURCE_MIPI 0x174 +#define CLK_SOURCE_I2C1 0x124 +#define CLK_SOURCE_I2C2 0x198 +#define CLK_SOURCE_I2C3 0x1b8 +#define CLK_SOURCE_I2C4 0x3c4 +#define CLK_SOURCE_I2C5 0x128 +#define CLK_SOURCE_UARTA 0x178 +#define CLK_SOURCE_UARTB 0x17c +#define CLK_SOURCE_UARTC 0x1a0 +#define CLK_SOURCE_UARTD 0x1c0 +#define CLK_SOURCE_UARTE 0x1c4 +#define CLK_SOURCE_3D 0x158 +#define CLK_SOURCE_2D 0x15c +#define CLK_SOURCE_MPE 0x170 +#define CLK_SOURCE_VI_SENSOR 0x1a8 +#define CLK_SOURCE_VI 0x148 +#define CLK_SOURCE_EPP 0x16c +#define CLK_SOURCE_MSENC 0x1f0 +#define CLK_SOURCE_TSEC 0x1f4 +#define CLK_SOURCE_HOST1X 0x180 +#define CLK_SOURCE_HDMI 0x18c +#define CLK_SOURCE_DISP1 0x138 +#define CLK_SOURCE_DISP2 0x13c +#define CLK_SOURCE_CILAB 0x614 +#define CLK_SOURCE_CILCD 0x618 +#define CLK_SOURCE_CILE 0x61c +#define CLK_SOURCE_DSIALP 0x620 +#define CLK_SOURCE_DSIBLP 0x624 +#define CLK_SOURCE_TSENSOR 0x3b8 +#define CLK_SOURCE_D_AUDIO 0x3d0 +#define CLK_SOURCE_DAM0 0x3d8 +#define CLK_SOURCE_DAM1 0x3dc +#define CLK_SOURCE_DAM2 0x3e0 +#define CLK_SOURCE_ACTMON 0x3e8 +#define CLK_SOURCE_EXTERN1 0x3ec +#define CLK_SOURCE_EXTERN2 0x3f0 +#define CLK_SOURCE_EXTERN3 0x3f4 +#define CLK_SOURCE_I2CSLOW 0x3fc +#define CLK_SOURCE_SE 0x42c +#define CLK_SOURCE_MSELECT 0x3b4 +#define CLK_SOURCE_DFLL_REF 0x62c +#define CLK_SOURCE_DFLL_SOC 0x630 +#define CLK_SOURCE_SOC_THERM 0x644 +#define CLK_SOURCE_XUSB_HOST_SRC 0x600 +#define CLK_SOURCE_XUSB_FALCON_SRC 0x604 +#define CLK_SOURCE_XUSB_FS_SRC 0x608 +#define CLK_SOURCE_XUSB_SS_SRC 0x610 +#define CLK_SOURCE_XUSB_DEV_SRC 0x60c + +#define MASK(x) (BIT(x) - 1) + +#define MUX(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) + +#define MUX_FLAGS(_name, _parents, _offset,\ + _clk_num, _gate_flags, _clk_id, flags)\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + _clk_num, _gate_flags, _clk_id, _parents##_idx, flags) + +#define MUX8(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) + +#define INT(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, 0) + +#define INT_FLAGS(_name, _parents, _offset,\ + _clk_num, _gate_flags, _clk_id, flags)\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, flags) + +#define INT8(_name, _parents, _offset,\ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, 0) + +#define UART(_name, _parents, _offset,\ + _clk_num, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, 0, _clk_id,\ + _parents##_idx, 0) + +#define I2C(_name, _parents, _offset,\ + _clk_num, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ + _clk_num, 0, _clk_id, _parents##_idx, 0) + +#define XUSB(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, 0) + +#define AUDIO(_name, _offset, _clk_num,\ + _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, mux_d_audio_clk, \ + _offset, 16, 0xE01F, 0, 0, 8, 1, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags, \ + _clk_id, mux_d_audio_clk_idx, 0) + +#define NODIV(_name, _parents, _offset, \ + _mux_shift, _mux_mask, _clk_num, \ + _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ + _clk_num, (_gate_flags) | TEGRA_PERIPH_NO_DIV,\ + _clk_id, _parents##_idx, 0) + +#define GATE(_name, _parent_name, \ + _clk_num, _gate_flags, _clk_id, _flags) \ + { \ + .name = _name, \ + .clk_id = _clk_id, \ + .p.parent_name = _parent_name, \ + .periph = TEGRA_CLK_PERIPH(0, 0, 0, 0, 0, 0, 0, \ + _clk_num, _gate_flags, 0), \ + .flags = _flags \ + } + +#define PLLP_BASE 0xa0 +#define PLLP_MISC 0xac +#define PLLP_OUTA 0xa4 +#define PLLP_OUTB 0xa8 + +#define PLL_BASE_LOCK BIT(27) +#define PLL_MISC_LOCK_ENABLE 18 + +static DEFINE_SPINLOCK(PLLP_OUTA_lock); +static DEFINE_SPINLOCK(PLLP_OUTB_lock); + +#define MUX_I2S_SPDIF(_id) \ +static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ + #_id, "pll_p",\ + "clk_m"}; +MUX_I2S_SPDIF(audio0) +MUX_I2S_SPDIF(audio1) +MUX_I2S_SPDIF(audio2) +MUX_I2S_SPDIF(audio3) +MUX_I2S_SPDIF(audio4) +MUX_I2S_SPDIF(audio) + +#define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio_2x_pllp_clkm_idx NULL + +static const char *mux_pllp_pllc_pllm_clkm[] = { + "pll_p", "pll_c", "pll_m", "clk_m" +}; +#define mux_pllp_pllc_pllm_clkm_idx NULL + +static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" }; +#define mux_pllp_pllc_pllm_idx NULL + +static const char *mux_pllp_pllc_clk32_clkm[] = { + "pll_p", "pll_c", "clk_32k", "clk_m" +}; +#define mux_pllp_pllc_clk32_clkm_idx NULL + +static const char *mux_plla_pllc_pllp_clkm[] = { + "pll_a_out0", "pll_c", "pll_p", "clk_m" +}; +#define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx + +static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = { + "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m" +}; +static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, +}; + +static const char *mux_pllp_clkm[] = { + "pll_p", "clk_m" +}; +static u32 mux_pllp_clkm_idx[] = { + [0] = 0, [1] = 3, +}; + +static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { + "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" +}; +#define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx + +static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { + "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", + "pll_d2_out0", "clk_m" +}; +#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL + +static const char *mux_pllm_pllc_pllp_plla[] = { + "pll_m", "pll_c", "pll_p", "pll_a_out0" +}; +#define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx + +static const char *mux_pllp_pllc_clkm[] = { + "pll_p", "pll_c", "pll_m" +}; +static u32 mux_pllp_pllc_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 3, +}; + +static const char *mux_pllp_pllc_clkm_clk32[] = { + "pll_p", "pll_c", "clk_m", "clk_32k" +}; +#define mux_pllp_pllc_clkm_clk32_idx NULL + +static const char *mux_plla_clk32_pllp_clkm_plle[] = { + "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0" +}; +#define mux_plla_clk32_pllp_clkm_plle_idx NULL + +static const char *mux_clkm_pllp_pllc_pllre[] = { + "clk_m", "pll_p", "pll_c", "pll_re_out" +}; +static u32 mux_clkm_pllp_pllc_pllre_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 5, +}; + +static const char *mux_clkm_48M_pllp_480M[] = { + "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" +}; +#define mux_clkm_48M_pllp_480M_idx NULL + +static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { + "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" +}; +static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, +}; + +static const char *mux_d_audio_clk[] = { + "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", + "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", +}; +static u32 mux_d_audio_clk_idx[] = { + [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001, + [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007, +}; + +static const char *mux_pllp_plld_pllc_clkm[] = { + "pll_p", "pll_d_out0", "pll_c", "clk_m" +}; +#define mux_pllp_plld_pllc_clkm_idx NULL + +static struct tegra_periph_init_data periph_clks[] = { + AUDIO("d_audio", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, tegra_clk_d_audio), + AUDIO("dam0", CLK_SOURCE_DAM0, 108, TEGRA_PERIPH_ON_APB, tegra_clk_dam0), + AUDIO("dam1", CLK_SOURCE_DAM1, 109, TEGRA_PERIPH_ON_APB, tegra_clk_dam1), + AUDIO("dam2", CLK_SOURCE_DAM2, 110, TEGRA_PERIPH_ON_APB, tegra_clk_dam2), + I2C("i2c1", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, tegra_clk_i2c1), + I2C("i2c2", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, tegra_clk_i2c2), + I2C("i2c3", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, tegra_clk_i2c3), + I2C("i2c4", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, tegra_clk_i2c4), + I2C("i2c5", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, tegra_clk_i2c5), + INT("vde", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde), + INT("vi", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi), + INT("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp), + INT("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x), + INT("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60, 0, tegra_clk_mpe), + INT("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d), + INT("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d), + INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde_8), + INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_8), + INT8("epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp_8), + INT8("msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, tegra_clk_msenc), + INT8("tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, tegra_clk_tsec), + INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_8), + INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), + INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d_8), + INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d_8), + INT_FLAGS("mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, tegra_clk_mselect, CLK_IGNORE_UNUSED), + MUX("i2s0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, tegra_clk_i2s0), + MUX("i2s1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, tegra_clk_i2s1), + MUX("i2s2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, tegra_clk_i2s2), + MUX("i2s3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, tegra_clk_i2s3), + MUX("i2s4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, tegra_clk_i2s4), + MUX("spdif_out", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_out), + MUX("spdif_in", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_in), + MUX("pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, tegra_clk_pwm), + MUX("adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, tegra_clk_adx), + MUX("amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, tegra_clk_amx), + MUX("hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, tegra_clk_hda), + MUX("hda2codec_2x", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, tegra_clk_hda2codec_2x), + MUX("vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, tegra_clk_vfir), + MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1), + MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2), + MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3), + MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, tegra_clk_sdmmc4), + MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la), + MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace), + MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr), + MUX("nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, tegra_clk_nor), + MUX("mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, tegra_clk_mipi), + MUX("vi_sensor", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor), + MUX("cilab", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, tegra_clk_cilab), + MUX("cilcd", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, tegra_clk_cilcd), + MUX("cile", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, tegra_clk_cile), + MUX("dsialp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, 0, tegra_clk_dsialp), + MUX("dsiblp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, 0, tegra_clk_dsiblp), + MUX("tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, tegra_clk_tsensor), + MUX("actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, 0, tegra_clk_actmon), + MUX("dfll_ref", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, TEGRA_PERIPH_ON_APB, tegra_clk_dfll_ref), + MUX("dfll_soc", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, TEGRA_PERIPH_ON_APB, tegra_clk_dfll_soc), + MUX("i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, tegra_clk_i2cslow), + MUX("sbc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1), + MUX("sbc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2), + MUX("sbc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3), + MUX("sbc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4), + MUX("sbc5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, tegra_clk_sbc5), + MUX("sbc6", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, tegra_clk_sbc6), + MUX("cve", mux_pllp_plld_pllc_clkm, CLK_SOURCE_CVE, 49, 0, tegra_clk_cve), + MUX("tvo", mux_pllp_plld_pllc_clkm, CLK_SOURCE_TVO, 49, 0, tegra_clk_tvo), + MUX("tvdac", mux_pllp_plld_pllc_clkm, CLK_SOURCE_TVDAC, 53, 0, tegra_clk_tvdac), + MUX("ndflash", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash), + MUX("ndspeed", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed), + MUX("sata_oob", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, tegra_clk_sata_oob), + MUX("sata", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, tegra_clk_sata), + MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8), + MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8), + MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8), + MUX8("sbc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4_8), + MUX8("sbc5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, tegra_clk_sbc5_8), + MUX8("sbc6", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, tegra_clk_sbc6_8), + MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), + MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), + MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), + MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, tegra_clk_extern1), + MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2), + MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), + MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), + MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), + MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), + NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1), + NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2), + UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), + UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), + UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), + UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd), + UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 65, tegra_clk_uarte), + XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src), + XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), + XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), + XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ss_src), + XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src), +}; + +static struct tegra_periph_init_data gate_clks[] = { + GATE("rtc", "clk_32k", 4, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_rtc, 0), + GATE("timer", "clk_m", 5, 0, tegra_clk_timer, 0), + GATE("isp", "clk_m", 23, 0, tegra_clk_isp, 0), + GATE("vcp", "clk_m", 29, 0, tegra_clk_vcp, 0), + GATE("apbdma", "clk_m", 34, 0, tegra_clk_apbdma, 0), + GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0), + GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0), + GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0), + GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0), + GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0), + GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0), + GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0), + GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0), + GATE("mipi-cal", "clk_m", 56, 0, tegra_clk_mipi_cal, 0), + GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0), + GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0), + GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0), + GATE("csi", "pll_p_out3", 52, 0, tegra_clk_csi, 0), + GATE("afi", "clk_m", 72, 0, tegra_clk_afi, 0), + GATE("csus", "clk_m", 92, TEGRA_PERIPH_NO_RESET, tegra_clk_csus, 0), + GATE("dds", "clk_m", 150, TEGRA_PERIPH_ON_APB, tegra_clk_dds, 0), + GATE("dp2", "clk_m", 152, TEGRA_PERIPH_ON_APB, tegra_clk_dp2, 0), + GATE("dtv", "clk_m", 79, TEGRA_PERIPH_ON_APB, tegra_clk_dtv, 0), + GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0), + GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0), + GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0), + GATE("dsia", "dsia_mux", 48, 0, tegra_clk_dsia, 0), + GATE("dsib", "dsib_mux", 82, 0, tegra_clk_dsib, 0), + GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED), + GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0), +}; + +struct pll_out_data { + char *div_name; + char *pll_out_name; + u32 offset; + int clk_id; + u8 div_shift; + u8 div_flags; + u8 rst_shift; + spinlock_t *lock; +}; + +#define PLL_OUT(_num, _offset, _div_shift, _div_flags, _rst_shift, _id) \ + {\ + .div_name = "pll_p_out" #_num "_div",\ + .pll_out_name = "pll_p_out" #_num,\ + .offset = _offset,\ + .div_shift = _div_shift,\ + .div_flags = _div_flags | TEGRA_DIVIDER_FIXED |\ + TEGRA_DIVIDER_ROUND_UP,\ + .rst_shift = _rst_shift,\ + .clk_id = tegra_clk_ ## _id,\ + .lock = &_offset ##_lock,\ + } + +static struct pll_out_data pllp_out_clks[] = { + PLL_OUT(1, PLLP_OUTA, 8, 0, 0, pll_p_out1), + PLL_OUT(2, PLLP_OUTA, 24, 0, 16, pll_p_out2), + PLL_OUT(2, PLLP_OUTA, 24, TEGRA_DIVIDER_INT, 16, pll_p_out2_int), + PLL_OUT(3, PLLP_OUTB, 8, 0, 0, pll_p_out3), + PLL_OUT(4, PLLP_OUTB, 24, 0, 16, pll_p_out4), +}; + +static void __init periph_clk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks) +{ + int i; + struct clk *clk; + struct clk **dt_clk; + + for (i = 0; i < ARRAY_SIZE(periph_clks); i++) { + struct tegra_clk_periph_regs *bank; + struct tegra_periph_init_data *data; + + data = periph_clks + i; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + bank = get_reg_bank(data->periph.gate.clk_num); + if (!bank) + continue; + + data->periph.gate.regs = bank; + clk = tegra_clk_register_periph(data->name, + data->p.parent_names, data->num_parents, + &data->periph, clk_base, data->offset, + data->flags); + *dt_clk = clk; + } +} + +static void __init gate_clk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks) +{ + int i; + struct clk *clk; + struct clk **dt_clk; + + for (i = 0; i < ARRAY_SIZE(gate_clks); i++) { + struct tegra_periph_init_data *data; + + data = gate_clks + i; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = tegra_clk_register_periph_gate(data->name, + data->p.parent_name, data->periph.gate.flags, + clk_base, data->flags, + data->periph.gate.clk_num, + periph_clk_enb_refcnt); + *dt_clk = clk; + } +} + +static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params) +{ + struct clk *clk; + struct clk **dt_clk; + int i; + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_p, tegra_clks); + if (dt_clk) { + /* PLLP */ + clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, + pmc_base, 0, pll_params, NULL); + clk_register_clkdev(clk, "pll_p", NULL); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(pllp_out_clks); i++) { + struct pll_out_data *data; + + data = pllp_out_clks + i; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = tegra_clk_register_divider(data->div_name, "pll_p", + clk_base + data->offset, 0, data->div_flags, + data->div_shift, 8, 1, data->lock); + clk = tegra_clk_register_pll_out(data->pll_out_name, + data->div_name, clk_base + data->offset, + data->rst_shift + 1, data->rst_shift, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, + data->lock); + *dt_clk = clk; + } +} + +void __init tegra_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params) +{ + init_pllp(clk_base, pmc_base, tegra_clks, pll_params); + periph_clk_init(clk_base, tegra_clks); + gate_clk_init(clk_base, tegra_clks); +} diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 8bb9a226d05c..07098597db53 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -106,8 +106,6 @@ #define PLLE_AUX 0x48c #define PLLC_OUT 0x84 #define PLLM_OUT 0x94 -#define PLLP_OUTA 0xa4 -#define PLLP_OUTB 0xa8 #define PMC_CLK_OUT_CNTRL 0x1a8 #define PMC_DPD_PADS_ORIDE 0x1c @@ -153,91 +151,8 @@ #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) -#define CLK_SOURCE_I2S0 0x1d8 -#define CLK_SOURCE_I2S1 0x100 -#define CLK_SOURCE_I2S2 0x104 -#define CLK_SOURCE_NDFLASH 0x160 -#define CLK_SOURCE_I2S3 0x3bc -#define CLK_SOURCE_I2S4 0x3c0 -#define CLK_SOURCE_SPDIF_OUT 0x108 -#define CLK_SOURCE_SPDIF_IN 0x10c -#define CLK_SOURCE_PWM 0x110 -#define CLK_SOURCE_ADX 0x638 -#define CLK_SOURCE_AMX 0x63c -#define CLK_SOURCE_HDA 0x428 -#define CLK_SOURCE_HDA2CODEC_2X 0x3e4 -#define CLK_SOURCE_SBC1 0x134 -#define CLK_SOURCE_SBC2 0x118 -#define CLK_SOURCE_SBC3 0x11c -#define CLK_SOURCE_SBC4 0x1b4 -#define CLK_SOURCE_SBC5 0x3c8 -#define CLK_SOURCE_SBC6 0x3cc -#define CLK_SOURCE_SATA_OOB 0x420 -#define CLK_SOURCE_SATA 0x424 -#define CLK_SOURCE_NDSPEED 0x3f8 -#define CLK_SOURCE_VFIR 0x168 -#define CLK_SOURCE_SDMMC1 0x150 -#define CLK_SOURCE_SDMMC2 0x154 -#define CLK_SOURCE_SDMMC3 0x1bc -#define CLK_SOURCE_SDMMC4 0x164 -#define CLK_SOURCE_VDE 0x1c8 #define CLK_SOURCE_CSITE 0x1d4 -#define CLK_SOURCE_LA 0x1f8 -#define CLK_SOURCE_TRACE 0x634 -#define CLK_SOURCE_OWR 0x1cc -#define CLK_SOURCE_NOR 0x1d0 -#define CLK_SOURCE_MIPI 0x174 -#define CLK_SOURCE_I2C1 0x124 -#define CLK_SOURCE_I2C2 0x198 -#define CLK_SOURCE_I2C3 0x1b8 -#define CLK_SOURCE_I2C4 0x3c4 -#define CLK_SOURCE_I2C5 0x128 -#define CLK_SOURCE_UARTA 0x178 -#define CLK_SOURCE_UARTB 0x17c -#define CLK_SOURCE_UARTC 0x1a0 -#define CLK_SOURCE_UARTD 0x1c0 -#define CLK_SOURCE_UARTE 0x1c4 -#define CLK_SOURCE_UARTA_DBG 0x178 -#define CLK_SOURCE_UARTB_DBG 0x17c -#define CLK_SOURCE_UARTC_DBG 0x1a0 -#define CLK_SOURCE_UARTD_DBG 0x1c0 -#define CLK_SOURCE_UARTE_DBG 0x1c4 -#define CLK_SOURCE_3D 0x158 -#define CLK_SOURCE_2D 0x15c -#define CLK_SOURCE_VI_SENSOR 0x1a8 -#define CLK_SOURCE_VI 0x148 -#define CLK_SOURCE_EPP 0x16c -#define CLK_SOURCE_MSENC 0x1f0 -#define CLK_SOURCE_TSEC 0x1f4 -#define CLK_SOURCE_HOST1X 0x180 -#define CLK_SOURCE_HDMI 0x18c -#define CLK_SOURCE_DISP1 0x138 -#define CLK_SOURCE_DISP2 0x13c -#define CLK_SOURCE_CILAB 0x614 -#define CLK_SOURCE_CILCD 0x618 -#define CLK_SOURCE_CILE 0x61c -#define CLK_SOURCE_DSIALP 0x620 -#define CLK_SOURCE_DSIBLP 0x624 -#define CLK_SOURCE_TSENSOR 0x3b8 -#define CLK_SOURCE_D_AUDIO 0x3d0 -#define CLK_SOURCE_DAM0 0x3d8 -#define CLK_SOURCE_DAM1 0x3dc -#define CLK_SOURCE_DAM2 0x3e0 -#define CLK_SOURCE_ACTMON 0x3e8 -#define CLK_SOURCE_EXTERN1 0x3ec -#define CLK_SOURCE_EXTERN2 0x3f0 -#define CLK_SOURCE_EXTERN3 0x3f4 -#define CLK_SOURCE_I2CSLOW 0x3fc -#define CLK_SOURCE_SE 0x42c -#define CLK_SOURCE_MSELECT 0x3b4 -#define CLK_SOURCE_DFLL_REF 0x62c -#define CLK_SOURCE_DFLL_SOC 0x630 -#define CLK_SOURCE_SOC_THERM 0x644 -#define CLK_SOURCE_XUSB_HOST_SRC 0x600 -#define CLK_SOURCE_XUSB_FALCON_SRC 0x604 -#define CLK_SOURCE_XUSB_FS_SRC 0x608 #define CLK_SOURCE_XUSB_SS_SRC 0x610 -#define CLK_SOURCE_XUSB_DEV_SRC 0x60c #define CLK_SOURCE_EMC 0x19c /* PLLM override registers */ @@ -261,7 +176,6 @@ static void __iomem *pmc_base; static DEFINE_SPINLOCK(pll_d_lock); static DEFINE_SPINLOCK(pll_d2_lock); static DEFINE_SPINLOCK(pll_u_lock); -static DEFINE_SPINLOCK(pll_div_lock); static DEFINE_SPINLOCK(pll_re_lock); static DEFINE_SPINLOCK(clk_out_lock); static DEFINE_SPINLOCK(sysrate_lock); @@ -723,73 +637,6 @@ static unsigned long tegra114_input_freq[] = { #define MASK(x) (BIT(x) - 1) -#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ - _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _parents, _offset,\ - _clk_num, _gate_flags, _clk_id, flags)\ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, _gate_flags, _clk_id, _parents##_idx, flags) - -#define TEGRA_INIT_DATA_MUX8(_name, _parents, _offset, \ - _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_INT_FLAGS(_name, _parents, _offset,\ - _clk_num, _gate_flags, _clk_id, flags)\ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ - TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - _gate_flags, _clk_id, _parents##_idx, flags) - -#define TEGRA_INIT_DATA_INT8(_name, _parents, _offset,\ - _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ - TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - _gate_flags, _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_UART(_name, _parents, _offset,\ - _clk_num, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ - TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - 0, _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_I2C(_name, _parents, _offset,\ - _clk_num, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, 0, _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ - _mux_shift, _mux_mask, _clk_num, \ - _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ - _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ - _clk_num, _gate_flags, \ - _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_XUSB(_name, _parents, _offset, \ - _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ - 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ - TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - _gate_flags, _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_AUDIO(_name, _offset, _clk_num,\ - _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, mux_d_audio_clk, \ - _offset, 16, 0xE01F, 0, 0, 8, 1, \ - TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - _gate_flags , _clk_id, mux_d_audio_clk_idx, 0) - struct utmi_clk_param { /* Oscillator Frequency in KHz */ u32 osc_frequency; @@ -823,122 +670,11 @@ static const struct utmi_clk_param utmi_parameters[] = { /* peripheral mux definitions */ -#define MUX_I2S_SPDIF(_id) \ -static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ - #_id, "pll_p",\ - "clk_m"}; -MUX_I2S_SPDIF(audio0) -MUX_I2S_SPDIF(audio1) -MUX_I2S_SPDIF(audio2) -MUX_I2S_SPDIF(audio3) -MUX_I2S_SPDIF(audio4) -MUX_I2S_SPDIF(audio) - -#define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio_2x_pllp_clkm_idx NULL - -static const char *mux_pllp_pllc_pllm_clkm[] = { - "pll_p", "pll_c", "pll_m", "clk_m" -}; -#define mux_pllp_pllc_pllm_clkm_idx NULL - -static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" }; -#define mux_pllp_pllc_pllm_idx NULL - -static const char *mux_pllp_pllc_clk32_clkm[] = { - "pll_p", "pll_c", "clk_32k", "clk_m" -}; -#define mux_pllp_pllc_clk32_clkm_idx NULL - -static const char *mux_plla_pllc_pllp_clkm[] = { - "pll_a_out0", "pll_c", "pll_p", "clk_m" -}; -#define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx - -static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = { - "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m" -}; -static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = { - [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, -}; - -static const char *mux_pllp_clkm[] = { - "pll_p", "clk_m" -}; -static u32 mux_pllp_clkm_idx[] = { - [0] = 0, [1] = 3, -}; - -static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { - "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" -}; -#define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx - -static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { - "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", - "pll_d2_out0", "clk_m" -}; -#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL - -static const char *mux_pllm_pllc_pllp_plla[] = { - "pll_m", "pll_c", "pll_p", "pll_a_out0" -}; -#define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx - -static const char *mux_pllp_pllc_clkm[] = { - "pll_p", "pll_c", "pll_m" -}; -static u32 mux_pllp_pllc_clkm_idx[] = { - [0] = 0, [1] = 1, [2] = 3, -}; - -static const char *mux_pllp_pllc_clkm_clk32[] = { - "pll_p", "pll_c", "clk_m", "clk_32k" -}; -#define mux_pllp_pllc_clkm_clk32_idx NULL - -static const char *mux_plla_clk32_pllp_clkm_plle[] = { - "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0" -}; -#define mux_plla_clk32_pllp_clkm_plle_idx NULL - -static const char *mux_clkm_pllp_pllc_pllre[] = { - "clk_m", "pll_p", "pll_c", "pll_re_out" -}; -static u32 mux_clkm_pllp_pllc_pllre_idx[] = { - [0] = 0, [1] = 1, [2] = 3, [3] = 5, -}; - -static const char *mux_clkm_48M_pllp_480M[] = { - "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" -}; -#define mux_clkm_48M_pllp_480M_idx NULL - -static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { - "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" -}; -static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { - [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, -}; - static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", "pll_d2_out0", }; #define mux_plld_out0_plld2_out0_idx NULL -static const char *mux_d_audio_clk[] = { - "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", - "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", -}; -static u32 mux_d_audio_clk_idx[] = { - [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001, - [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007, -}; - static const char *mux_pllmcp_clkm[] = { "pll_m_out0", "pll_c_out0", "pll_p_out0", "clk_m", "pll_m_ud", }; @@ -1366,53 +1102,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, &pll_c3_params, NULL); clks[TEGRA114_CLK_PLL_C3] = clk; - /* PLLP */ - clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0, - &pll_p_params, NULL); - clks[TEGRA114_CLK_PLL_P] = clk; - - /* PLLP_OUT1 */ - clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", - clk_base + PLLP_OUTA, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clks[TEGRA114_CLK_PLL_P_OUT1] = clk; - - /* PLLP_OUT2 */ - clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP | TEGRA_DIVIDER_INT, 24, - 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", - clk_base + PLLP_OUTA, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clks[TEGRA114_CLK_PLL_P_OUT2] = clk; - - /* PLLP_OUT3 */ - clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", - clk_base + PLLP_OUTB, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clks[TEGRA114_CLK_PLL_P_OUT3] = clk; - - /* PLLP_OUT4 */ - clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", - clk_base + PLLP_OUTB, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clks[TEGRA114_CLK_PLL_P_OUT4] = clk; - /* PLLM */ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, @@ -1634,290 +1323,44 @@ static void __init tegra114_super_clk_init(void __iomem *clk_base) clks[TEGRA114_CLK_PCLK] = clk; } -static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S0), - TEGRA_INIT_DATA_MUX("i2s1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S1), - TEGRA_INIT_DATA_MUX("i2s2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S2), - TEGRA_INIT_DATA_MUX("i2s3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S3), - TEGRA_INIT_DATA_MUX("i2s4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2S4), - TEGRA_INIT_DATA_MUX("spdif_out", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_OUT), - TEGRA_INIT_DATA_MUX("spdif_in", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SPDIF_IN), - TEGRA_INIT_DATA_MUX("pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_PWM), - TEGRA_INIT_DATA_MUX("adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_ADX), - TEGRA_INIT_DATA_MUX("amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_AMX), - TEGRA_INIT_DATA_MUX("hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA), - TEGRA_INIT_DATA_MUX("hda2codec_2x", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_HDA2CODEC_2X), - TEGRA_INIT_DATA_MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC1), - TEGRA_INIT_DATA_MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC2), - TEGRA_INIT_DATA_MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC3), - TEGRA_INIT_DATA_MUX8("sbc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC4), - TEGRA_INIT_DATA_MUX8("sbc5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC5), - TEGRA_INIT_DATA_MUX8("sbc6", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SBC6), - TEGRA_INIT_DATA_MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), - TEGRA_INIT_DATA_MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_NDSPEED), - TEGRA_INIT_DATA_MUX("vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_VFIR), - TEGRA_INIT_DATA_MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, TEGRA114_CLK_SDMMC1), - TEGRA_INIT_DATA_MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, TEGRA114_CLK_SDMMC2), - TEGRA_INIT_DATA_MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, TEGRA114_CLK_SDMMC3), - TEGRA_INIT_DATA_MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, TEGRA114_CLK_SDMMC4), - TEGRA_INIT_DATA_INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, TEGRA114_CLK_VDE), - TEGRA_INIT_DATA_MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_CSITE, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_LA), - TEGRA_INIT_DATA_MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TRACE), - TEGRA_INIT_DATA_MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_OWR), - TEGRA_INIT_DATA_MUX("nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, TEGRA114_CLK_NOR), - TEGRA_INIT_DATA_MUX("mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_MIPI), - TEGRA_INIT_DATA_I2C("i2c1", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, TEGRA114_CLK_I2C1), - TEGRA_INIT_DATA_I2C("i2c2", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, TEGRA114_CLK_I2C2), - TEGRA_INIT_DATA_I2C("i2c3", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, TEGRA114_CLK_I2C3), - TEGRA_INIT_DATA_I2C("i2c4", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, TEGRA114_CLK_I2C4), - TEGRA_INIT_DATA_I2C("i2c5", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, TEGRA114_CLK_I2C5), - TEGRA_INIT_DATA_UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, TEGRA114_CLK_UARTA), - TEGRA_INIT_DATA_UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, TEGRA114_CLK_UARTB), - TEGRA_INIT_DATA_UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, TEGRA114_CLK_UARTC), - TEGRA_INIT_DATA_UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, TEGRA114_CLK_UARTD), - TEGRA_INIT_DATA_INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, TEGRA114_CLK_GR3D), - TEGRA_INIT_DATA_INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, TEGRA114_CLK_GR2D), - TEGRA_INIT_DATA_MUX("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR), - TEGRA_INIT_DATA_INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, TEGRA114_CLK_VI), - TEGRA_INIT_DATA_INT8("epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, TEGRA114_CLK_EPP), - TEGRA_INIT_DATA_INT8("msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, TEGRA114_CLK_MSENC), - TEGRA_INIT_DATA_INT8("tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, TEGRA114_CLK_TSEC), - TEGRA_INIT_DATA_INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, TEGRA114_CLK_HOST1X), - TEGRA_INIT_DATA_MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA114_CLK_HDMI), - TEGRA_INIT_DATA_MUX("cilab", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, TEGRA114_CLK_CILAB), - TEGRA_INIT_DATA_MUX("cilcd", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, TEGRA114_CLK_CILCD), - TEGRA_INIT_DATA_MUX("cile", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, TEGRA114_CLK_CILE), - TEGRA_INIT_DATA_MUX("dsialp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, 0, TEGRA114_CLK_DSIALP), - TEGRA_INIT_DATA_MUX("dsiblp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, 0, TEGRA114_CLK_DSIBLP), - TEGRA_INIT_DATA_MUX("tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_TSENSOR), - TEGRA_INIT_DATA_MUX("actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, 0, TEGRA114_CLK_ACTMON), - TEGRA_INIT_DATA_MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, TEGRA114_CLK_EXTERN1), - TEGRA_INIT_DATA_MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, TEGRA114_CLK_EXTERN2), - TEGRA_INIT_DATA_MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, TEGRA114_CLK_EXTERN3), - TEGRA_INIT_DATA_MUX("i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_I2CSLOW), - TEGRA_INIT_DATA_INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SE), - TEGRA_INIT_DATA_INT_FLAGS("mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, TEGRA114_CLK_MSELECT, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("dfll_ref", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_REF), - TEGRA_INIT_DATA_MUX("dfll_soc", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DFLL_SOC), - TEGRA_INIT_DATA_MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_SOC_THERM), - TEGRA_INIT_DATA_XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_HOST_SRC), - TEGRA_INIT_DATA_XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FALCON_SRC), - TEGRA_INIT_DATA_XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_FS_SRC), - TEGRA_INIT_DATA_XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_SS_SRC), - TEGRA_INIT_DATA_XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_XUSB_DEV_SRC), - TEGRA_INIT_DATA_AUDIO("d_audio", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_D_AUDIO), - TEGRA_INIT_DATA_AUDIO("dam0", CLK_SOURCE_DAM0, 108, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM0), - TEGRA_INIT_DATA_AUDIO("dam1", CLK_SOURCE_DAM1, 109, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM1), - TEGRA_INIT_DATA_AUDIO("dam2", CLK_SOURCE_DAM2, 110, TEGRA_PERIPH_ON_APB, TEGRA114_CLK_DAM2), -}; - -static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, TEGRA114_CLK_DISP1), - TEGRA_INIT_DATA_NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, TEGRA114_CLK_DISP2), -}; - -static __init void tegra114_periph_clk_init(void __iomem *clk_base) +static __init void tegra114_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base) { - struct tegra_periph_init_data *data; struct clk *clk; - int i; u32 val; - /* apbdma */ - clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, - 0, 34, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_APBDMA] = clk; - - /* rtc */ - clk = tegra_clk_register_periph_gate("rtc", "clk_32k", - TEGRA_PERIPH_ON_APB | - TEGRA_PERIPH_NO_RESET, clk_base, - 0, 4, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_RTC] = clk; - - /* kbc */ - clk = tegra_clk_register_periph_gate("kbc", "clk_32k", - TEGRA_PERIPH_ON_APB | - TEGRA_PERIPH_NO_RESET, clk_base, - 0, 36, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_KBC] = clk; - - /* timer */ - clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, - 0, 5, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_TIMER] = clk; - - /* kfuse */ - clk = tegra_clk_register_periph_gate("kfuse", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 40, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_KFUSE] = clk; - - /* fuse */ - clk = tegra_clk_register_periph_gate("fuse", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 39, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_FUSE] = clk; - - /* fuse_burn */ - clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 39, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_FUSE_BURN] = clk; - - /* apbif */ - clk = tegra_clk_register_periph_gate("apbif", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 107, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_APBIF] = clk; - - /* hda2hdmi */ - clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 128, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_HDA2HDMI] = clk; - - /* vcp */ - clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, - 29, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_VCP] = clk; - - /* bsea */ - clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, - 0, 62, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_BSEA] = clk; - - /* bsev */ - clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, - 0, 63, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_BSEV] = clk; - - /* mipi-cal */ - clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, - 0, 56, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_MIPI_CAL] = clk; - - /* usbd */ - clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, - 0, 22, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_USBD] = clk; - - /* usb2 */ - clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, - 0, 58, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_USB2] = clk; - - /* usb3 */ - clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, - 0, 59, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_USB3] = clk; - - /* csi */ - clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_CSI] = clk; - - /* isp */ - clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, - 23, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_ISP] = clk; - - /* csus */ - clk = tegra_clk_register_periph_gate("csus", "clk_m", - TEGRA_PERIPH_NO_RESET, clk_base, 0, 92, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_CSUS] = clk; - - /* dds */ - clk = tegra_clk_register_periph_gate("dds", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 150, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_DDS] = clk; - - /* dp2 */ - clk = tegra_clk_register_periph_gate("dp2", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 152, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_DP2] = clk; - - /* dtv */ - clk = tegra_clk_register_periph_gate("dtv", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 79, - periph_clk_enb_refcnt); - clks[TEGRA114_CLK_DTV] = clk; - - /* dsia */ + /* xusb_hs_src */ + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); + val |= BIT(25); /* always select PLLU_60M */ + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); + + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, + 1, 1); + clks[TEGRA114_CLK_XUSB_HS_SRC] = clk; + + /* dsia mux */ clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, ARRAY_SIZE(mux_plld_out0_plld2_out0), CLK_SET_RATE_NO_REPARENT, clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); clks[TEGRA114_CLK_DSIA_MUX] = clk; - clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, - 0, 48, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_DSIA] = clk; - /* dsib */ + /* dsib mux */ clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, ARRAY_SIZE(mux_plld_out0_plld2_out0), CLK_SET_RATE_NO_REPARENT, clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); clks[TEGRA114_CLK_DSIB_MUX] = clk; - clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, - 0, 82, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_DSIB] = clk; - /* xusb_hs_src */ - val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); - val |= BIT(25); /* always select PLLU_60M */ - writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); - - clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, - 1, 1); - clks[TEGRA114_CLK_XUSB_HS_SRC] = clk; - - /* xusb_host */ - clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, - clk_base, 0, 89, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_XUSB_HOST] = clk; - - /* xusb_ss */ - clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, - clk_base, 0, 156, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_XUSB_HOST] = clk; - - /* xusb_dev */ - clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, - clk_base, 0, 95, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_XUSB_DEV] = clk; - - /* emc */ + /* emc mux */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, ARRAY_SIZE(mux_pllmcp_clkm), CLK_SET_RATE_NO_REPARENT, clk_base + CLK_SOURCE_EMC, 29, 3, 0, NULL); - clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, - CLK_IGNORE_UNUSED, 57, periph_clk_enb_refcnt); - clks[TEGRA114_CLK_EMC] = clk; - - for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { - data = &tegra_periph_clk_list[i]; - clk = tegra_clk_register_periph(data->name, - data->parent_names, data->num_parents, &data->periph, - clk_base, data->offset, data->flags); - clks[data->clk_id] = clk; - } - - for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { - data = &tegra_periph_nodiv_clk_list[i]; - - clk = tegra_clk_register_periph_nodiv(data->name, - data->parent_names, data->num_parents, - &data->periph, clk_base, data->offset); - clks[data->clk_id] = clk; - } + tegra_periph_clk_init(clk_base, pmc_base, tegra114_clks, + &pll_p_params); } /* Tegra114 CPU clock and reset control functions */ @@ -2167,7 +1610,7 @@ static void __init tegra114_clock_init(struct device_node *np) tegra114_fixed_clk_init(clk_base); tegra114_pll_init(clk_base, pmc_base); - tegra114_periph_clk_init(clk_base); + tegra114_periph_clk_init(clk_base, pmc_base); tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); tegra114_pmc_clk_init(pmc_base); tegra114_super_clk_init(clk_base); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 31547fde92e4..7c9af8e2c33b 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -973,7 +973,7 @@ static void __init tegra20_periph_clk_init(void) for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; - clk = tegra_clk_register_periph(data->name, data->parent_names, + clk = tegra_clk_register_periph(data->name, data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset, data->flags); clk_register_clkdev(clk, data->con_id, data->dev_id); @@ -983,7 +983,7 @@ static void __init tegra20_periph_clk_init(void) for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { data = &tegra_periph_nodiv_clk_list[i]; clk = tegra_clk_register_periph_nodiv(data->name, - data->parent_names, + data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset); clk_register_clkdev(clk, data->con_id, data->dev_id); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index da540f6dc9c9..c75db196728c 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1616,7 +1616,7 @@ static void __init tegra30_periph_clk_init(void) for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; - clk = tegra_clk_register_periph(data->name, data->parent_names, + clk = tegra_clk_register_periph(data->name, data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset, data->flags); clk_register_clkdev(clk, data->con_id, data->dev_id); @@ -1626,7 +1626,7 @@ static void __init tegra30_periph_clk_init(void) for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { data = &tegra_periph_nodiv_clk_list[i]; clk = tegra_clk_register_periph_nodiv(data->name, - data->parent_names, + data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset); clk_register_clkdev(clk, data->con_id, data->dev_id); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 3306e41e6270..9ec6118e9b99 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -460,7 +460,10 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, struct tegra_periph_init_data { const char *name; int clk_id; - const char **parent_names; + union { + const char **parent_names; + const char *parent_name; + } p; int num_parents; struct tegra_clk_periph periph; u32 offset; @@ -477,7 +480,7 @@ struct tegra_periph_init_data { { \ .name = _name, \ .clk_id = _clk_id, \ - .parent_names = _parent_names, \ + .p.parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names), \ .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \ _mux_flags, _div_shift, \ @@ -597,6 +600,10 @@ void tegra_audio_clk_init(void __iomem *clk_base, void __iomem *pmc_base, struct tegra_clk *tegra_clks, struct tegra_clk_pll_params *pll_params); +void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params); + void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); void tegra114_clock_tune_cpu_trimmers_init(void); -- cgit v1.2.3 From de4f30fd8403cd67449fbb9dc06a3d898fb9f10c Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Tue, 15 Oct 2013 17:19:13 +0300 Subject: clk: tegra: move PMC, fixed clocks to common files Introduce new files for fixed and PMC clocks common between several Tegra SoCs and move Tegra114 to this new infrastructure. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/Makefile | 2 + drivers/clk/tegra/clk-tegra-fixed.c | 111 ++++++++++++++++++++++++++++++ drivers/clk/tegra/clk-tegra-pmc.c | 132 ++++++++++++++++++++++++++++++++++++ drivers/clk/tegra/clk-tegra114.c | 75 +------------------- drivers/clk/tegra/clk.h | 7 ++ 5 files changed, 253 insertions(+), 74 deletions(-) create mode 100644 drivers/clk/tegra/clk-tegra-fixed.c create mode 100644 drivers/clk/tegra/clk-tegra-pmc.c (limited to 'drivers') diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 304ea5df63eb..a02e9a95a4cb 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -8,6 +8,8 @@ obj-y += clk-pll-out.o obj-y += clk-super.o obj-y += clk-tegra-audio.o obj-y += clk-tegra-periph.o +obj-y += clk-tegra-pmc.o +obj-y += clk-tegra-fixed.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c new file mode 100644 index 000000000000..f3b773833429 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, 2013, 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-id.h" + +#define OSC_CTRL 0x50 +#define OSC_CTRL_OSC_FREQ_SHIFT 28 +#define OSC_CTRL_PLL_REF_DIV_SHIFT 26 + +int __init tegra_osc_clk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks, + unsigned long *input_freqs, int num, + unsigned long *osc_freq, + unsigned long *pll_ref_freq) +{ + struct clk *clk; + struct clk **dt_clk; + u32 val, pll_ref_div; + unsigned osc_idx; + + val = readl_relaxed(clk_base + OSC_CTRL); + osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT; + + if (osc_idx < num) + *osc_freq = input_freqs[osc_idx]; + else + *osc_freq = 0; + + if (!*osc_freq) { + WARN_ON(1); + return -EINVAL; + } + + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, tegra_clks); + if (!dt_clk) + return 0; + + clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, + *osc_freq); + *dt_clk = clk; + + /* pll_ref */ + val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; + pll_ref_div = 1 << val; + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, tegra_clks); + if (!dt_clk) + return 0; + + clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", + 0, 1, pll_ref_div); + *dt_clk = clk; + + if (pll_ref_freq) + *pll_ref_freq = *osc_freq / pll_ref_div; + + return 0; +} + +void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) +{ + struct clk *clk; + struct clk **dt_clk; + + /* clk_32k */ + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_32k, tegra_clks); + if (dt_clk) { + clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, + CLK_IS_ROOT, 32768); + *dt_clk = clk; + } + + /* clk_m_div2 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div2, tegra_clks); + if (dt_clk) { + clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", + CLK_SET_RATE_PARENT, 1, 2); + *dt_clk = clk; + } + + /* clk_m_div4 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div4, tegra_clks); + if (dt_clk) { + clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", + CLK_SET_RATE_PARENT, 1, 4); + *dt_clk = clk; + } +} + diff --git a/drivers/clk/tegra/clk-tegra-pmc.c b/drivers/clk/tegra/clk-tegra-pmc.c new file mode 100644 index 000000000000..08b21c1ee867 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-pmc.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2012, 2013, 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-id.h" + +#define PMC_CLK_OUT_CNTRL 0x1a8 +#define PMC_DPD_PADS_ORIDE 0x1c +#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 +#define PMC_CTRL 0 +#define PMC_CTRL_BLINK_ENB 7 +#define PMC_BLINK_TIMER 0x40 + +struct pmc_clk_init_data { + char *mux_name; + char *gate_name; + const char **parents; + int num_parents; + int mux_id; + int gate_id; + char *dev_name; + u8 mux_shift; + u8 gate_shift; +}; + +#define PMC_CLK(_num, _mux_shift, _gate_shift)\ + {\ + .mux_name = "clk_out_" #_num "_mux",\ + .gate_name = "clk_out_" #_num,\ + .parents = clk_out ##_num ##_parents,\ + .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\ + .mux_id = tegra_clk_clk_out_ ##_num ##_mux,\ + .gate_id = tegra_clk_clk_out_ ##_num,\ + .dev_name = "extern" #_num,\ + .mux_shift = _mux_shift,\ + .gate_shift = _gate_shift,\ + } + +static DEFINE_SPINLOCK(clk_out_lock); + +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern1", +}; + +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern2", +}; + +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern3", +}; + +static struct pmc_clk_init_data pmc_clks[] = { + PMC_CLK(1, 6, 2), + PMC_CLK(2, 14, 10), + PMC_CLK(3, 22, 18), +}; + +void __init tegra_pmc_clk_init(void __iomem *pmc_base, + struct tegra_clk *tegra_clks) +{ + struct clk *clk; + struct clk **dt_clk; + int i; + + for (i = 0; i < ARRAY_SIZE(pmc_clks); i++) { + struct pmc_clk_init_data *data; + + data = pmc_clks + i; + + dt_clk = tegra_lookup_dt_id(data->mux_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_mux(NULL, data->mux_name, data->parents, + data->num_parents, CLK_SET_RATE_NO_REPARENT, + pmc_base + PMC_CLK_OUT_CNTRL, data->mux_shift, + 3, 0, &clk_out_lock); + *dt_clk = clk; + + + dt_clk = tegra_lookup_dt_id(data->gate_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_gate(NULL, data->gate_name, data->mux_name, + 0, pmc_base + PMC_CLK_OUT_CNTRL, + data->gate_shift, 0, &clk_out_lock); + *dt_clk = clk; + clk_register_clkdev(clk, data->dev_name, data->gate_name); + } + + /* blink */ + writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); + clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, + pmc_base + PMC_DPD_PADS_ORIDE, + PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); + + dt_clk = tegra_lookup_dt_id(tegra_clk_blink, tegra_clks); + if (!dt_clk) + return; + + clk = clk_register_gate(NULL, "blink", "blink_override", 0, + pmc_base + PMC_CTRL, + PMC_CTRL_BLINK_ENB, 0, NULL); + clk_register_clkdev(clk, "blink", NULL); + *dt_clk = clk; +} + diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 07098597db53..046dbed0c2c5 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -107,13 +107,6 @@ #define PLLC_OUT 0x84 #define PLLM_OUT 0x94 -#define PMC_CLK_OUT_CNTRL 0x1a8 -#define PMC_DPD_PADS_ORIDE 0x1c -#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 -#define PMC_CTRL 0 -#define PMC_CTRL_BLINK_ENB 7 -#define PMC_BLINK_TIMER 0x40 - #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_SHIFT 28 #define OSC_CTRL_PLL_REF_DIV_SHIFT 26 @@ -177,7 +170,6 @@ static DEFINE_SPINLOCK(pll_d_lock); static DEFINE_SPINLOCK(pll_d2_lock); static DEFINE_SPINLOCK(pll_u_lock); static DEFINE_SPINLOCK(pll_re_lock); -static DEFINE_SPINLOCK(clk_out_lock); static DEFINE_SPINLOCK(sysrate_lock); static struct div_nmp pllxc_nmp = { @@ -1199,71 +1191,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_E_OUT0] = clk; } -static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern1", -}; - -static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern2", -}; - -static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern3", -}; - -static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) -{ - struct clk *clk; - - /* clk_out_1 */ - clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, - ARRAY_SIZE(clk_out1_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, - &clk_out_lock); - clks[TEGRA114_CLK_CLK_OUT_1_MUX] = clk; - clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, - &clk_out_lock); - clks[TEGRA114_CLK_CLK_OUT_1] = clk; - - /* clk_out_2 */ - clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, - ARRAY_SIZE(clk_out2_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, - &clk_out_lock); - clks[TEGRA114_CLK_CLK_OUT_2_MUX] = clk; - clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, - &clk_out_lock); - clks[TEGRA114_CLK_CLK_OUT_2] = clk; - - /* clk_out_3 */ - clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, - ARRAY_SIZE(clk_out3_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, - &clk_out_lock); - clks[TEGRA114_CLK_CLK_OUT_3_MUX] = clk; - clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, - &clk_out_lock); - clks[TEGRA114_CLK_CLK_OUT_3] = clk; - - /* blink */ - /* clear the blink timer register to directly output clk_32k */ - writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); - clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, - pmc_base + PMC_DPD_PADS_ORIDE, - PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); - clk = clk_register_gate(NULL, "blink", "blink_override", 0, - pmc_base + PMC_CTRL, - PMC_CTRL_BLINK_ENB, 0, NULL); - clks[TEGRA114_CLK_BLINK] = clk; - -} - static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", "pll_p", "pll_p_out2", "unused", "clk_32k", "pll_m_out1" }; @@ -1612,7 +1539,7 @@ static void __init tegra114_clock_init(struct device_node *np) tegra114_pll_init(clk_base, pmc_base); tegra114_periph_clk_init(clk_base, pmc_base); tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); - tegra114_pmc_clk_init(pmc_base); + tegra_pmc_clk_init(pmc_base, tegra114_clks); tegra114_super_clk_init(clk_base); tegra_add_of_provider(np); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 9ec6118e9b99..2d4881763902 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -604,6 +604,13 @@ void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, struct tegra_clk *tegra_clks, struct tegra_clk_pll_params *pll_params); +void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks); +void tegra_fixed_clk_init(struct tegra_clk *tegra_clks); +int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *tegra_clks, + unsigned long *input_freqs, int num, + unsigned long *osc_freq, + unsigned long *pll_ref_freq); + void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); void tegra114_clock_tune_cpu_trimmers_init(void); -- cgit v1.2.3 From a7c8485a0ebbdce303c6709e208bb4fd08aff8ad Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Tue, 3 Sep 2013 15:46:01 +0300 Subject: clk: tegra: introduce common gen4 super clock Introduce a common function which performs super clock initialization for Tegra114 and beyond. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/Makefile | 1 + drivers/clk/tegra/clk-tegra-super-gen4.c | 149 +++++++++++++++++++++++++++++++ drivers/clk/tegra/clk-tegra114.c | 76 +--------------- drivers/clk/tegra/clk.h | 3 + 4 files changed, 155 insertions(+), 74 deletions(-) create mode 100644 drivers/clk/tegra/clk-tegra-super-gen4.c (limited to 'drivers') diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index a02e9a95a4cb..2d837411dfed 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -10,6 +10,7 @@ obj-y += clk-tegra-audio.o obj-y += clk-tegra-periph.o obj-y += clk-tegra-pmc.o obj-y += clk-tegra-fixed.o +obj-y += clk-tegra-super-gen4.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c new file mode 100644 index 000000000000..05dce4aa2c11 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2012, 2013, 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-id.h" + +#define PLLX_BASE 0xe0 +#define PLLX_MISC 0xe4 +#define PLLX_MISC2 0x514 +#define PLLX_MISC3 0x518 + +#define CCLKG_BURST_POLICY 0x368 +#define CCLKLP_BURST_POLICY 0x370 +#define SCLK_BURST_POLICY 0x028 +#define SYSTEM_CLK_RATE 0x030 + +static DEFINE_SPINLOCK(sysrate_lock); + +static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", + "pll_p", "pll_p_out2", "unused", + "clk_32k", "pll_m_out1" }; + +static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", + "pll_p", "pll_p_out4", "unused", + "unused", "pll_x" }; + +static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", + "pll_p", "pll_p_out4", "unused", + "unused", "pll_x", "pll_x_out0" }; + +static void __init tegra_sclk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks) +{ + struct clk *clk; + struct clk **dt_clk; + + /* SCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_super_mux("sclk", sclk_parents, + ARRAY_SIZE(sclk_parents), + CLK_SET_RATE_PARENT, + clk_base + SCLK_BURST_POLICY, + 0, 4, 0, 0, NULL); + *dt_clk = clk; + } + + /* HCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_hclk, tegra_clks); + if (dt_clk) { + clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, + clk_base + SYSTEM_CLK_RATE, 4, 2, 0, + &sysrate_lock); + clk = clk_register_gate(NULL, "hclk", "hclk_div", + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + clk_base + SYSTEM_CLK_RATE, + 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); + *dt_clk = clk; + } + + /* PCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pclk, tegra_clks); + if (!dt_clk) + return; + + clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, + clk_base + SYSTEM_CLK_RATE, 0, 2, 0, + &sysrate_lock); + clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT | + CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, + 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); + *dt_clk = clk; +} + +void __init tegra_super_clk_gen4_init(void __iomem *clk_base, + void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *params) +{ + struct clk *clk; + struct clk **dt_clk; + + /* CCLKG */ + dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_g, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, + ARRAY_SIZE(cclk_g_parents), + CLK_SET_RATE_PARENT, + clk_base + CCLKG_BURST_POLICY, + 0, 4, 0, 0, NULL); + *dt_clk = clk; + } + + /* CCLKLP */ + dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, + ARRAY_SIZE(cclk_lp_parents), + CLK_SET_RATE_PARENT, + clk_base + CCLKLP_BURST_POLICY, + 0, 4, 8, 9, NULL); + *dt_clk = clk; + } + + tegra_sclk_init(clk_base, tegra_clks); + +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) + /* PLLX */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x, tegra_clks); + if (!dt_clk) + return; + + clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, + pmc_base, CLK_IGNORE_UNUSED, params, NULL); + *dt_clk = clk; + + /* PLLX_OUT0 */ + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x_out0, tegra_clks); + if (!dt_clk) + return; + clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", + CLK_SET_RATE_PARENT, 1, 2); + *dt_clk = clk; +#endif +} + diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 046dbed0c2c5..0b8c9af5bff3 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -114,9 +114,6 @@ #define PLLXC_SW_MAX_P 6 #define CCLKG_BURST_POLICY 0x368 -#define CCLKLP_BURST_POLICY 0x370 -#define SCLK_BURST_POLICY 0x028 -#define SYSTEM_CLK_RATE 0x030 #define UTMIP_PLL_CFG2 0x488 #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) @@ -170,7 +167,6 @@ static DEFINE_SPINLOCK(pll_d_lock); static DEFINE_SPINLOCK(pll_d2_lock); static DEFINE_SPINLOCK(pll_u_lock); static DEFINE_SPINLOCK(pll_re_lock); -static DEFINE_SPINLOCK(sysrate_lock); static struct div_nmp pllxc_nmp = { .divm_shift = 0, @@ -1113,16 +1109,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", CLK_SET_RATE_PARENT, 1, 1); - /* PLLX */ - clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, - pmc, CLK_IGNORE_UNUSED, &pll_x_params, NULL); - clks[TEGRA114_CLK_PLL_X] = clk; - - /* PLLX_OUT0 */ - clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", - CLK_SET_RATE_PARENT, 1, 2); - clks[TEGRA114_CLK_PLL_X_OUT0] = clk; - /* PLLU */ val = readl(clk_base + pll_u_params.base_reg); val &= ~BIT(24); /* disable PLLU_OVERRIDE */ @@ -1191,65 +1177,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clks[TEGRA114_CLK_PLL_E_OUT0] = clk; } -static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", - "pll_p", "pll_p_out2", "unused", - "clk_32k", "pll_m_out1" }; - -static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", - "pll_p", "pll_p_out4", "unused", - "unused", "pll_x" }; - -static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", - "pll_p", "pll_p_out4", "unused", - "unused", "pll_x", "pll_x_out0" }; - -static void __init tegra114_super_clk_init(void __iomem *clk_base) -{ - struct clk *clk; - - /* CCLKG */ - clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, - ARRAY_SIZE(cclk_g_parents), - CLK_SET_RATE_PARENT, - clk_base + CCLKG_BURST_POLICY, - 0, 4, 0, 0, NULL); - clks[TEGRA114_CLK_CCLK_G] = clk; - - /* CCLKLP */ - clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, - ARRAY_SIZE(cclk_lp_parents), - CLK_SET_RATE_PARENT, - clk_base + CCLKLP_BURST_POLICY, - 0, 4, 8, 9, NULL); - clks[TEGRA114_CLK_CCLK_LP] = clk; - - /* SCLK */ - clk = tegra_clk_register_super_mux("sclk", sclk_parents, - ARRAY_SIZE(sclk_parents), - CLK_SET_RATE_PARENT, - clk_base + SCLK_BURST_POLICY, - 0, 4, 0, 0, NULL); - clks[TEGRA114_CLK_SCLK] = clk; - - /* HCLK */ - clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, - clk_base + SYSTEM_CLK_RATE, 4, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT | - CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, - 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clks[TEGRA114_CLK_HCLK] = clk; - - /* PCLK */ - clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, - clk_base + SYSTEM_CLK_RATE, 0, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT | - CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, - 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clks[TEGRA114_CLK_PCLK] = clk; -} - static __init void tegra114_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base) { @@ -1540,7 +1467,8 @@ static void __init tegra114_clock_init(struct device_node *np) tegra114_periph_clk_init(clk_base, pmc_base); tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); tegra_pmc_clk_init(pmc_base, tegra114_clks); - tegra114_super_clk_init(clk_base); + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, + &pll_x_params); tegra_add_of_provider(np); tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 2d4881763902..05abfc5fdff8 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -610,6 +610,9 @@ int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *tegra_clks, unsigned long *input_freqs, int num, unsigned long *osc_freq, unsigned long *pll_ref_freq); +void tegra_super_clk_gen4_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params); void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); -- cgit v1.2.3 From 1bf409159b90804d5e36e4034abc0641555a292f Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 7 Oct 2013 14:49:04 +0300 Subject: clk: tegra: move tegra30 to common infra Move tegra30 to common tegra clock infrastructure. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra30.c | 1298 ++++++++++++--------------------------- 1 file changed, 403 insertions(+), 895 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index c75db196728c..f7ebf2bacdd9 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -23,8 +23,9 @@ #include #include #include - +#include #include "clk.h" +#include "clk-id.h" #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) @@ -100,88 +101,20 @@ #define AUDIO_SYNC_CLK_I2S4 0x4b0 #define AUDIO_SYNC_CLK_SPDIF 0x4b4 -#define PMC_CLK_OUT_CNTRL 0x1a8 - -#define CLK_SOURCE_I2S0 0x1d8 -#define CLK_SOURCE_I2S1 0x100 -#define CLK_SOURCE_I2S2 0x104 -#define CLK_SOURCE_I2S3 0x3bc -#define CLK_SOURCE_I2S4 0x3c0 #define CLK_SOURCE_SPDIF_OUT 0x108 -#define CLK_SOURCE_SPDIF_IN 0x10c -#define CLK_SOURCE_PWM 0x110 #define CLK_SOURCE_D_AUDIO 0x3d0 #define CLK_SOURCE_DAM0 0x3d8 #define CLK_SOURCE_DAM1 0x3dc #define CLK_SOURCE_DAM2 0x3e0 -#define CLK_SOURCE_HDA 0x428 -#define CLK_SOURCE_HDA2CODEC_2X 0x3e4 -#define CLK_SOURCE_SBC1 0x134 -#define CLK_SOURCE_SBC2 0x118 -#define CLK_SOURCE_SBC3 0x11c -#define CLK_SOURCE_SBC4 0x1b4 -#define CLK_SOURCE_SBC5 0x3c8 -#define CLK_SOURCE_SBC6 0x3cc -#define CLK_SOURCE_SATA_OOB 0x420 -#define CLK_SOURCE_SATA 0x424 -#define CLK_SOURCE_NDFLASH 0x160 -#define CLK_SOURCE_NDSPEED 0x3f8 -#define CLK_SOURCE_VFIR 0x168 -#define CLK_SOURCE_SDMMC1 0x150 -#define CLK_SOURCE_SDMMC2 0x154 -#define CLK_SOURCE_SDMMC3 0x1bc -#define CLK_SOURCE_SDMMC4 0x164 -#define CLK_SOURCE_VDE 0x1c8 -#define CLK_SOURCE_CSITE 0x1d4 -#define CLK_SOURCE_LA 0x1f8 -#define CLK_SOURCE_OWR 0x1cc -#define CLK_SOURCE_NOR 0x1d0 -#define CLK_SOURCE_MIPI 0x174 -#define CLK_SOURCE_I2C1 0x124 -#define CLK_SOURCE_I2C2 0x198 -#define CLK_SOURCE_I2C3 0x1b8 -#define CLK_SOURCE_I2C4 0x3c4 -#define CLK_SOURCE_I2C5 0x128 -#define CLK_SOURCE_UARTA 0x178 -#define CLK_SOURCE_UARTB 0x17c -#define CLK_SOURCE_UARTC 0x1a0 -#define CLK_SOURCE_UARTD 0x1c0 -#define CLK_SOURCE_UARTE 0x1c4 -#define CLK_SOURCE_VI 0x148 -#define CLK_SOURCE_VI_SENSOR 0x1a8 -#define CLK_SOURCE_3D 0x158 #define CLK_SOURCE_3D2 0x3b0 #define CLK_SOURCE_2D 0x15c -#define CLK_SOURCE_EPP 0x16c -#define CLK_SOURCE_MPE 0x170 -#define CLK_SOURCE_HOST1X 0x180 -#define CLK_SOURCE_CVE 0x140 -#define CLK_SOURCE_TVO 0x188 -#define CLK_SOURCE_DTV 0x1dc #define CLK_SOURCE_HDMI 0x18c -#define CLK_SOURCE_TVDAC 0x194 -#define CLK_SOURCE_DISP1 0x138 -#define CLK_SOURCE_DISP2 0x13c #define CLK_SOURCE_DSIB 0xd0 -#define CLK_SOURCE_TSENSOR 0x3b8 -#define CLK_SOURCE_ACTMON 0x3e8 -#define CLK_SOURCE_EXTERN1 0x3ec -#define CLK_SOURCE_EXTERN2 0x3f0 -#define CLK_SOURCE_EXTERN3 0x3f4 -#define CLK_SOURCE_I2CSLOW 0x3fc #define CLK_SOURCE_SE 0x42c -#define CLK_SOURCE_MSELECT 0x3b4 #define CLK_SOURCE_EMC 0x19c #define AUDIO_SYNC_DOUBLER 0x49c -#define PMC_CTRL 0 -#define PMC_CTRL_BLINK_ENB 7 - -#define PMC_DPD_PADS_ORIDE 0x1c -#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 -#define PMC_BLINK_TIMER 0x40 - #define UTMIP_PLL_CFG2 0x488 #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) #define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) @@ -238,82 +171,36 @@ static void __iomem *clk_base; static void __iomem *pmc_base; static unsigned long input_freq; -static DEFINE_SPINLOCK(clk_doubler_lock); -static DEFINE_SPINLOCK(clk_out_lock); -static DEFINE_SPINLOCK(pll_div_lock); static DEFINE_SPINLOCK(cml_lock); static DEFINE_SPINLOCK(pll_d_lock); -static DEFINE_SPINLOCK(sysrate_lock); -#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, _gate_flags, _clk_id) -#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, \ - _gate_flags, _clk_id) - -#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_MUX8(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, _gate_flags, _clk_id) -#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_INT(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \ _gate_flags, _clk_id) -#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ - TEGRA_DIVIDER_ROUND_UP, _clk_num, \ - 0, _clk_id) - -#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ _mux_shift, _mux_width, _clk_num, \ _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ _mux_shift, _mux_width, 0, 0, 0, 0, 0,\ _clk_num, _gate_flags, \ _clk_id) -/* - * IDs assigned here must be in sync with DT bindings definition - * for Tegra30 clocks. - */ -enum tegra30_clk { - cpu, rtc = 4, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, ndflash, - sdmmc1, sdmmc4, pwm = 17, i2s2, epp, gr2d = 21, usbd, isp, gr3d, - disp2 = 26, disp1, host1x, vcp, i2s0, cop_cache, mc, ahbdma, apbdma, - kbc = 36, statmon, pmc, kfuse = 40, sbc1, nor, sbc2 = 44, sbc3 = 46, - i2c5, dsia, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, - usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, - pcie, owr, afi, csite, pciex, avpucq, la, dtv = 79, ndspeed, i2cslow, - dsib, irama = 84, iramb, iramc, iramd, cram2, audio_2x = 90, csus = 92, - cdev2, cdev1, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4, - i2c4, sbc5, sbc6, d_audio, apbif, dam0, dam1, dam2, hda2codec_2x, - atomics, audio0_2x, audio1_2x, audio2_2x, audio3_2x, audio4_2x, - spdif_2x, actmon, extern1, extern2, extern3, sata_oob, sata, hda, - se = 127, hda2hdmi, sata_cold, uartb = 160, vfir, spdif_in, spdif_out, - vi, vi_sensor, fuse, fuse_burn, cve, tvo, clk_32k, clk_m, clk_m_div2, - clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_m, pll_m_out1, pll_p, - pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_a, pll_a_out0, - pll_d, pll_d_out0, pll_d2, pll_d2_out0, pll_u, pll_x, pll_x_out0, pll_e, - spdif_in_sync, i2s0_sync, i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, - vimclk_sync, audio0, audio1, audio2, audio3, audio4, spdif, clk_out_1, - clk_out_2, clk_out_3, sclk, blink, cclk_g, cclk_lp, twd, cml0, cml1, - hclk, pclk, clk_out_1_mux = 300, clk_max -}; - static struct clk **clks; /* @@ -685,67 +572,295 @@ static struct tegra_clk_pll_params pll_e_params = { .fixed_rate = 100000000, }; -static void tegra30_clk_measure_input_freq(void) -{ - u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); - u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK; - u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; - - switch (auto_clk_control) { - case OSC_CTRL_OSC_FREQ_12MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 12000000; - break; - case OSC_CTRL_OSC_FREQ_13MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 13000000; - break; - case OSC_CTRL_OSC_FREQ_19_2MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 19200000; - break; - case OSC_CTRL_OSC_FREQ_26MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 26000000; - break; - case OSC_CTRL_OSC_FREQ_16_8MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 16800000; - break; - case OSC_CTRL_OSC_FREQ_38_4MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2); - input_freq = 38400000; - break; - case OSC_CTRL_OSC_FREQ_48MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); - input_freq = 48000000; - break; - default: - pr_err("Unexpected auto clock control value %d", - auto_clk_control); - BUG(); - return; - } -} +static unsigned long tegra30_input_freq[] = { + [0] = 13000000, + [1] = 16800000, + [4] = 19200000, + [5] = 38400000, + [8] = 12000000, + [9] = 48000000, + [12] = 260000000, +}; -static unsigned int tegra30_get_pll_ref_div(void) -{ - u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) & - OSC_CTRL_PLL_REF_DIV_MASK; - - switch (pll_ref_div) { - case OSC_CTRL_PLL_REF_DIV_1: - return 1; - case OSC_CTRL_PLL_REF_DIV_2: - return 2; - case OSC_CTRL_PLL_REF_DIV_4: - return 4; - default: - pr_err("Invalid pll ref divider %d", pll_ref_div); - BUG(); - } - return 0; -} +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "pll_c", .dt_id = TEGRA30_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA30_CLK_PLL_C_OUT1 }, + { .con_id = "pll_p", .dt_id = TEGRA30_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA30_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA30_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA30_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA30_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA30_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA30_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA30_CLK_PLL_X }, + { .con_id = "pll_x_out0", .dt_id = TEGRA30_CLK_PLL_X_OUT0 }, + { .con_id = "pll_u", .dt_id = TEGRA30_CLK_PLL_U }, + { .con_id = "pll_d", .dt_id = TEGRA30_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA30_CLK_PLL_D_OUT0 }, + { .con_id = "pll_d2", .dt_id = TEGRA30_CLK_PLL_D2 }, + { .con_id = "pll_d2_out0", .dt_id = TEGRA30_CLK_PLL_D2_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA30_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA30_CLK_PLL_A_OUT0 }, + { .con_id = "pll_e", .dt_id = TEGRA30_CLK_PLL_E }, + { .con_id = "spdif_in_sync", .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC }, + { .con_id = "i2s0_sync", .dt_id = TEGRA30_CLK_I2S0_SYNC }, + { .con_id = "i2s1_sync", .dt_id = TEGRA30_CLK_I2S1_SYNC }, + { .con_id = "i2s2_sync", .dt_id = TEGRA30_CLK_I2S2_SYNC }, + { .con_id = "i2s3_sync", .dt_id = TEGRA30_CLK_I2S3_SYNC }, + { .con_id = "i2s4_sync", .dt_id = TEGRA30_CLK_I2S4_SYNC }, + { .con_id = "vimclk_sync", .dt_id = TEGRA30_CLK_VIMCLK_SYNC }, + { .con_id = "audio0", .dt_id = TEGRA30_CLK_AUDIO0 }, + { .con_id = "audio1", .dt_id = TEGRA30_CLK_AUDIO1 }, + { .con_id = "audio2", .dt_id = TEGRA30_CLK_AUDIO2 }, + { .con_id = "audio3", .dt_id = TEGRA30_CLK_AUDIO3 }, + { .con_id = "audio4", .dt_id = TEGRA30_CLK_AUDIO4 }, + { .con_id = "spdif", .dt_id = TEGRA30_CLK_SPDIF }, + { .con_id = "audio0_2x", .dt_id = TEGRA30_CLK_AUDIO0_2X }, + { .con_id = "audio1_2x", .dt_id = TEGRA30_CLK_AUDIO1_2X }, + { .con_id = "audio2_2x", .dt_id = TEGRA30_CLK_AUDIO2_2X }, + { .con_id = "audio3_2x", .dt_id = TEGRA30_CLK_AUDIO3_2X }, + { .con_id = "audio4_2x", .dt_id = TEGRA30_CLK_AUDIO4_2X }, + { .con_id = "spdif_2x", .dt_id = TEGRA30_CLK_SPDIF_2X }, + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA30_CLK_EXTERN1 }, + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA30_CLK_EXTERN2 }, + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA30_CLK_EXTERN3 }, + { .con_id = "blink", .dt_id = TEGRA30_CLK_BLINK }, + { .con_id = "cclk_g", .dt_id = TEGRA30_CLK_CCLK_G }, + { .con_id = "cclk_lp", .dt_id = TEGRA30_CLK_CCLK_LP }, + { .con_id = "sclk", .dt_id = TEGRA30_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA30_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA30_CLK_PCLK }, + { .con_id = "twd", .dt_id = TEGRA30_CLK_TWD }, + { .con_id = "emc", .dt_id = TEGRA30_CLK_EMC }, + { .con_id = "clk_32k", .dt_id = TEGRA30_CLK_CLK_32K }, + { .con_id = "clk_m_div2", .dt_id = TEGRA30_CLK_CLK_M_DIV2 }, + { .con_id = "clk_m_div4", .dt_id = TEGRA30_CLK_CLK_M_DIV4 }, + { .con_id = "cml0", .dt_id = TEGRA30_CLK_CML0 }, + { .con_id = "cml1", .dt_id = TEGRA30_CLK_CML1 }, + { .con_id = "clk_m", .dt_id = TEGRA30_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA30_CLK_PLL_REF }, + { .con_id = "csus", .dev_id = "tengra_camera", .dt_id = TEGRA30_CLK_CSUS }, + { .con_id = "vcp", .dev_id = "tegra-avp", .dt_id = TEGRA30_CLK_VCP }, + { .con_id = "bsea", .dev_id = "tegra-avp", .dt_id = TEGRA30_CLK_BSEA }, + { .con_id = "bsev", .dev_id = "tegra-aes", .dt_id = TEGRA30_CLK_BSEV }, + { .con_id = "dsia", .dev_id = "tegradc.0", .dt_id = TEGRA30_CLK_DSIA }, + { .con_id = "csi", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_CSI }, + { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_ISP }, + { .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE }, + { .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI }, + { .con_id = "pciex", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIEX }, + { .con_id = "fuse", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE }, + { .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN }, + { .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF }, + { .con_id = "hda2hdmi", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2HDMI }, + { .dev_id = "tegra-apbdma", .dt_id = TEGRA30_CLK_APBDMA }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA30_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA30_CLK_TIMER }, + { .dev_id = "tegra-kbc", .dt_id = TEGRA30_CLK_KBC }, + { .dev_id = "fsl-tegra-udc", .dt_id = TEGRA30_CLK_USBD }, + { .dev_id = "tegra-ehci.1", .dt_id = TEGRA30_CLK_USB2 }, + { .dev_id = "tegra-ehci.2", .dt_id = TEGRA30_CLK_USB2 }, + { .dev_id = "kfuse-tegra", .dt_id = TEGRA30_CLK_KFUSE }, + { .dev_id = "tegra_sata_cold", .dt_id = TEGRA30_CLK_SATA_COLD }, + { .dev_id = "dtv", .dt_id = TEGRA30_CLK_DTV }, + { .dev_id = "tegra30-i2s.0", .dt_id = TEGRA30_CLK_I2S0 }, + { .dev_id = "tegra30-i2s.1", .dt_id = TEGRA30_CLK_I2S1 }, + { .dev_id = "tegra30-i2s.2", .dt_id = TEGRA30_CLK_I2S2 }, + { .dev_id = "tegra30-i2s.3", .dt_id = TEGRA30_CLK_I2S3 }, + { .dev_id = "tegra30-i2s.4", .dt_id = TEGRA30_CLK_I2S4 }, + { .con_id = "spdif_out", .dev_id = "tegra30-spdif", .dt_id = TEGRA30_CLK_SPDIF_OUT }, + { .con_id = "spdif_in", .dev_id = "tegra30-spdif", .dt_id = TEGRA30_CLK_SPDIF_IN }, + { .con_id = "d_audio", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_D_AUDIO }, + { .dev_id = "tegra30-dam.0", .dt_id = TEGRA30_CLK_DAM0 }, + { .dev_id = "tegra30-dam.1", .dt_id = TEGRA30_CLK_DAM1 }, + { .dev_id = "tegra30-dam.2", .dt_id = TEGRA30_CLK_DAM2 }, + { .con_id = "hda", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA }, + { .con_id = "hda2codec", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2CODEC_2X }, + { .dev_id = "spi_tegra.0", .dt_id = TEGRA30_CLK_SBC1 }, + { .dev_id = "spi_tegra.1", .dt_id = TEGRA30_CLK_SBC2 }, + { .dev_id = "spi_tegra.2", .dt_id = TEGRA30_CLK_SBC3 }, + { .dev_id = "spi_tegra.3", .dt_id = TEGRA30_CLK_SBC4 }, + { .dev_id = "spi_tegra.4", .dt_id = TEGRA30_CLK_SBC5 }, + { .dev_id = "spi_tegra.5", .dt_id = TEGRA30_CLK_SBC6 }, + { .dev_id = "tegra_sata_oob", .dt_id = TEGRA30_CLK_SATA_OOB }, + { .dev_id = "tegra_sata", .dt_id = TEGRA30_CLK_SATA }, + { .dev_id = "tegra_nand", .dt_id = TEGRA30_CLK_NDFLASH }, + { .dev_id = "tegra_nand_speed", .dt_id = TEGRA30_CLK_NDSPEED }, + { .dev_id = "vfir", .dt_id = TEGRA30_CLK_VFIR }, + { .dev_id = "csite", .dt_id = TEGRA30_CLK_CSITE }, + { .dev_id = "la", .dt_id = TEGRA30_CLK_LA }, + { .dev_id = "tegra_w1", .dt_id = TEGRA30_CLK_OWR }, + { .dev_id = "mipi", .dt_id = TEGRA30_CLK_MIPI }, + { .dev_id = "tegra-tsensor", .dt_id = TEGRA30_CLK_TSENSOR }, + { .dev_id = "i2cslow", .dt_id = TEGRA30_CLK_I2CSLOW }, + { .dev_id = "vde", .dt_id = TEGRA30_CLK_VDE }, + { .con_id = "vi", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_VI }, + { .dev_id = "epp", .dt_id = TEGRA30_CLK_EPP }, + { .dev_id = "mpe", .dt_id = TEGRA30_CLK_MPE }, + { .dev_id = "host1x", .dt_id = TEGRA30_CLK_HOST1X }, + { .dev_id = "3d", .dt_id = TEGRA30_CLK_GR3D }, + { .dev_id = "3d2", .dt_id = TEGRA30_CLK_GR3D2 }, + { .dev_id = "2d", .dt_id = TEGRA30_CLK_GR2D }, + { .dev_id = "se", .dt_id = TEGRA30_CLK_SE }, + { .dev_id = "mselect", .dt_id = TEGRA30_CLK_MSELECT }, + { .dev_id = "tegra-nor", .dt_id = TEGRA30_CLK_NOR }, + { .dev_id = "sdhci-tegra.0", .dt_id = TEGRA30_CLK_SDMMC1 }, + { .dev_id = "sdhci-tegra.1", .dt_id = TEGRA30_CLK_SDMMC2 }, + { .dev_id = "sdhci-tegra.2", .dt_id = TEGRA30_CLK_SDMMC3 }, + { .dev_id = "sdhci-tegra.3", .dt_id = TEGRA30_CLK_SDMMC4 }, + { .dev_id = "cve", .dt_id = TEGRA30_CLK_CVE }, + { .dev_id = "tvo", .dt_id = TEGRA30_CLK_TVO }, + { .dev_id = "tvdac", .dt_id = TEGRA30_CLK_TVDAC }, + { .dev_id = "actmon", .dt_id = TEGRA30_CLK_ACTMON }, + { .con_id = "vi_sensor", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_VI_SENSOR }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.0", .dt_id = TEGRA30_CLK_I2C1 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.1", .dt_id = TEGRA30_CLK_I2C2 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.2", .dt_id = TEGRA30_CLK_I2C3 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.3", .dt_id = TEGRA30_CLK_I2C4 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.4", .dt_id = TEGRA30_CLK_I2C5 }, + { .dev_id = "tegra_uart.0", .dt_id = TEGRA30_CLK_UARTA }, + { .dev_id = "tegra_uart.1", .dt_id = TEGRA30_CLK_UARTB }, + { .dev_id = "tegra_uart.2", .dt_id = TEGRA30_CLK_UARTC }, + { .dev_id = "tegra_uart.3", .dt_id = TEGRA30_CLK_UARTD }, + { .dev_id = "tegra_uart.4", .dt_id = TEGRA30_CLK_UARTE }, + { .dev_id = "hdmi", .dt_id = TEGRA30_CLK_HDMI }, + { .dev_id = "extern1", .dt_id = TEGRA30_CLK_EXTERN1 }, + { .dev_id = "extern2", .dt_id = TEGRA30_CLK_EXTERN2 }, + { .dev_id = "extern3", .dt_id = TEGRA30_CLK_EXTERN3 }, + { .dev_id = "pwm", .dt_id = TEGRA30_CLK_PWM }, + { .dev_id = "tegradc.0", .dt_id = TEGRA30_CLK_DISP1 }, + { .dev_id = "tegradc.1", .dt_id = TEGRA30_CLK_DISP2 }, + { .dev_id = "tegradc.1", .dt_id = TEGRA30_CLK_DSIB }, +}; + +static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { + [tegra_clk_clk_32k] = { .dt_id = TEGRA30_CLK_CLK_32K, .present = true }, + [tegra_clk_clk_m] = { .dt_id = TEGRA30_CLK_CLK_M, .present = true }, + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA30_CLK_CLK_M_DIV2, .present = true }, + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA30_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_pll_ref] = { .dt_id = TEGRA30_CLK_PLL_REF, .present = true }, + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC, .present = true }, + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA30_CLK_I2S0_SYNC, .present = true }, + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA30_CLK_I2S1_SYNC, .present = true }, + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA30_CLK_I2S2_SYNC, .present = true }, + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA30_CLK_I2S3_SYNC, .present = true }, + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA30_CLK_I2S4_SYNC, .present = true }, + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA30_CLK_VIMCLK_SYNC, .present = true }, + [tegra_clk_audio0] = { .dt_id = TEGRA30_CLK_AUDIO0, .present = true }, + [tegra_clk_audio1] = { .dt_id = TEGRA30_CLK_AUDIO1, .present = true }, + [tegra_clk_audio2] = { .dt_id = TEGRA30_CLK_AUDIO2, .present = true }, + [tegra_clk_audio3] = { .dt_id = TEGRA30_CLK_AUDIO3, .present = true }, + [tegra_clk_audio4] = { .dt_id = TEGRA30_CLK_AUDIO4, .present = true }, + [tegra_clk_spdif] = { .dt_id = TEGRA30_CLK_SPDIF, .present = true }, + [tegra_clk_audio0_mux] = { .dt_id = TEGRA30_CLK_AUDIO0_MUX, .present = true }, + [tegra_clk_audio1_mux] = { .dt_id = TEGRA30_CLK_AUDIO1_MUX, .present = true }, + [tegra_clk_audio2_mux] = { .dt_id = TEGRA30_CLK_AUDIO2_MUX, .present = true }, + [tegra_clk_audio3_mux] = { .dt_id = TEGRA30_CLK_AUDIO3_MUX, .present = true }, + [tegra_clk_audio4_mux] = { .dt_id = TEGRA30_CLK_AUDIO4_MUX, .present = true }, + [tegra_clk_spdif_mux] = { .dt_id = TEGRA30_CLK_SPDIF_MUX, .present = true }, + [tegra_clk_audio0_2x] = { .dt_id = TEGRA30_CLK_AUDIO0_2X, .present = true }, + [tegra_clk_audio1_2x] = { .dt_id = TEGRA30_CLK_AUDIO1_2X, .present = true }, + [tegra_clk_audio2_2x] = { .dt_id = TEGRA30_CLK_AUDIO2_2X, .present = true }, + [tegra_clk_audio3_2x] = { .dt_id = TEGRA30_CLK_AUDIO3_2X, .present = true }, + [tegra_clk_audio4_2x] = { .dt_id = TEGRA30_CLK_AUDIO4_2X, .present = true }, + [tegra_clk_spdif_2x] = { .dt_id = TEGRA30_CLK_SPDIF_2X, .present = true }, + [tegra_clk_clk_out_1] = { .dt_id = TEGRA30_CLK_CLK_OUT_1, .present = true }, + [tegra_clk_clk_out_2] = { .dt_id = TEGRA30_CLK_CLK_OUT_2, .present = true }, + [tegra_clk_clk_out_3] = { .dt_id = TEGRA30_CLK_CLK_OUT_3, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA30_CLK_BLINK, .present = true }, + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_1_MUX, .present = true }, + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_2_MUX, .present = true }, + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_3_MUX, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA30_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA30_CLK_PCLK, .present = true }, + [tegra_clk_i2s0] = { .dt_id = TEGRA30_CLK_I2S0, .present = true }, + [tegra_clk_i2s1] = { .dt_id = TEGRA30_CLK_I2S1, .present = true }, + [tegra_clk_i2s2] = { .dt_id = TEGRA30_CLK_I2S2, .present = true }, + [tegra_clk_i2s3] = { .dt_id = TEGRA30_CLK_I2S3, .present = true }, + [tegra_clk_i2s4] = { .dt_id = TEGRA30_CLK_I2S4, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA30_CLK_SPDIF_IN, .present = true }, + [tegra_clk_hda] = { .dt_id = TEGRA30_CLK_HDA, .present = true }, + [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA30_CLK_HDA2CODEC_2X, .present = true }, + [tegra_clk_sbc1] = { .dt_id = TEGRA30_CLK_SBC1, .present = true }, + [tegra_clk_sbc2] = { .dt_id = TEGRA30_CLK_SBC2, .present = true }, + [tegra_clk_sbc3] = { .dt_id = TEGRA30_CLK_SBC3, .present = true }, + [tegra_clk_sbc4] = { .dt_id = TEGRA30_CLK_SBC4, .present = true }, + [tegra_clk_sbc5] = { .dt_id = TEGRA30_CLK_SBC5, .present = true }, + [tegra_clk_sbc6] = { .dt_id = TEGRA30_CLK_SBC6, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA30_CLK_NDFLASH, .present = true }, + [tegra_clk_ndspeed] = { .dt_id = TEGRA30_CLK_NDSPEED, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA30_CLK_VFIR, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA30_CLK_LA, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA30_CLK_CSITE, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA30_CLK_OWR, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA30_CLK_MIPI, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA30_CLK_TSENSOR, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA30_CLK_I2CSLOW, .present = true }, + [tegra_clk_vde] = { .dt_id = TEGRA30_CLK_VDE, .present = true }, + [tegra_clk_vi] = { .dt_id = TEGRA30_CLK_VI, .present = true }, + [tegra_clk_epp] = { .dt_id = TEGRA30_CLK_EPP, .present = true }, + [tegra_clk_mpe] = { .dt_id = TEGRA30_CLK_MPE, .present = true }, + [tegra_clk_host1x] = { .dt_id = TEGRA30_CLK_HOST1X, .present = true }, + [tegra_clk_gr2d] = { .dt_id = TEGRA30_CLK_GR2D, .present = true }, + [tegra_clk_gr3d] = { .dt_id = TEGRA30_CLK_GR3D, .present = true }, + [tegra_clk_mselect] = { .dt_id = TEGRA30_CLK_MSELECT, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA30_CLK_NOR, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA30_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA30_CLK_SDMMC2, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA30_CLK_SDMMC3, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA30_CLK_SDMMC4, .present = true }, + [tegra_clk_cve] = { .dt_id = TEGRA30_CLK_CVE, .present = true }, + [tegra_clk_tvo] = { .dt_id = TEGRA30_CLK_TVO, .present = true }, + [tegra_clk_tvdac] = { .dt_id = TEGRA30_CLK_TVDAC, .present = true }, + [tegra_clk_actmon] = { .dt_id = TEGRA30_CLK_ACTMON, .present = true }, + [tegra_clk_vi_sensor] = { .dt_id = TEGRA30_CLK_VI_SENSOR, .present = true }, + [tegra_clk_i2c1] = { .dt_id = TEGRA30_CLK_I2C1, .present = true }, + [tegra_clk_i2c2] = { .dt_id = TEGRA30_CLK_I2C2, .present = true }, + [tegra_clk_i2c3] = { .dt_id = TEGRA30_CLK_I2C3, .present = true }, + [tegra_clk_i2c4] = { .dt_id = TEGRA30_CLK_I2C4, .present = true }, + [tegra_clk_i2c5] = { .dt_id = TEGRA30_CLK_I2C5, .present = true }, + [tegra_clk_uarta] = { .dt_id = TEGRA30_CLK_UARTA, .present = true }, + [tegra_clk_uartb] = { .dt_id = TEGRA30_CLK_UARTB, .present = true }, + [tegra_clk_uartc] = { .dt_id = TEGRA30_CLK_UARTC, .present = true }, + [tegra_clk_uartd] = { .dt_id = TEGRA30_CLK_UARTD, .present = true }, + [tegra_clk_uarte] = { .dt_id = TEGRA30_CLK_UARTE, .present = true }, + [tegra_clk_extern1] = { .dt_id = TEGRA30_CLK_EXTERN1, .present = true }, + [tegra_clk_extern2] = { .dt_id = TEGRA30_CLK_EXTERN2, .present = true }, + [tegra_clk_extern3] = { .dt_id = TEGRA30_CLK_EXTERN3, .present = true }, + [tegra_clk_pwm] = { .dt_id = TEGRA30_CLK_PWM, .present = true }, + [tegra_clk_disp1] = { .dt_id = TEGRA30_CLK_DISP1, .present = true }, + [tegra_clk_disp2] = { .dt_id = TEGRA30_CLK_DISP2, .present = true }, + [tegra_clk_apbdma] = { .dt_id = TEGRA30_CLK_APBDMA, .present = true }, + [tegra_clk_rtc] = { .dt_id = TEGRA30_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA30_CLK_TIMER, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA30_CLK_KBC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA30_CLK_CSUS, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA30_CLK_VCP, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA30_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA30_CLK_BSEV, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA30_CLK_USBD, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA30_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA30_CLK_USB3, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA30_CLK_CSI, .present = true }, + [tegra_clk_isp] = { .dt_id = TEGRA30_CLK_ISP, .present = true }, + [tegra_clk_kfuse] = { .dt_id = TEGRA30_CLK_KFUSE, .present = true }, + [tegra_clk_fuse] = { .dt_id = TEGRA30_CLK_FUSE, .present = true }, + [tegra_clk_fuse_burn] = { .dt_id = TEGRA30_CLK_FUSE_BURN, .present = true }, + [tegra_clk_apbif] = { .dt_id = TEGRA30_CLK_APBIF, .present = true }, + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA30_CLK_HDA2HDMI, .present = true }, + [tegra_clk_sata_cold] = { .dt_id = TEGRA30_CLK_SATA_COLD, .present = true }, + [tegra_clk_sata_oob] = { .dt_id = TEGRA30_CLK_SATA_OOB, .present = true }, + [tegra_clk_sata] = { .dt_id = TEGRA30_CLK_SATA, .present = true }, + [tegra_clk_dtv] = { .dt_id = TEGRA30_CLK_DTV, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA30_CLK_PLL_P, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA30_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2] = { .dt_id = TEGRA30_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA30_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA30_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, + +}; static void tegra30_utmi_param_configure(void) { @@ -809,8 +924,7 @@ static void __init tegra30_pll_init(void) /* PLLC */ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, &pll_c_params, NULL); - clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; + clks[TEGRA30_CLK_PLL_C] = clk; /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", @@ -819,69 +933,13 @@ static void __init tegra30_pll_init(void) clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_c_out1", NULL); - clks[pll_c_out1] = clk; - - /* PLLP */ - clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc_base, 0, - &pll_p_params, NULL); - clk_register_clkdev(clk, "pll_p", NULL); - clks[pll_p] = clk; - - /* PLLP_OUT1 */ - clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", - clk_base + PLLP_OUTA, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out1", NULL); - clks[pll_p_out1] = clk; - - /* PLLP_OUT2 */ - clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", - clk_base + PLLP_OUTA, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out2", NULL); - clks[pll_p_out2] = clk; - - /* PLLP_OUT3 */ - clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", - clk_base + PLLP_OUTB, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out3", NULL); - clks[pll_p_out3] = clk; - - /* PLLP_OUT4 */ - clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", - clk_base + PLLP_OUTB, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out4", NULL); - clks[pll_p_out4] = clk; + clks[TEGRA30_CLK_PLL_C_OUT1] = clk; /* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, &pll_m_params, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + clks[TEGRA30_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -890,68 +948,44 @@ static void __init tegra30_pll_init(void) clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_m_out1", NULL); - clks[pll_m_out1] = clk; + clks[TEGRA30_CLK_PLL_M_OUT1] = clk; /* PLLX */ clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0, &pll_x_params, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; + clks[TEGRA30_CLK_PLL_X] = clk; /* PLLX_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_x_out0", NULL); - clks[pll_x_out0] = clk; + clks[TEGRA30_CLK_PLL_X_OUT0] = clk; /* PLLU */ clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0, &pll_u_params, NULL); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + clks[TEGRA30_CLK_PLL_U] = clk; tegra30_utmi_param_configure(); /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0, &pll_d_params, &pll_d_lock); - clk_register_clkdev(clk, "pll_d", NULL); - clks[pll_d] = clk; + clks[TEGRA30_CLK_PLL_D] = clk; /* PLLD_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d_out0", NULL); - clks[pll_d_out0] = clk; + clks[TEGRA30_CLK_PLL_D_OUT0] = clk; /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, &pll_d2_params, NULL); - clk_register_clkdev(clk, "pll_d2", NULL); - clks[pll_d2] = clk; + clks[TEGRA30_CLK_PLL_D2] = clk; /* PLLD2_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d2_out0", NULL); - clks[pll_d2_out0] = clk; - - /* PLLA */ - clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc_base, - 0, &pll_a_params, NULL); - clk_register_clkdev(clk, "pll_a", NULL); - clks[pll_a] = clk; - - /* PLLA_OUT0 */ - clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", - clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, NULL); - clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", - clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | - CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_a_out0", NULL); - clks[pll_a_out0] = clk; + clks[TEGRA30_CLK_PLL_D2_OUT0] = clk; /* PLLE */ clk = clk_register_mux(NULL, "pll_e_mux", pll_e_parents, @@ -960,256 +994,7 @@ static void __init tegra30_pll_init(void) clk_base + PLLE_AUX, 2, 1, 0, NULL); clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, CLK_GET_RATE_NOCACHE, &pll_e_params, NULL); - clk_register_clkdev(clk, "pll_e", NULL); - clks[pll_e] = clk; -} - -static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", - "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",}; -static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern1", }; -static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern2", }; -static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern3", }; - -static void __init tegra30_audio_clk_init(void) -{ - struct clk *clk; - - /* spdif_in_sync */ - clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, - 24000000); - clk_register_clkdev(clk, "spdif_in_sync", NULL); - clks[spdif_in_sync] = clk; - - /* i2s0_sync */ - clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s0_sync", NULL); - clks[i2s0_sync] = clk; - - /* i2s1_sync */ - clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s1_sync", NULL); - clks[i2s1_sync] = clk; - - /* i2s2_sync */ - clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s2_sync", NULL); - clks[i2s2_sync] = clk; - - /* i2s3_sync */ - clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s3_sync", NULL); - clks[i2s3_sync] = clk; - - /* i2s4_sync */ - clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s4_sync", NULL); - clks[i2s4_sync] = clk; - - /* vimclk_sync */ - clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); - clk_register_clkdev(clk, "vimclk_sync", NULL); - clks[vimclk_sync] = clk; - - /* audio0 */ - clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S0, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio0", NULL); - clks[audio0] = clk; - - /* audio1 */ - clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S1, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio1", NULL); - clks[audio1] = clk; - - /* audio2 */ - clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S2, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio2", NULL); - clks[audio2] = clk; - - /* audio3 */ - clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S3, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio3", NULL); - clks[audio3] = clk; - - /* audio4 */ - clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S4, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio4", NULL); - clks[audio4] = clk; - - /* spdif */ - clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, - clk_base + AUDIO_SYNC_CLK_SPDIF, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "spdif", NULL); - clks[spdif] = clk; - - /* audio0_2x */ - clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 113, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio0_2x", NULL); - clks[audio0_2x] = clk; - - /* audio1_2x */ - clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 114, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio1_2x", NULL); - clks[audio1_2x] = clk; - - /* audio2_2x */ - clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 115, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio2_2x", NULL); - clks[audio2_2x] = clk; - - /* audio3_2x */ - clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 116, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio3_2x", NULL); - clks[audio3_2x] = clk; - - /* audio4_2x */ - clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 117, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio4_2x", NULL); - clks[audio4_2x] = clk; - - /* spdif_2x */ - clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 118, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "spdif_2x", NULL); - clks[spdif_2x] = clk; -} - -static void __init tegra30_pmc_clk_init(void) -{ - struct clk *clk; - - /* clk_out_1 */ - clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, - ARRAY_SIZE(clk_out1_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, - &clk_out_lock); - clks[clk_out_1_mux] = clk; - clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern1", "clk_out_1"); - clks[clk_out_1] = clk; - - /* clk_out_2 */ - clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, - ARRAY_SIZE(clk_out2_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, - &clk_out_lock); - clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern2", "clk_out_2"); - clks[clk_out_2] = clk; - - /* clk_out_3 */ - clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, - ARRAY_SIZE(clk_out3_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, - &clk_out_lock); - clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern3", "clk_out_3"); - clks[clk_out_3] = clk; - - /* blink */ - writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); - clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, - pmc_base + PMC_DPD_PADS_ORIDE, - PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); - clk = clk_register_gate(NULL, "blink", "blink_override", 0, - pmc_base + PMC_CTRL, - PMC_CTRL_BLINK_ENB, 0, NULL); - clk_register_clkdev(clk, "blink", NULL); - clks[blink] = clk; - + clks[TEGRA30_CLK_PLL_E] = clk; } static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", @@ -1260,8 +1045,7 @@ static void __init tegra30_super_clk_init(void) CLK_SET_RATE_PARENT, clk_base + CCLKG_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "cclk_g", NULL); - clks[cclk_g] = clk; + clks[TEGRA30_CLK_CCLK_G] = clk; /* * Clock input to cclk_lp divided from pll_p using @@ -1297,8 +1081,7 @@ static void __init tegra30_super_clk_init(void) clk_base + CCLKLP_BURST_POLICY, TEGRA_DIVIDER_2, 4, 8, 9, NULL); - clk_register_clkdev(clk, "cclk_lp", NULL); - clks[cclk_lp] = clk; + clks[TEGRA30_CLK_CCLK_LP] = clk; /* SCLK */ clk = tegra_clk_register_super_mux("sclk", sclk_parents, @@ -1306,142 +1089,42 @@ static void __init tegra30_super_clk_init(void) CLK_SET_RATE_PARENT, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "sclk", NULL); - clks[sclk] = clk; - - /* HCLK */ - clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, - clk_base + SYSTEM_CLK_RATE, 4, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, - clk_base + SYSTEM_CLK_RATE, 7, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "hclk", NULL); - clks[hclk] = clk; - - /* PCLK */ - clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, - clk_base + SYSTEM_CLK_RATE, 0, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, - clk_base + SYSTEM_CLK_RATE, 3, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "pclk", NULL); - clks[pclk] = clk; + clks[TEGRA30_CLK_SCLK] = clk; /* twd */ clk = clk_register_fixed_factor(NULL, "twd", "cclk_g", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "twd", NULL); - clks[twd] = clk; + clks[TEGRA30_CLK_TWD] = clk; + + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra30_clks, NULL); } static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", "clk_m" }; static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; -static const char *i2s0_parents[] = { "pll_a_out0", "audio0_2x", "pll_p", - "clk_m" }; -static const char *i2s1_parents[] = { "pll_a_out0", "audio1_2x", "pll_p", - "clk_m" }; -static const char *i2s2_parents[] = { "pll_a_out0", "audio2_2x", "pll_p", - "clk_m" }; -static const char *i2s3_parents[] = { "pll_a_out0", "audio3_2x", "pll_p", - "clk_m" }; -static const char *i2s4_parents[] = { "pll_a_out0", "audio4_2x", "pll_p", - "clk_m" }; static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", "clk_m" }; -static const char *spdif_in_parents[] = { "pll_p", "pll_c", "pll_m" }; -static const char *mux_pllpc_clk32k_clkm[] = { "pll_p", "pll_c", "clk_32k", - "clk_m" }; -static const char *mux_pllpc_clkm_clk32k[] = { "pll_p", "pll_c", "clk_m", - "clk_32k" }; static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; -static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", - "clk_m" }; -static const char *mux_pllp_clkm[] = { "pll_p", "unused", "unused", "clk_m" }; static const char *mux_pllpmdacd2_clkm[] = { "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", "pll_d2_out0", "clk_m" }; -static const char *mux_plla_clk32k_pllp_clkm_plle[] = { "pll_a_out0", - "clk_32k", "pll_p", - "clk_m", "pll_e" }; static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", "pll_d2_out0" }; static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", i2s0_parents, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, i2s0), - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", i2s2_parents, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", i2s3_parents, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, i2s3), - TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", i2s4_parents, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, i2s4), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("d_audio", "d_audio", "tegra30-ahub", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, 0, d_audio), - TEGRA_INIT_DATA_MUX("dam0", NULL, "tegra30-dam.0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, 0, dam0), - TEGRA_INIT_DATA_MUX("dam1", NULL, "tegra30-dam.1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, 0, dam1), - TEGRA_INIT_DATA_MUX("dam2", NULL, "tegra30-dam.2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, 0, dam2), - TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA, 125, 0, hda), - TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, 0, hda2codec_2x), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("sbc5", NULL, "spi_tegra.4", mux_pllpcm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, sbc5), - TEGRA_INIT_DATA_MUX("sbc6", NULL, "spi_tegra.5", mux_pllpcm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, sbc6), - TEGRA_INIT_DATA_MUX("sata_oob", NULL, "tegra_sata_oob", mux_pllpcm_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, sata_oob), - TEGRA_INIT_DATA_MUX("sata", NULL, "tegra_sata", mux_pllpcm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, sata), - TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, ndflash), - TEGRA_INIT_DATA_MUX("ndspeed", NULL, "tegra_nand_speed", mux_pllpcm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, ndspeed), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, csite), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, la), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllpc_clkm_clk32k, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, tsensor), - TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllpc_clk32k_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, i2cslow), - TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, 0, vde), - TEGRA_INIT_DATA_INT("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, 0, vi), - TEGRA_INIT_DATA_INT("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, 0, epp), - TEGRA_INIT_DATA_INT("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, 0, mpe), - TEGRA_INIT_DATA_INT("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, 0, host1x), - TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, TEGRA_PERIPH_MANUAL_RESET, gr3d), - TEGRA_INIT_DATA_INT("3d2", NULL, "3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, TEGRA_PERIPH_MANUAL_RESET, gr3d2), - TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, 0, gr2d), - TEGRA_INIT_DATA_INT("se", NULL, "se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, 0, se), - TEGRA_INIT_DATA_MUX("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, mselect), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, 0, nor), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, 0, sdmmc4), - TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, 0, cve), - TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, 0, tvo), - TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, 0, tvdac), - TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllpc_clk32k_clkm, CLK_SOURCE_ACTMON, 119, 0, actmon), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, TEGRA_PERIPH_ON_APB, i2c1), - TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, TEGRA_PERIPH_ON_APB, i2c2), - TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3), - TEGRA_INIT_DATA_DIV16("i2c4", "div-clk", "tegra-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, TEGRA_PERIPH_ON_APB, i2c4), - TEGRA_INIT_DATA_DIV16("i2c5", "div-clk", "tegra-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, TEGRA_PERIPH_ON_APB, i2c5), - TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 6, uarta), - TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 7, uartb), - TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 55, uartc), - TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 65, uartd), - TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 66, uarte), - TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi), - TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, extern1), - TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, extern2), - TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, extern3), - TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, 0, pwm), + TEGRA_INIT_DATA_MUX("spdif_out", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_SPDIF_OUT), + TEGRA_INIT_DATA_MUX("d_audio", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, 0, TEGRA30_CLK_D_AUDIO), + TEGRA_INIT_DATA_MUX("dam0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, 0, TEGRA30_CLK_DAM0), + TEGRA_INIT_DATA_MUX("dam1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, 0, TEGRA30_CLK_DAM1), + TEGRA_INIT_DATA_MUX("dam2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, 0, TEGRA30_CLK_DAM2), + TEGRA_INIT_DATA_INT("3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, TEGRA_PERIPH_MANUAL_RESET, TEGRA30_CLK_GR3D2), + TEGRA_INIT_DATA_INT("se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, 0, TEGRA30_CLK_SE), + TEGRA_INIT_DATA_MUX8("hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA30_CLK_HDMI), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, 0, disp2), - TEGRA_INIT_DATA_NODIV("dsib", NULL, "tegradc.1", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, 0, dsib), + TEGRA_INIT_DATA_NODIV("dsib", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, 0, TEGRA30_CLK_DSIB), }; static void __init tegra30_periph_clk_init(void) @@ -1450,158 +1133,25 @@ static void __init tegra30_periph_clk_init(void) struct clk *clk; int i; - /* apbdma */ - clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, 0, 34, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-apbdma"); - clks[apbdma] = clk; - - /* rtc */ - clk = tegra_clk_register_periph_gate("rtc", "clk_32k", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 4, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "rtc-tegra"); - clks[rtc] = clk; - - /* timer */ - clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0, - 5, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "timer"); - clks[timer] = clk; - - /* kbc */ - clk = tegra_clk_register_periph_gate("kbc", "clk_32k", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 36, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-kbc"); - clks[kbc] = clk; - - /* csus */ - clk = tegra_clk_register_periph_gate("csus", "clk_m", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 92, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csus", "tengra_camera"); - clks[csus] = clk; - - /* vcp */ - clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, 29, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "vcp", "tegra-avp"); - clks[vcp] = clk; - - /* bsea */ - clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, 0, - 62, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsea", "tegra-avp"); - clks[bsea] = clk; - - /* bsev */ - clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, 0, - 63, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsev", "tegra-aes"); - clks[bsev] = clk; - - /* usbd */ - clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, - 22, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); - clks[usbd] = clk; - - /* usb2 */ - clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, - 58, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.1"); - clks[usb2] = clk; - - /* usb3 */ - clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, - 59, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.2"); - clks[usb3] = clk; - /* dsia */ clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base, 0, 48, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "dsia", "tegradc.0"); - clks[dsia] = clk; - - /* csi */ - clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csi", "tegra_camera"); - clks[csi] = clk; - - /* isp */ - clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "isp", "tegra_camera"); - clks[isp] = clk; + clks[TEGRA30_CLK_DSIA] = clk; /* pcie */ clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, 70, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pcie", "tegra-pcie"); - clks[pcie] = clk; + clks[TEGRA30_CLK_PCIE] = clk; /* afi */ clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "afi", "tegra-pcie"); - clks[afi] = clk; + clks[TEGRA30_CLK_AFI] = clk; /* pciex */ clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0, 74, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pciex", "tegra-pcie"); - clks[pciex] = clk; - - /* kfuse */ - clk = tegra_clk_register_periph_gate("kfuse", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 40, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "kfuse-tegra"); - clks[kfuse] = clk; - - /* fuse */ - clk = tegra_clk_register_periph_gate("fuse", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 39, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "fuse", "fuse-tegra"); - clks[fuse] = clk; - - /* fuse_burn */ - clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 39, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "fuse_burn", "fuse-tegra"); - clks[fuse_burn] = clk; - - /* apbif */ - clk = tegra_clk_register_periph_gate("apbif", "clk_m", 0, - clk_base, 0, 107, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "apbif", "tegra30-ahub"); - clks[apbif] = clk; - - /* hda2hdmi */ - clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 128, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "hda2hdmi", "tegra30-hda"); - clks[hda2hdmi] = clk; - - /* sata_cold */ - clk = tegra_clk_register_periph_gate("sata_cold", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 129, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra_sata_cold"); - clks[sata_cold] = clk; - - /* dtv */ - clk = tegra_clk_register_periph_gate("dtv", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 79, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "dtv"); - clks[dtv] = clk; + clks[TEGRA30_CLK_PCIEX] = clk; /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, @@ -1611,15 +1161,23 @@ static void __init tegra30_periph_clk_init(void) 30, 2, 0, NULL); clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, 57, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "emc", NULL); - clks[emc] = clk; + clks[TEGRA30_CLK_EMC] = clk; + + /* cml0 */ + clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, + 0, 0, &cml_lock); + clks[TEGRA30_CLK_CML0] = clk; + + /* cml1 */ + clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, + 1, 0, &cml_lock); + clks[TEGRA30_CLK_CML1] = clk; for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; clk = tegra_clk_register_periph(data->name, data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset, data->flags); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } @@ -1629,65 +1187,10 @@ static void __init tegra30_periph_clk_init(void) data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } -} - -static void __init tegra30_fixed_clk_init(void) -{ - struct clk *clk; - - /* clk_32k */ - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, - 32768); - clk_register_clkdev(clk, "clk_32k", NULL); - clks[clk_32k] = clk; - - /* clk_m_div2 */ - clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", - CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "clk_m_div2", NULL); - clks[clk_m_div2] = clk; - - /* clk_m_div4 */ - clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", - CLK_SET_RATE_PARENT, 1, 4); - clk_register_clkdev(clk, "clk_m_div4", NULL); - clks[clk_m_div4] = clk; - - /* cml0 */ - clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, - 0, 0, &cml_lock); - clk_register_clkdev(clk, "cml0", NULL); - clks[cml0] = clk; - /* cml1 */ - clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, - 1, 0, &cml_lock); - clk_register_clkdev(clk, "cml1", NULL); - clks[cml1] = clk; -} - -static void __init tegra30_osc_clk_init(void) -{ - struct clk *clk; - unsigned int pll_ref_div; - - tegra30_clk_measure_input_freq(); - - /* clk_m */ - clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, - input_freq); - clk_register_clkdev(clk, "clk_m", NULL); - clks[clk_m] = clk; - - /* pll_ref */ - pll_ref_div = tegra30_get_pll_ref_div(); - clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", - CLK_SET_RATE_PARENT, 1, pll_ref_div); - clk_register_clkdev(clk, "pll_ref", NULL); - clks[pll_ref] = clk; + tegra_periph_clk_init(clk_base, pmc_base, tegra30_clks, &pll_p_params); } /* Tegra30 CPU clock and reset control functions */ @@ -1829,48 +1332,48 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { }; static struct tegra_clk_init_table init_table[] __initdata = { - {uarta, pll_p, 408000000, 0}, - {uartb, pll_p, 408000000, 0}, - {uartc, pll_p, 408000000, 0}, - {uartd, pll_p, 408000000, 0}, - {uarte, pll_p, 408000000, 0}, - {pll_a, clk_max, 564480000, 1}, - {pll_a_out0, clk_max, 11289600, 1}, - {extern1, pll_a_out0, 0, 1}, - {clk_out_1_mux, extern1, 0, 0}, - {clk_out_1, clk_max, 0, 1}, - {blink, clk_max, 0, 1}, - {i2s0, pll_a_out0, 11289600, 0}, - {i2s1, pll_a_out0, 11289600, 0}, - {i2s2, pll_a_out0, 11289600, 0}, - {i2s3, pll_a_out0, 11289600, 0}, - {i2s4, pll_a_out0, 11289600, 0}, - {sdmmc1, pll_p, 48000000, 0}, - {sdmmc2, pll_p, 48000000, 0}, - {sdmmc3, pll_p, 48000000, 0}, - {pll_m, clk_max, 0, 1}, - {pclk, clk_max, 0, 1}, - {csite, clk_max, 0, 1}, - {emc, clk_max, 0, 1}, - {mselect, clk_max, 0, 1}, - {sbc1, pll_p, 100000000, 0}, - {sbc2, pll_p, 100000000, 0}, - {sbc3, pll_p, 100000000, 0}, - {sbc4, pll_p, 100000000, 0}, - {sbc5, pll_p, 100000000, 0}, - {sbc6, pll_p, 100000000, 0}, - {host1x, pll_c, 150000000, 0}, - {disp1, pll_p, 600000000, 0}, - {disp2, pll_p, 600000000, 0}, - {twd, clk_max, 0, 1}, - {gr2d, pll_c, 300000000, 0}, - {gr3d, pll_c, 300000000, 0}, - {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ + {TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 1}, + {TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 1}, + {TEGRA30_CLK_EXTERN1, TEGRA30_CLK_PLL_A_OUT0, 0, 1}, + {TEGRA30_CLK_CLK_OUT_1_MUX, TEGRA30_CLK_EXTERN1, 0, 0}, + {TEGRA30_CLK_CLK_OUT_1, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_BLINK, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_I2S0, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S1, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S2, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S3, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S4, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0}, + {TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0}, + {TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0}, + {TEGRA30_CLK_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_EMC, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC3, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0}, + {TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0}, + {TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0}, + {TEGRA30_CLK_TWD, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0}, + {TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0}, + {TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry. */ }; static void __init tegra30_clock_apply_init_table(void) { - tegra_init_from_table(init_table, clks, clk_max); + tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX); } /* @@ -1879,19 +1382,19 @@ static void __init tegra30_clock_apply_init_table(void) * table under two names. */ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { - TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), - TEGRA_CLK_DUPLICATE(bsev, "tegra-avp", "bsev"), - TEGRA_CLK_DUPLICATE(bsev, "nvavp", "bsev"), - TEGRA_CLK_DUPLICATE(vde, "tegra-aes", "vde"), - TEGRA_CLK_DUPLICATE(bsea, "tegra-aes", "bsea"), - TEGRA_CLK_DUPLICATE(bsea, "nvavp", "bsea"), - TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL), - TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"), - TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"), - TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"), - TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */ + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "utmip-pad", NULL), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "tegra-ehci.0", NULL), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "tegra-otg", NULL), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEV, "tegra-avp", "bsev"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEV, "nvavp", "bsev"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VDE, "tegra-aes", "vde"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "tegra-aes", "bsea"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "nvavp", "bsea"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML1, "tegra_sata_cml", NULL), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML0, "tegra_pcie", "cml"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_PCIEX, "tegra_pcie", "pciex"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VCP, "nvavp", "vcp"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */ }; static const struct of_device_id pmc_match[] __initconst = { @@ -1921,21 +1424,26 @@ static void __init tegra30_clock_init(struct device_node *np) BUG(); } - clks = tegra_clk_init(clk_max, TEGRA30_CLK_PERIPH_BANKS); + clks = tegra_clk_init(TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_PERIPH_BANKS); if (!clks) return; - tegra30_osc_clk_init(); - tegra30_fixed_clk_init(); + if (tegra_osc_clk_init(clk_base, tegra30_clks, tegra30_input_freq, + ARRAY_SIZE(tegra30_input_freq), &input_freq, NULL) < 0) + return; + + + tegra_fixed_clk_init(tegra30_clks); tegra30_pll_init(); tegra30_super_clk_init(); tegra30_periph_clk_init(); - tegra30_audio_clk_init(); - tegra30_pmc_clk_init(); + tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, &pll_a_params); + tegra_pmc_clk_init(pmc_base, tegra30_clks); - tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); + tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra30_clock_apply_init_table; -- cgit v1.2.3 From 540fc26a02a950a523a62a16d75b87f0e2103584 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 7 Oct 2013 14:49:10 +0300 Subject: clk: tegra: move tegra20 to common infra Move tegra20 to common tegra clock infrastructure. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra20.c | 657 ++++++++++++++++------------------------ 1 file changed, 255 insertions(+), 402 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 7c9af8e2c33b..be5bdbab78a6 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -22,8 +22,10 @@ #include #include #include +#include #include "clk.h" +#include "clk-id.h" #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (3<<30) @@ -94,34 +96,15 @@ #define CLK_SOURCE_I2S1 0x100 #define CLK_SOURCE_I2S2 0x104 -#define CLK_SOURCE_SPDIF_OUT 0x108 -#define CLK_SOURCE_SPDIF_IN 0x10c #define CLK_SOURCE_PWM 0x110 #define CLK_SOURCE_SPI 0x114 -#define CLK_SOURCE_SBC1 0x134 -#define CLK_SOURCE_SBC2 0x118 -#define CLK_SOURCE_SBC3 0x11c -#define CLK_SOURCE_SBC4 0x1b4 #define CLK_SOURCE_XIO 0x120 #define CLK_SOURCE_TWC 0x12c #define CLK_SOURCE_IDE 0x144 -#define CLK_SOURCE_NDFLASH 0x160 -#define CLK_SOURCE_VFIR 0x168 -#define CLK_SOURCE_SDMMC1 0x150 -#define CLK_SOURCE_SDMMC2 0x154 -#define CLK_SOURCE_SDMMC3 0x1bc -#define CLK_SOURCE_SDMMC4 0x164 -#define CLK_SOURCE_CVE 0x140 -#define CLK_SOURCE_TVO 0x188 -#define CLK_SOURCE_TVDAC 0x194 #define CLK_SOURCE_HDMI 0x18c #define CLK_SOURCE_DISP1 0x138 #define CLK_SOURCE_DISP2 0x13c #define CLK_SOURCE_CSITE 0x1d4 -#define CLK_SOURCE_LA 0x1f8 -#define CLK_SOURCE_OWR 0x1cc -#define CLK_SOURCE_NOR 0x1d0 -#define CLK_SOURCE_MIPI 0x174 #define CLK_SOURCE_I2C1 0x124 #define CLK_SOURCE_I2C2 0x198 #define CLK_SOURCE_I2C3 0x1b8 @@ -131,24 +114,10 @@ #define CLK_SOURCE_UARTC 0x1a0 #define CLK_SOURCE_UARTD 0x1c0 #define CLK_SOURCE_UARTE 0x1c4 -#define CLK_SOURCE_3D 0x158 -#define CLK_SOURCE_2D 0x15c -#define CLK_SOURCE_MPE 0x170 -#define CLK_SOURCE_EPP 0x16c -#define CLK_SOURCE_HOST1X 0x180 -#define CLK_SOURCE_VDE 0x1c8 -#define CLK_SOURCE_VI 0x148 -#define CLK_SOURCE_VI_SENSOR 0x1a8 #define CLK_SOURCE_EMC 0x19c #define AUDIO_SYNC_CLK 0x38 -#define PMC_CTRL 0x0 -#define PMC_CTRL_BLINK_ENB 7 -#define PMC_DPD_PADS_ORIDE 0x1c -#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 -#define PMC_BLINK_TIMER 0x40 - /* Tegra CPU clock and reset control regs */ #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 @@ -171,57 +140,28 @@ static struct cpu_clk_suspend_context { static void __iomem *clk_base; static void __iomem *pmc_base; -static DEFINE_SPINLOCK(pll_div_lock); -static DEFINE_SPINLOCK(sysrate_lock); - -#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, \ _gate_flags, _clk_id) -#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \ - _clk_num, _gate_flags, \ - _clk_id) - -#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_DIV16(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ _clk_num, _gate_flags, \ _clk_id) -#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ _mux_shift, _mux_width, _clk_num, \ _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ _mux_shift, _mux_width, 0, 0, 0, 0, 0, \ _clk_num, _gate_flags, \ _clk_id) -/* IDs assigned here must be in sync with DT bindings definition - * for Tegra20 clocks . - */ -enum tegra20_clk { - cpu, ac97 = 3, rtc, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, - ndflash, sdmmc1, sdmmc4, twc, pwm, i2s2, epp, gr2d = 21, usbd, isp, - gr3d, ide, disp2, disp1, host1x, vcp, cache2 = 31, mem, ahbdma, apbdma, - kbc = 36, stat_mon, pmc, fuse, kfuse, sbc1, nor, spi, sbc2, xio, sbc3, - dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, - usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, - pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb, - iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev2, cdev1, - uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve, - osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0, - pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1, - pll_p, pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_s, pll_u, - pll_x, cop, audio, pll_ref, twd, clk_max, -}; - static struct clk **clks; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { @@ -485,6 +425,157 @@ static struct tegra_clk_pll_params pll_e_params = { .fixed_rate = 100000000, }; +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "pll_c", .dt_id = TEGRA20_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA20_CLK_PLL_C_OUT1 }, + { .con_id = "pll_p", .dt_id = TEGRA20_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA20_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA20_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA20_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA20_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA20_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA20_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA20_CLK_PLL_X }, + { .con_id = "pll_u", .dt_id = TEGRA20_CLK_PLL_U }, + { .con_id = "pll_d", .dt_id = TEGRA20_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA20_CLK_PLL_D_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA20_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA20_CLK_PLL_A_OUT0 }, + { .con_id = "pll_e", .dt_id = TEGRA20_CLK_PLL_E }, + { .con_id = "cclk", .dt_id = TEGRA20_CLK_CCLK }, + { .con_id = "sclk", .dt_id = TEGRA20_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA20_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA20_CLK_PCLK }, + { .con_id = "twd", .dt_id = TEGRA20_CLK_TWD }, + { .con_id = "audio", .dt_id = TEGRA20_CLK_AUDIO }, + { .con_id = "audio_2x", .dt_id = TEGRA20_CLK_AUDIO_2X }, + { .dev_id = "tegra20-ac97", .dt_id = TEGRA20_CLK_AC97 }, + { .dev_id = "tegra-apbdma", .dt_id = TEGRA20_CLK_APBDMA }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA20_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA20_CLK_TIMER }, + { .dev_id = "tegra-kbc", .dt_id = TEGRA20_CLK_KBC }, + { .con_id = "csus", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_CSUS }, + { .con_id = "vcp", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_VCP }, + { .con_id = "bsea", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_BSEA }, + { .con_id = "bsev", .dev_id = "tegra-aes", .dt_id = TEGRA20_CLK_BSEV }, + { .con_id = "emc", .dt_id = TEGRA20_CLK_EMC }, + { .dev_id = "fsl-tegra-udc", .dt_id = TEGRA20_CLK_USBD }, + { .dev_id = "tegra-ehci.1", .dt_id = TEGRA20_CLK_USB2 }, + { .dev_id = "tegra-ehci.2", .dt_id = TEGRA20_CLK_USB3 }, + { .dev_id = "dsi", .dt_id = TEGRA20_CLK_DSI }, + { .con_id = "csi", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_CSI }, + { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP }, + { .con_id = "pex", .dt_id = TEGRA20_CLK_PEX }, + { .con_id = "afi", .dt_id = TEGRA20_CLK_AFI }, + { .con_id = "pcie_xclk", .dt_id = TEGRA20_CLK_PCIE_XCLK }, + { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 }, + { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 }, + { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K }, + { .con_id = "blink", .dt_id = TEGRA20_CLK_BLINK }, + { .con_id = "clk_m", .dt_id = TEGRA20_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA20_CLK_PLL_REF }, + { .dev_id = "tegra20-i2s.0", .dt_id = TEGRA20_CLK_I2S1 }, + { .dev_id = "tegra20-i2s.1", .dt_id = TEGRA20_CLK_I2S2 }, + { .con_id = "spdif_out", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_OUT }, + { .con_id = "spdif_in", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_IN }, + { .dev_id = "spi_tegra.0", .dt_id = TEGRA20_CLK_SBC1 }, + { .dev_id = "spi_tegra.1", .dt_id = TEGRA20_CLK_SBC2 }, + { .dev_id = "spi_tegra.2", .dt_id = TEGRA20_CLK_SBC3 }, + { .dev_id = "spi_tegra.3", .dt_id = TEGRA20_CLK_SBC4 }, + { .dev_id = "spi", .dt_id = TEGRA20_CLK_SPI }, + { .dev_id = "xio", .dt_id = TEGRA20_CLK_XIO }, + { .dev_id = "twc", .dt_id = TEGRA20_CLK_TWC }, + { .dev_id = "ide", .dt_id = TEGRA20_CLK_IDE }, + { .dev_id = "tegra_nand", .dt_id = TEGRA20_CLK_NDFLASH }, + { .dev_id = "vfir", .dt_id = TEGRA20_CLK_VFIR }, + { .dev_id = "csite", .dt_id = TEGRA20_CLK_CSITE }, + { .dev_id = "la", .dt_id = TEGRA20_CLK_LA }, + { .dev_id = "tegra_w1", .dt_id = TEGRA20_CLK_OWR }, + { .dev_id = "mipi", .dt_id = TEGRA20_CLK_MIPI }, + { .dev_id = "vde", .dt_id = TEGRA20_CLK_VDE }, + { .con_id = "vi", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_VI }, + { .dev_id = "epp", .dt_id = TEGRA20_CLK_EPP }, + { .dev_id = "mpe", .dt_id = TEGRA20_CLK_MPE }, + { .dev_id = "host1x", .dt_id = TEGRA20_CLK_HOST1X }, + { .dev_id = "3d", .dt_id = TEGRA20_CLK_GR3D }, + { .dev_id = "2d", .dt_id = TEGRA20_CLK_GR2D }, + { .dev_id = "tegra-nor", .dt_id = TEGRA20_CLK_NOR }, + { .dev_id = "sdhci-tegra.0", .dt_id = TEGRA20_CLK_SDMMC1 }, + { .dev_id = "sdhci-tegra.1", .dt_id = TEGRA20_CLK_SDMMC2 }, + { .dev_id = "sdhci-tegra.2", .dt_id = TEGRA20_CLK_SDMMC3 }, + { .dev_id = "sdhci-tegra.3", .dt_id = TEGRA20_CLK_SDMMC4 }, + { .dev_id = "cve", .dt_id = TEGRA20_CLK_CVE }, + { .dev_id = "tvo", .dt_id = TEGRA20_CLK_TVO }, + { .dev_id = "tvdac", .dt_id = TEGRA20_CLK_TVDAC }, + { .con_id = "vi_sensor", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_VI_SENSOR }, + { .dev_id = "hdmi", .dt_id = TEGRA20_CLK_HDMI }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.0", .dt_id = TEGRA20_CLK_I2C1 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.1", .dt_id = TEGRA20_CLK_I2C2 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.2", .dt_id = TEGRA20_CLK_I2C3 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.3", .dt_id = TEGRA20_CLK_DVC }, + { .dev_id = "tegra-pwm", .dt_id = TEGRA20_CLK_PWM }, + { .dev_id = "tegra_uart.0", .dt_id = TEGRA20_CLK_UARTA }, + { .dev_id = "tegra_uart.1", .dt_id = TEGRA20_CLK_UARTB }, + { .dev_id = "tegra_uart.2", .dt_id = TEGRA20_CLK_UARTC }, + { .dev_id = "tegra_uart.3", .dt_id = TEGRA20_CLK_UARTD }, + { .dev_id = "tegra_uart.4", .dt_id = TEGRA20_CLK_UARTE }, + { .dev_id = "tegradc.0", .dt_id = TEGRA20_CLK_DISP1 }, + { .dev_id = "tegradc.1", .dt_id = TEGRA20_CLK_DISP2 }, +}; + +static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { + [tegra_clk_spdif_out] = { .dt_id = TEGRA20_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA20_CLK_SPDIF_IN, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA20_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA20_CLK_SDMMC2, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA20_CLK_SDMMC3, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA20_CLK_SDMMC4, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA20_CLK_LA, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA20_CLK_CSITE, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA20_CLK_VFIR, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA20_CLK_MIPI, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA20_CLK_NOR, .present = true }, + [tegra_clk_rtc] = { .dt_id = TEGRA20_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA20_CLK_TIMER, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA20_CLK_KBC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA20_CLK_CSUS, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA20_CLK_VCP, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA20_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA20_CLK_BSEV, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA20_CLK_USBD, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA20_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA20_CLK_USB3, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA20_CLK_CSI, .present = true }, + [tegra_clk_isp] = { .dt_id = TEGRA20_CLK_ISP, .present = true }, + [tegra_clk_clk_32k] = { .dt_id = TEGRA20_CLK_CLK_32K, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA20_CLK_BLINK, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA20_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA20_CLK_PCLK, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA20_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2] = { .dt_id = TEGRA20_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA20_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA20_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA20_CLK_PLL_P, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA20_CLK_OWR, .present = true }, + [tegra_clk_sbc1] = { .dt_id = TEGRA20_CLK_SBC1, .present = true }, + [tegra_clk_sbc2] = { .dt_id = TEGRA20_CLK_SBC2, .present = true }, + [tegra_clk_sbc3] = { .dt_id = TEGRA20_CLK_SBC3, .present = true }, + [tegra_clk_sbc4] = { .dt_id = TEGRA20_CLK_SBC4, .present = true }, + [tegra_clk_vde] = { .dt_id = TEGRA20_CLK_VDE, .present = true }, + [tegra_clk_vi] = { .dt_id = TEGRA20_CLK_VI, .present = true }, + [tegra_clk_epp] = { .dt_id = TEGRA20_CLK_EPP, .present = true }, + [tegra_clk_mpe] = { .dt_id = TEGRA20_CLK_MPE, .present = true }, + [tegra_clk_host1x] = { .dt_id = TEGRA20_CLK_HOST1X, .present = true }, + [tegra_clk_gr2d] = { .dt_id = TEGRA20_CLK_GR2D, .present = true }, + [tegra_clk_gr3d] = { .dt_id = TEGRA20_CLK_GR3D, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA20_CLK_NDFLASH, .present = true }, + [tegra_clk_cve] = { .dt_id = TEGRA20_CLK_CVE, .present = true }, + [tegra_clk_tvo] = { .dt_id = TEGRA20_CLK_TVO, .present = true }, + [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true }, + [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true }, + [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, +}; + static unsigned long tegra20_clk_measure_input_freq(void) { u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); @@ -545,8 +636,7 @@ static void tegra20_pll_init(void) /* PLLC */ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0, &pll_c_params, NULL); - clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; + clks[TEGRA20_CLK_PLL_C] = clk; /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", @@ -555,69 +645,13 @@ static void tegra20_pll_init(void) clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_c_out1", NULL); - clks[pll_c_out1] = clk; - - /* PLLP */ - clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, NULL, 0, - &pll_p_params, NULL); - clk_register_clkdev(clk, "pll_p", NULL); - clks[pll_p] = clk; - - /* PLLP_OUT1 */ - clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", - clk_base + PLLP_OUTA, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", - clk_base + PLLP_OUTA, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out1", NULL); - clks[pll_p_out1] = clk; - - /* PLLP_OUT2 */ - clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", - clk_base + PLLP_OUTA, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 24, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", - clk_base + PLLP_OUTA, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out2", NULL); - clks[pll_p_out2] = clk; - - /* PLLP_OUT3 */ - clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", - clk_base + PLLP_OUTB, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", - clk_base + PLLP_OUTB, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out3", NULL); - clks[pll_p_out3] = clk; - - /* PLLP_OUT4 */ - clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", - clk_base + PLLP_OUTB, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 24, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", - clk_base + PLLP_OUTB, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out4", NULL); - clks[pll_p_out4] = clk; + clks[TEGRA20_CLK_PLL_C_OUT1] = clk; /* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, &pll_m_params, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + clks[TEGRA20_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -626,38 +660,32 @@ static void tegra20_pll_init(void) clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_m_out1", NULL); - clks[pll_m_out1] = clk; + clks[TEGRA20_CLK_PLL_M_OUT1] = clk; /* PLLX */ clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0, &pll_x_params, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; + clks[TEGRA20_CLK_PLL_X] = clk; /* PLLU */ clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0, &pll_u_params, NULL); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + clks[TEGRA20_CLK_PLL_U] = clk; /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0, &pll_d_params, NULL); - clk_register_clkdev(clk, "pll_d", NULL); - clks[pll_d] = clk; + clks[TEGRA20_CLK_PLL_D] = clk; /* PLLD_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d_out0", NULL); - clks[pll_d_out0] = clk; + clks[TEGRA20_CLK_PLL_D_OUT0] = clk; /* PLLA */ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0, &pll_a_params, NULL); - clk_register_clkdev(clk, "pll_a", NULL); - clks[pll_a] = clk; + clks[TEGRA20_CLK_PLL_A] = clk; /* PLLA_OUT0 */ clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", @@ -666,14 +694,12 @@ static void tegra20_pll_init(void) clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_a_out0", NULL); - clks[pll_a_out0] = clk; + clks[TEGRA20_CLK_PLL_A_OUT0] = clk; /* PLLE */ clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, 0, &pll_e_params, NULL); - clk_register_clkdev(clk, "pll_e", NULL); - clks[pll_e] = clk; + clks[TEGRA20_CLK_PLL_E] = clk; } static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", @@ -691,40 +717,17 @@ static void tegra20_super_clk_init(void) clk = tegra_clk_register_super_mux("cclk", cclk_parents, ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT, clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "cclk", NULL); - clks[cclk] = clk; + clks[TEGRA20_CLK_CCLK] = clk; /* SCLK */ clk = tegra_clk_register_super_mux("sclk", sclk_parents, ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "sclk", NULL); - clks[sclk] = clk; - - /* HCLK */ - clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, - clk_base + CLK_SYSTEM_RATE, 4, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, - clk_base + CLK_SYSTEM_RATE, 7, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "hclk", NULL); - clks[hclk] = clk; - - /* PCLK */ - clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, - clk_base + CLK_SYSTEM_RATE, 0, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, - clk_base + CLK_SYSTEM_RATE, 3, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "pclk", NULL); - clks[pclk] = clk; + clks[TEGRA20_CLK_SCLK] = clk; /* twd */ clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4); - clk_register_clkdev(clk, "twd", NULL); - clks[twd] = clk; + clks[TEGRA20_CLK_TWD] = clk; } static const char *audio_parents[] = {"spdif_in", "i2s1", "i2s2", "unused", @@ -743,8 +746,7 @@ static void __init tegra20_audio_clk_init(void) clk = clk_register_gate(NULL, "audio", "audio_mux", 0, clk_base + AUDIO_SYNC_CLK, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio", NULL); - clks[audio] = clk; + clks[TEGRA20_CLK_AUDIO] = clk; /* audio_2x */ clk = clk_register_fixed_factor(NULL, "audio_doubler", "audio", @@ -753,8 +755,7 @@ static void __init tegra20_audio_clk_init(void) TEGRA_PERIPH_NO_RESET, clk_base, CLK_SET_RATE_PARENT, 89, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio_2x", NULL); - clks[audio_2x] = clk; + clks[TEGRA20_CLK_AUDIO_2X] = clk; } @@ -762,68 +763,36 @@ static const char *i2s1_parents[] = {"pll_a_out0", "audio_2x", "pll_p", "clk_m"}; static const char *i2s2_parents[] = {"pll_a_out0", "audio_2x", "pll_p", "clk_m"}; -static const char *spdif_out_parents[] = {"pll_a_out0", "audio_2x", "pll_p", - "clk_m"}; -static const char *spdif_in_parents[] = {"pll_p", "pll_c", "pll_m"}; static const char *pwm_parents[] = {"pll_p", "pll_c", "audio", "clk_m", "clk_32k"}; static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; -static const char *mux_pllmcpa[] = {"pll_m", "pll_c", "pll_c", "pll_a"}; static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c", "clk_m"}; static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"}; static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra20-i2s.0", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra20-i2s.1", i2s2_parents, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra20-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra20-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("spi", NULL, "spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, TEGRA_PERIPH_ON_APB, spi), - TEGRA_INIT_DATA_MUX("xio", NULL, "xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, 0, xio), - TEGRA_INIT_DATA_MUX("twc", NULL, "twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, TEGRA_PERIPH_ON_APB, twc), - TEGRA_INIT_DATA_MUX("ide", NULL, "ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, 0, ide), - TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, 0, ndflash), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, 0, csite), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, 0, la), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_MUX("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, 0, vde), - TEGRA_INIT_DATA_MUX("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, 0, vi), - TEGRA_INIT_DATA_MUX("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, 0, epp), - TEGRA_INIT_DATA_MUX("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, 0, mpe), - TEGRA_INIT_DATA_MUX("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, 0, host1x), - TEGRA_INIT_DATA_MUX("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, TEGRA_PERIPH_MANUAL_RESET, gr3d), - TEGRA_INIT_DATA_MUX("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, 0, gr2d), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, 0, nor), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, 0, sdmmc4), - TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, 0, cve), - TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, 0, tvo), - TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, 0, tvdac), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, TEGRA_PERIPH_ON_APB, i2c1), - TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, TEGRA_PERIPH_ON_APB, i2c2), - TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3), - TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, dvc), - TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi), - TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, pwm), + TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1), + TEGRA_INIT_DATA_MUX("i2s2", i2s2_parents, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S2), + TEGRA_INIT_DATA_MUX("spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_SPI), + TEGRA_INIT_DATA_MUX("xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, 0, TEGRA20_CLK_XIO), + TEGRA_INIT_DATA_MUX("twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_TWC), + TEGRA_INIT_DATA_MUX("ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, 0, TEGRA20_CLK_IDE), + TEGRA_INIT_DATA_DIV16("dvc", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_DVC), + TEGRA_INIT_DATA_DIV16("i2c1", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C1), + TEGRA_INIT_DATA_DIV16("i2c2", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C2), + TEGRA_INIT_DATA_DIV16("i2c3", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C3), + TEGRA_INIT_DATA_MUX("hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA20_CLK_HDMI), + TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_PWM), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, TEGRA_PERIPH_ON_APB, uarta), - TEGRA_INIT_DATA_NODIV("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, TEGRA_PERIPH_ON_APB, uartb), - TEGRA_INIT_DATA_NODIV("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, TEGRA_PERIPH_ON_APB, uartc), - TEGRA_INIT_DATA_NODIV("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, TEGRA_PERIPH_ON_APB, uartd), - TEGRA_INIT_DATA_NODIV("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, TEGRA_PERIPH_ON_APB, uarte), - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, disp2), + TEGRA_INIT_DATA_NODIV("uarta", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTA), + TEGRA_INIT_DATA_NODIV("uartb", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTB), + TEGRA_INIT_DATA_NODIV("uartc", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTC), + TEGRA_INIT_DATA_NODIV("uartd", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTD), + TEGRA_INIT_DATA_NODIV("uarte", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTE), + TEGRA_INIT_DATA_NODIV("disp1", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, 0, TEGRA20_CLK_DISP1), + TEGRA_INIT_DATA_NODIV("disp2", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, TEGRA20_CLK_DISP2), }; static void __init tegra20_periph_clk_init(void) @@ -836,59 +805,12 @@ static void __init tegra20_periph_clk_init(void) clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", TEGRA_PERIPH_ON_APB, clk_base, 0, 3, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra20-ac97"); - clks[ac97] = clk; + clks[TEGRA20_CLK_AC97] = clk; /* apbdma */ clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, 0, 34, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-apbdma"); - clks[apbdma] = clk; - - /* rtc */ - clk = tegra_clk_register_periph_gate("rtc", "clk_32k", - TEGRA_PERIPH_NO_RESET, - clk_base, 0, 4, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "rtc-tegra"); - clks[rtc] = clk; - - /* timer */ - clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, - 0, 5, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "timer"); - clks[timer] = clk; - - /* kbc */ - clk = tegra_clk_register_periph_gate("kbc", "clk_32k", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 36, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-kbc"); - clks[kbc] = clk; - - /* csus */ - clk = tegra_clk_register_periph_gate("csus", "clk_m", - TEGRA_PERIPH_NO_RESET, - clk_base, 0, 92, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csus", "tengra_camera"); - clks[csus] = clk; - - /* vcp */ - clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, - clk_base, 0, 29, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "vcp", "tegra-avp"); - clks[vcp] = clk; - - /* bsea */ - clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, - clk_base, 0, 62, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsea", "tegra-avp"); - clks[bsea] = clk; - - /* bsev */ - clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, - clk_base, 0, 63, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsev", "tegra-aes"); - clks[bsev] = clk; + clks[TEGRA20_CLK_APBDMA] = clk; /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, @@ -898,85 +820,43 @@ static void __init tegra20_periph_clk_init(void) 30, 2, 0, NULL); clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, 57, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "emc", NULL); - clks[emc] = clk; - - /* usbd */ - clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, - 22, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); - clks[usbd] = clk; - - /* usb2 */ - clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, - 58, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.1"); - clks[usb2] = clk; - - /* usb3 */ - clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, - 59, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.2"); - clks[usb3] = clk; + clks[TEGRA20_CLK_EMC] = clk; /* dsi */ clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, 48, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "dsi"); - clks[dsi] = clk; - - /* csi */ - clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csi", "tegra_camera"); - clks[csi] = clk; - - /* isp */ - clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "isp", "tegra_camera"); - clks[isp] = clk; + clks[TEGRA20_CLK_DSI] = clk; /* pex */ clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pex", NULL); - clks[pex] = clk; - - /* afi */ - clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "afi", NULL); - clks[afi] = clk; + clks[TEGRA20_CLK_PEX] = clk; /* pcie_xclk */ clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base, 0, 74, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pcie_xclk", NULL); - clks[pcie_xclk] = clk; + clks[TEGRA20_CLK_PCIE_XCLK] = clk; /* cdev1 */ clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, 26000000); clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, clk_base, 0, 94, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "cdev1", NULL); - clks[cdev1] = clk; + clks[TEGRA20_CLK_CDEV1] = clk; /* cdev2 */ clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, 26000000); clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, clk_base, 0, 93, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "cdev2", NULL); - clks[cdev2] = clk; + clks[TEGRA20_CLK_CDEV2] = clk; for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; clk = tegra_clk_register_periph(data->name, data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset, data->flags); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } @@ -986,37 +866,10 @@ static void __init tegra20_periph_clk_init(void) data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } -} - - -static void __init tegra20_fixed_clk_init(void) -{ - struct clk *clk; - - /* clk_32k */ - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, - 32768); - clk_register_clkdev(clk, "clk_32k", NULL); - clks[clk_32k] = clk; -} - -static void __init tegra20_pmc_clk_init(void) -{ - struct clk *clk; - /* blink */ - writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); - clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, - pmc_base + PMC_DPD_PADS_ORIDE, - PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); - clk = clk_register_gate(NULL, "blink", "blink_override", 0, - pmc_base + PMC_CTRL, - PMC_CTRL_BLINK_ENB, 0, NULL); - clk_register_clkdev(clk, "blink", NULL); - clks[blink] = clk; + tegra_periph_clk_init(clk_base, pmc_base, tegra20_clks, &pll_p_params); } static void __init tegra20_osc_clk_init(void) @@ -1030,15 +883,13 @@ static void __init tegra20_osc_clk_init(void) /* clk_m */ clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT | CLK_IGNORE_UNUSED, input_freq); - clk_register_clkdev(clk, "clk_m", NULL); - clks[clk_m] = clk; + clks[TEGRA20_CLK_CLK_M] = clk; /* pll_ref */ pll_ref_div = tegra20_get_pll_ref_div(); clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", CLK_SET_RATE_PARENT, 1, pll_ref_div); - clk_register_clkdev(clk, "pll_ref", NULL); - clks[pll_ref] = clk; + clks[TEGRA20_CLK_PLL_REF] = clk; } /* Tegra20 CPU clock and reset control functions */ @@ -1172,49 +1023,49 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = { }; static struct tegra_clk_init_table init_table[] __initdata = { - {pll_p, clk_max, 216000000, 1}, - {pll_p_out1, clk_max, 28800000, 1}, - {pll_p_out2, clk_max, 48000000, 1}, - {pll_p_out3, clk_max, 72000000, 1}, - {pll_p_out4, clk_max, 24000000, 1}, - {pll_c, clk_max, 600000000, 1}, - {pll_c_out1, clk_max, 120000000, 1}, - {sclk, pll_c_out1, 0, 1}, - {hclk, clk_max, 0, 1}, - {pclk, clk_max, 60000000, 1}, - {csite, clk_max, 0, 1}, - {emc, clk_max, 0, 1}, - {cclk, clk_max, 0, 1}, - {uarta, pll_p, 0, 0}, - {uartb, pll_p, 0, 0}, - {uartc, pll_p, 0, 0}, - {uartd, pll_p, 0, 0}, - {uarte, pll_p, 0, 0}, - {pll_a, clk_max, 56448000, 1}, - {pll_a_out0, clk_max, 11289600, 1}, - {cdev1, clk_max, 0, 1}, - {blink, clk_max, 32768, 1}, - {i2s1, pll_a_out0, 11289600, 0}, - {i2s2, pll_a_out0, 11289600, 0}, - {sdmmc1, pll_p, 48000000, 0}, - {sdmmc3, pll_p, 48000000, 0}, - {sdmmc4, pll_p, 48000000, 0}, - {spi, pll_p, 20000000, 0}, - {sbc1, pll_p, 100000000, 0}, - {sbc2, pll_p, 100000000, 0}, - {sbc3, pll_p, 100000000, 0}, - {sbc4, pll_p, 100000000, 0}, - {host1x, pll_c, 150000000, 0}, - {disp1, pll_p, 600000000, 0}, - {disp2, pll_p, 600000000, 0}, - {gr2d, pll_c, 300000000, 0}, - {gr3d, pll_c, 300000000, 0}, - {clk_max, clk_max, 0, 0}, /* This MUST be the last entry */ + {TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1}, + {TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1}, + {TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1}, + {TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1}, + {TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1}, + {TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1}, + {TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 1}, + {TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1}, + {TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1}, + {TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 1}, + {TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 1}, + {TEGRA20_CLK_CDEV1, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_BLINK, TEGRA20_CLK_CLK_MAX, 32768, 1}, + {TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0}, + {TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0}, + {TEGRA20_CLK_SDMMC4, TEGRA20_CLK_PLL_P, 48000000, 0}, + {TEGRA20_CLK_SPI, TEGRA20_CLK_PLL_P, 20000000, 0}, + {TEGRA20_CLK_SBC1, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_SBC2, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_SBC4, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_HOST1X, TEGRA20_CLK_PLL_C, 150000000, 0}, + {TEGRA20_CLK_DISP1, TEGRA20_CLK_PLL_P, 600000000, 0}, + {TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0}, + {TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0}, + {TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0}, + {TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry */ }; static void __init tegra20_clock_apply_init_table(void) { - tegra_init_from_table(init_table, clks, clk_max); + tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX); } /* @@ -1223,11 +1074,11 @@ static void __init tegra20_clock_apply_init_table(void) * table under two names. */ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { - TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), - TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"), - TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */ + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "utmip-pad", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-ehci.0", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-otg", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CCLK, NULL, "cpu"), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CLK_MAX, NULL, NULL), /* Must be the last entry */ }; static const struct of_device_id pmc_match[] __initconst = { @@ -1257,21 +1108,23 @@ static void __init tegra20_clock_init(struct device_node *np) BUG(); } - clks = tegra_clk_init(clk_max, TEGRA20_CLK_PERIPH_BANKS); + clks = tegra_clk_init(TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_PERIPH_BANKS); if (!clks) return; tegra20_osc_clk_init(); - tegra20_pmc_clk_init(); - tegra20_fixed_clk_init(); + tegra_fixed_clk_init(tegra20_clks); tegra20_pll_init(); tegra20_super_clk_init(); + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra20_clks, NULL); tegra20_periph_clk_init(); tegra20_audio_clk_init(); + tegra_pmc_clk_init(pmc_base, tegra20_clks); - tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); + tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX); tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra20_clock_apply_init_table; -- cgit v1.2.3 From 798e910bee3f9ad69a8b16d7e705086852d9f2de Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 9 Sep 2013 13:22:55 +0300 Subject: clk: tegra: Add support for PLLSS Tegra124 introduces a new PLL type, PLLSS. Add support for it. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-pll.c | 123 +++++++++++++++++++++++++++++++++++++++++++- drivers/clk/tegra/clk.h | 5 ++ 2 files changed, 126 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 3aa85bf2f425..689c468aca2f 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -137,6 +137,36 @@ #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) +#define PLLSS_MISC_KCP 0 +#define PLLSS_MISC_KVCO 0 +#define PLLSS_MISC_SETUP 0 +#define PLLSS_EN_SDM 0 +#define PLLSS_EN_SSC 0 +#define PLLSS_EN_DITHER2 0 +#define PLLSS_EN_DITHER 1 +#define PLLSS_SDM_RESET 0 +#define PLLSS_CLAMP 0 +#define PLLSS_SDM_SSC_MAX 0 +#define PLLSS_SDM_SSC_MIN 0 +#define PLLSS_SDM_SSC_STEP 0 +#define PLLSS_SDM_DIN 0 +#define PLLSS_MISC_DEFAULT ((PLLSS_MISC_KCP << 25) | \ + (PLLSS_MISC_KVCO << 24) | \ + PLLSS_MISC_SETUP) +#define PLLSS_CFG_DEFAULT ((PLLSS_EN_SDM << 31) | \ + (PLLSS_EN_SSC << 30) | \ + (PLLSS_EN_DITHER2 << 29) | \ + (PLLSS_EN_DITHER << 28) | \ + (PLLSS_SDM_RESET) << 27 | \ + (PLLSS_CLAMP << 22)) +#define PLLSS_CTRL1_DEFAULT \ + ((PLLSS_SDM_SSC_MAX << 16) | PLLSS_SDM_SSC_MIN) +#define PLLSS_CTRL2_DEFAULT \ + ((PLLSS_SDM_SSC_STEP << 16) | PLLSS_SDM_DIN) +#define PLLSS_LOCK_OVERRIDE BIT(24) +#define PLLSS_REF_SRC_SEL_SHIFT 25 +#define PLLSS_REF_SRC_SEL_MASK (3 << PLLSS_REF_SRC_SEL_SHIFT) + #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) #define pll_readl_base(p) pll_readl(p->params->base_reg, p) #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) @@ -764,7 +794,7 @@ const struct clk_ops tegra_clk_plle_ops = { .enable = clk_plle_enable, }; -#ifdef CONFIG_ARCH_TEGRA_114_SOC +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, unsigned long parent_rate) @@ -1405,7 +1435,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, return clk; } -#ifdef CONFIG_ARCH_TEGRA_114_SOC +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) const struct clk_ops tegra_clk_pllxc_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_iddq_enable, @@ -1702,3 +1732,92 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, return clk; } #endif + +#ifdef CONFIG_ARCH_TEGRA_124_SOC +const struct clk_ops tegra_clk_pllss_ops = { + .is_enabled = clk_pll_is_enabled, + .enable = clk_pll_iddq_enable, + .disable = clk_pll_iddq_disable, + .recalc_rate = clk_pll_recalc_rate, + .round_rate = clk_pll_ramp_round_rate, + .set_rate = clk_pllxc_set_rate, +}; + +struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, + void __iomem *clk_base, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) +{ + struct tegra_clk_pll *pll; + struct clk *clk, *parent; + struct tegra_clk_pll_freq_table cfg; + unsigned long parent_rate; + u32 val; + int i; + + if (!pll_params->div_nmp) + return ERR_PTR(-EINVAL); + + parent = __clk_lookup(parent_name); + if (IS_ERR(parent)) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } + + pll_params->flags = TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_USE_LOCK; + pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); + if (IS_ERR(pll)) + return ERR_CAST(pll); + + val = pll_readl_base(pll); + val &= ~PLLSS_REF_SRC_SEL_MASK; + pll_writel_base(val, pll); + + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + /* initialize PLL to minimum rate */ + + cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); + cfg.n = cfg.m * pll_params->vco_min / parent_rate; + + for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++) + ; + if (!i) { + kfree(pll); + return ERR_PTR(-EINVAL); + } + + cfg.p = pll_params->pdiv_tohw[i-1].hw_val; + + _update_pll_mnp(pll, &cfg); + + pll_writel_misc(PLLSS_MISC_DEFAULT, pll); + pll_writel(PLLSS_CFG_DEFAULT, pll_params->ext_misc_reg[0], pll); + pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[1], pll); + pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[2], pll); + + val = pll_readl_base(pll); + if (val & PLL_BASE_ENABLE) { + if (val & BIT(pll_params->iddq_bit_idx)) { + WARN(1, "%s is on but IDDQ set\n", name); + kfree(pll); + return ERR_PTR(-EINVAL); + } + } else + val |= BIT(pll_params->iddq_bit_idx); + + val &= ~PLLSS_LOCK_OVERRIDE; + pll_writel_base(val, pll); + + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, + &tegra_clk_pllss_ops); + + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} +#endif diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 05abfc5fdff8..7f110acfe2a1 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -298,6 +298,11 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, struct tegra_clk_pll_params *pll_params, spinlock_t *lock); +struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, + void __iomem *clk_base, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); + /** * struct tegra_clk_pll_out - PLL divider down clock * -- cgit v1.2.3 From 2b239077d1e2061c65763dcf57ab978ae5261559 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Wed, 11 Sep 2013 17:57:37 +0300 Subject: clk: tegra: Add periph regs bank X Tegra124 has an extra bank of peripheral clock registers. Add it to the generic peripheral clock code. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 14d25322aec5..a12a5f5107ec 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -57,6 +57,8 @@ #define RST_DEVICES_CLR_V 0x434 #define RST_DEVICES_SET_W 0x438 #define RST_DEVICES_CLR_W 0x43c +#define RST_DEVICES_SET_X 0x290 +#define RST_DEVICES_CLR_X 0x294 /* Global data of Tegra CPU CAR ops */ static struct tegra_cpu_car_ops dummy_car_ops; @@ -109,6 +111,14 @@ static struct tegra_clk_periph_regs periph_regs[] = { .rst_set_reg = RST_DEVICES_SET_W, .rst_clr_reg = RST_DEVICES_CLR_W, }, + [5] = { + .enb_reg = CLK_OUT_ENB_X, + .enb_set_reg = CLK_OUT_ENB_SET_X, + .enb_clr_reg = CLK_OUT_ENB_CLR_X, + .rst_reg = RST_DEVICES_X, + .rst_set_reg = RST_DEVICES_SET_X, + .rst_clr_reg = RST_DEVICES_CLR_X, + }, }; struct tegra_clk_periph_regs *get_reg_bank(int clkid) -- cgit v1.2.3 From bc44275b8ea2df7c77658b08955ec545a37560ab Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 18 Nov 2013 16:11:37 +0100 Subject: clk: tegra: add locking to periph clks Tegra124 has periph clocks which share the hw register. Hence locking is required. Signed-off-by: Peter De Schrijver Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra-periph.c | 33 ++++++++++++++++++--------------- drivers/clk/tegra/clk.h | 10 ++++++---- 2 files changed, 24 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 9b04139f331d..e8d6f2f20141 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -118,75 +118,78 @@ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\ + NULL) #define MUX_FLAGS(_name, _parents, _offset,\ _clk_num, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, _gate_flags, _clk_id, _parents##_idx, flags) + _clk_num, _gate_flags, _clk_id, _parents##_idx, flags,\ + NULL) #define MUX8(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, _gate_flags, _clk_id, _parents##_idx, 0) + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\ + NULL) #define INT(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ - _clk_id, _parents##_idx, 0) + _clk_id, _parents##_idx, 0, NULL) #define INT_FLAGS(_name, _parents, _offset,\ _clk_num, _gate_flags, _clk_id, flags)\ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ - _clk_id, _parents##_idx, flags) + _clk_id, _parents##_idx, flags, NULL) #define INT8(_name, _parents, _offset,\ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ - _clk_id, _parents##_idx, 0) + _clk_id, _parents##_idx, 0, NULL) #define UART(_name, _parents, _offset,\ _clk_num, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART| \ TEGRA_DIVIDER_ROUND_UP, _clk_num, 0, _clk_id,\ - _parents##_idx, 0) + _parents##_idx, 0, NULL) #define I2C(_name, _parents, _offset,\ _clk_num, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ - _clk_num, 0, _clk_id, _parents##_idx, 0) + _clk_num, 0, _clk_id, _parents##_idx, 0, NULL) #define XUSB(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ - _clk_id, _parents##_idx, 0) + _clk_id, _parents##_idx, 0, NULL) #define AUDIO(_name, _offset, _clk_num,\ _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, mux_d_audio_clk, \ _offset, 16, 0xE01F, 0, 0, 8, 1, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags, \ - _clk_id, mux_d_audio_clk_idx, 0) + _clk_id, mux_d_audio_clk_idx, 0, NULL) #define NODIV(_name, _parents, _offset, \ _mux_shift, _mux_mask, _clk_num, \ - _gate_flags, _clk_id) \ + _gate_flags, _clk_id, _lock) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ _clk_num, (_gate_flags) | TEGRA_PERIPH_NO_DIV,\ - _clk_id, _parents##_idx, 0) + _clk_id, _parents##_idx, 0, _lock) #define GATE(_name, _parent_name, \ _clk_num, _gate_flags, _clk_id, _flags) \ @@ -195,7 +198,7 @@ .clk_id = _clk_id, \ .p.parent_name = _parent_name, \ .periph = TEGRA_CLK_PERIPH(0, 0, 0, 0, 0, 0, 0, \ - _clk_num, _gate_flags, 0), \ + _clk_num, _gate_flags, 0, NULL), \ .flags = _flags \ } @@ -414,8 +417,8 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), - NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1), - NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2), + NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1, NULL), + NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2, NULL), UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 7f110acfe2a1..f984ebed9f1f 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -439,19 +439,21 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ _div_shift, _div_width, _div_frac_width, \ _div_flags, _clk_num,\ - _gate_flags, _table) \ + _gate_flags, _table, _lock) \ { \ .mux = { \ .flags = _mux_flags, \ .shift = _mux_shift, \ .mask = _mux_mask, \ .table = _table, \ + .lock = _lock, \ }, \ .divider = { \ .flags = _div_flags, \ .shift = _div_shift, \ .width = _div_width, \ .frac_width = _div_frac_width, \ + .lock = _lock, \ }, \ .gate = { \ .flags = _gate_flags, \ @@ -481,7 +483,7 @@ struct tegra_periph_init_data { _mux_shift, _mux_mask, _mux_flags, _div_shift, \ _div_width, _div_frac_width, _div_flags, \ _clk_num, _gate_flags, _clk_id, _table, \ - _flags) \ + _flags, _lock) \ { \ .name = _name, \ .clk_id = _clk_id, \ @@ -491,7 +493,7 @@ struct tegra_periph_init_data { _mux_flags, _div_shift, \ _div_width, _div_frac_width, \ _div_flags, _clk_num, \ - _gate_flags, _table), \ + _gate_flags, _table, _lock), \ .offset = _offset, \ .con_id = _con_id, \ .dev_id = _dev_id, \ @@ -506,7 +508,7 @@ struct tegra_periph_init_data { _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ _div_shift, _div_width, _div_frac_width, _div_flags, \ _clk_num, _gate_flags, _clk_id,\ - NULL, 0) + NULL, 0, NULL) /** * struct clk_super_mux - super clock -- cgit v1.2.3 From b29f9e926442c35bd42ebd283aaed0de2c4f1477 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 18 Nov 2013 16:11:38 +0100 Subject: clk: tegra: add TEGRA_PERIPH_NO_GATE Tegra124 has a clock which consists of a mux and a fractional divider. Add support for this. Signed-off-by: Peter De Schrijver Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-periph.c | 18 +++++++++++++++--- drivers/clk/tegra/clk-tegra-periph.c | 6 ++++++ drivers/clk/tegra/clk.h | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index b5feccca2f1e..d62b396863c1 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -170,6 +170,14 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = { .disable = clk_periph_disable, }; +const struct clk_ops tegra_clk_periph_no_gate_ops = { + .get_parent = clk_periph_get_parent, + .set_parent = clk_periph_set_parent, + .recalc_rate = clk_periph_recalc_rate, + .round_rate = clk_periph_round_rate, + .set_rate = clk_periph_set_rate, +}; + static struct clk *_tegra_clk_register_periph(const char *name, const char **parent_names, int num_parents, struct tegra_clk_periph *periph, @@ -181,11 +189,15 @@ static struct clk *_tegra_clk_register_periph(const char *name, struct tegra_clk_periph_regs *bank; bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); - flags |= periph->gate.flags & TEGRA_PERIPH_NO_DIV ? - CLK_SET_RATE_PARENT : 0; + if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) { + flags |= CLK_SET_RATE_PARENT; + init.ops = &tegra_clk_periph_nodiv_ops; + } else if (periph->gate.flags & TEGRA_PERIPH_NO_GATE) + init.ops = &tegra_clk_periph_no_gate_ops; + else + init.ops = &tegra_clk_periph_ops; init.name = name; - init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; init.flags = flags; init.parent_names = parent_names; init.num_parents = num_parents; diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index e8d6f2f20141..958d4f4fe91f 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -135,6 +135,12 @@ _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\ NULL) +#define MUX8_NOGATE_LOCK(_name, _parents, _offset, _clk_id, _lock) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + 0, TEGRA_PERIPH_NO_GATE, _clk_id,\ + _parents##_idx, 0, _lock) + #define INT(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index f984ebed9f1f..40fb011233c0 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -391,6 +391,7 @@ struct tegra_clk_periph_gate { #define TEGRA_PERIPH_ON_APB BIT(2) #define TEGRA_PERIPH_WAR_1005168 BIT(3) #define TEGRA_PERIPH_NO_DIV BIT(4) +#define TEGRA_PERIPH_NO_GATE BIT(5) void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); extern const struct clk_ops tegra_clk_periph_gate_ops; -- cgit v1.2.3 From 6d11632db44169a7b12a98da4853a8e9c96c3c7c Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 14 Oct 2013 18:52:25 +0300 Subject: clk: tegra124: Add common clk IDs to clk-id.h Tegra124 introduces a number of a new clocks. Introduce the corresponding the IDs for them. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-id.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index 22e2e8e67b2f..cf0c323f2c36 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -7,8 +7,10 @@ enum clk_id { tegra_clk_actmon, tegra_clk_adx, + tegra_clk_adx1, tegra_clk_afi, tegra_clk_amx, + tegra_clk_amx1, tegra_clk_apbdma, tegra_clk_apbif, tegra_clk_audio0, @@ -35,6 +37,7 @@ enum clk_id { tegra_clk_cilcd, tegra_clk_cile, tegra_clk_clk_32k, + tegra_clk_clk72Mhz, tegra_clk_clk_m, tegra_clk_clk_m_div2, tegra_clk_clk_m_div4, @@ -44,6 +47,8 @@ enum clk_id { tegra_clk_clk_out_2_mux, tegra_clk_clk_out_3, tegra_clk_clk_out_3_mux, + tegra_clk_cml0, + tegra_clk_cml1, tegra_clk_csi, tegra_clk_csite, tegra_clk_csus, @@ -58,6 +63,7 @@ enum clk_id { tegra_clk_disp1, tegra_clk_disp2, tegra_clk_dp2, + tegra_clk_dpaux, tegra_clk_dsia, tegra_clk_dsialp, tegra_clk_dsia_mux, @@ -66,6 +72,7 @@ enum clk_id { tegra_clk_dsib_mux, tegra_clk_dtv, tegra_clk_emc, + tegra_clk_entropy, tegra_clk_epp, tegra_clk_epp_8, tegra_clk_extern1, @@ -73,6 +80,7 @@ enum clk_id { tegra_clk_extern3, tegra_clk_fuse, tegra_clk_fuse_burn, + tegra_clk_gpu, tegra_clk_gr2d, tegra_clk_gr2d_8, tegra_clk_gr3d, @@ -82,6 +90,7 @@ enum clk_id { tegra_clk_hda2codec_2x, tegra_clk_hda2hdmi, tegra_clk_hdmi, + tegra_clk_hdmi_audio, tegra_clk_host1x, tegra_clk_host1x_8, tegra_clk_i2c1, @@ -89,6 +98,7 @@ enum clk_id { tegra_clk_i2c3, tegra_clk_i2c4, tegra_clk_i2c5, + tegra_clk_i2c6, tegra_clk_i2cslow, tegra_clk_i2s0, tegra_clk_i2s0_sync, @@ -101,6 +111,8 @@ enum clk_id { tegra_clk_i2s4, tegra_clk_i2s4_sync, tegra_clk_isp, + tegra_clk_isp_8, + tegra_clk_ispb, tegra_clk_kbc, tegra_clk_kfuse, tegra_clk_la, @@ -115,17 +127,20 @@ enum clk_id { tegra_clk_ndspeed_8, tegra_clk_nor, tegra_clk_owr, + tegra_clk_pcie, tegra_clk_pclk, tegra_clk_pll_a, tegra_clk_pll_a_out0, tegra_clk_pll_c, tegra_clk_pll_c2, tegra_clk_pll_c3, + tegra_clk_pll_c4, tegra_clk_pll_c_out1, tegra_clk_pll_d, tegra_clk_pll_d2, tegra_clk_pll_d2_out0, tegra_clk_pll_d_out0, + tegra_clk_pll_dp, tegra_clk_pll_e_out0, tegra_clk_pll_m, tegra_clk_pll_m_out1, @@ -135,6 +150,7 @@ enum clk_id { tegra_clk_pll_p_out2_int, tegra_clk_pll_p_out3, tegra_clk_pll_p_out4, + tegra_clk_pll_p_out5, tegra_clk_pll_ref, tegra_clk_pll_re_out, tegra_clk_pll_re_vco, @@ -169,6 +185,8 @@ enum clk_id { tegra_clk_sdmmc4, tegra_clk_se, tegra_clk_soc_therm, + tegra_clk_sor0, + tegra_clk_sor0_lvds, tegra_clk_spdif, tegra_clk_spdif_2x, tegra_clk_spdif_in, @@ -195,8 +213,12 @@ enum clk_id { tegra_clk_vfir, tegra_clk_vi, tegra_clk_vi_8, + tegra_clk_vi_9, + tegra_clk_vic03, + tegra_clk_vim2_clk, tegra_clk_vimclk_sync, tegra_clk_vi_sensor, + tegra_clk_vi_sensor2, tegra_clk_vi_sensor_8, tegra_clk_xusb_dev, tegra_clk_xusb_dev_src, -- cgit v1.2.3 From 3b34d8214dce9bfeef9049de3fe1e8bfbbbb2709 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 14 Oct 2013 18:53:10 +0300 Subject: clk: tegra124: Add new peripheral clocks Tegra124 introduces a number of new peripheral clocks. This patch adds those to the common peripheral clock code. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra-periph.c | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 958d4f4fe91f..5c35885f4a7c 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -37,7 +37,9 @@ #define CLK_SOURCE_SPDIF_IN 0x10c #define CLK_SOURCE_PWM 0x110 #define CLK_SOURCE_ADX 0x638 +#define CLK_SOURCE_ADX1 0x670 #define CLK_SOURCE_AMX 0x63c +#define CLK_SOURCE_AMX1 0x674 #define CLK_SOURCE_HDA 0x428 #define CLK_SOURCE_HDA2CODEC_2X 0x3e4 #define CLK_SOURCE_SBC1 0x134 @@ -69,6 +71,7 @@ #define CLK_SOURCE_I2C3 0x1b8 #define CLK_SOURCE_I2C4 0x3c4 #define CLK_SOURCE_I2C5 0x128 +#define CLK_SOURCE_I2C6 0x65c #define CLK_SOURCE_UARTA 0x178 #define CLK_SOURCE_UARTB 0x17c #define CLK_SOURCE_UARTC 0x1a0 @@ -77,6 +80,7 @@ #define CLK_SOURCE_3D 0x158 #define CLK_SOURCE_2D 0x15c #define CLK_SOURCE_MPE 0x170 +#define CLK_SOURCE_UARTE 0x1c4 #define CLK_SOURCE_VI_SENSOR 0x1a8 #define CLK_SOURCE_VI 0x148 #define CLK_SOURCE_EPP 0x16c @@ -111,6 +115,16 @@ #define CLK_SOURCE_XUSB_FS_SRC 0x608 #define CLK_SOURCE_XUSB_SS_SRC 0x610 #define CLK_SOURCE_XUSB_DEV_SRC 0x60c +#define CLK_SOURCE_ISP 0x144 +#define CLK_SOURCE_SOR0 0x414 +#define CLK_SOURCE_DPAUX 0x418 +#define CLK_SOURCE_SATA_OOB 0x420 +#define CLK_SOURCE_SATA 0x424 +#define CLK_SOURCE_ENTROPY 0x628 +#define CLK_SOURCE_VI_SENSOR2 0x658 +#define CLK_SOURCE_HDMI_AUDIO 0x668 +#define CLK_SOURCE_VIC03 0x678 +#define CLK_SOURCE_CLK72MHZ 0x66c #define MASK(x) (BIT(x) - 1) @@ -212,12 +226,15 @@ #define PLLP_MISC 0xac #define PLLP_OUTA 0xa4 #define PLLP_OUTB 0xa8 +#define PLLP_OUTC 0x67c #define PLL_BASE_LOCK BIT(27) #define PLL_MISC_LOCK_ENABLE 18 static DEFINE_SPINLOCK(PLLP_OUTA_lock); static DEFINE_SPINLOCK(PLLP_OUTB_lock); +static DEFINE_SPINLOCK(PLLP_OUTC_lock); +static DEFINE_SPINLOCK(sor0_lock); #define MUX_I2S_SPDIF(_id) \ static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ @@ -334,6 +351,41 @@ static const char *mux_pllp_plld_pllc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", "clk_m" }; #define mux_pllp_plld_pllc_clkm_idx NULL +static const char *mux_pllm_pllc_pllp_plla_clkm_pllc4[] = { + "pll_m", "pll_c", "pll_p", "pll_a_out0", "clk_m", "pll_c4", +}; +static u32 mux_pllm_pllc_pllp_plla_clkm_pllc4_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 6, [5] = 7, +}; + +static const char *mux_pllp_clkm1[] = { + "pll_p", "clk_m", +}; +#define mux_pllp_clkm1_idx NULL + +static const char *mux_pllp3_pllc_clkm[] = { + "pll_p_out3", "pll_c", "pll_c2", "clk_m", +}; +#define mux_pllp3_pllc_clkm_idx NULL + +static const char *mux_pllm_pllc_pllp_plla_pllc2_c3_clkm[] = { + "pll_m", "pll_c", "pll_p", "pll_a", "pll_c2", "pll_c3", "clk_m" +}; +static u32 mux_pllm_pllc_pllp_plla_pllc2_c3_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, +}; + +static const char *mux_pllm_pllc2_c_c3_pllp_plla_pllc4[] = { + "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0", "pll_c4", +}; +static u32 mux_pllm_pllc2_c_c3_pllp_plla_pllc4_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, [6] = 7, +}; + +static const char *mux_clkm_plldp_sor0lvds[] = { + "clk_m", "pll_dp", "sor0_lvds", +}; +#define mux_clkm_plldp_sor0lvds_idx NULL static struct tegra_periph_init_data periph_clks[] = { AUDIO("d_audio", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, tegra_clk_d_audio), @@ -354,6 +406,7 @@ static struct tegra_periph_init_data periph_clks[] = { INT("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d), INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde_8), INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_8), + INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla_pllc4, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_9), INT8("epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp_8), INT8("msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, tegra_clk_msenc), INT8("tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, tegra_clk_tsec), @@ -361,6 +414,7 @@ static struct tegra_periph_init_data periph_clks[] = { INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d_8), INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d_8), + INT8("vic03", mux_pllm_pllc_pllp_plla_pllc2_c3_clkm, CLK_SOURCE_VIC03, 178, 0, tegra_clk_vic03), INT_FLAGS("mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, tegra_clk_mselect, CLK_IGNORE_UNUSED), MUX("i2s0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, tegra_clk_i2s0), MUX("i2s1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, tegra_clk_i2s1), @@ -408,6 +462,9 @@ static struct tegra_periph_init_data periph_clks[] = { MUX("ndspeed", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed), MUX("sata_oob", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, tegra_clk_sata_oob), MUX("sata", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, tegra_clk_sata), + MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1), + MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1), + MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2), MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8), MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8), MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8), @@ -422,9 +479,15 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), + MUX8("isp", mux_pllm_pllc_pllp_plla_clkm_pllc4, CLK_SOURCE_ISP, 23, TEGRA_PERIPH_ON_APB, tegra_clk_isp_8), + MUX8("entropy", mux_pllp_clkm1, CLK_SOURCE_ENTROPY, 149, 0, tegra_clk_entropy), + MUX8("hdmi_audio", mux_pllp3_pllc_clkm, CLK_SOURCE_HDMI_AUDIO, 176, TEGRA_PERIPH_NO_RESET, tegra_clk_hdmi_audio), + MUX8("clk72mhz", mux_pllp3_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz), + MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1, NULL), NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2, NULL), + NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), @@ -468,6 +531,11 @@ static struct tegra_periph_init_data gate_clks[] = { GATE("dsib", "dsib_mux", 82, 0, tegra_clk_dsib, 0), GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED), GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0), + GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0), + GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0), + GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), + GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0), + GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), }; struct pll_out_data { @@ -500,6 +568,7 @@ static struct pll_out_data pllp_out_clks[] = { PLL_OUT(2, PLLP_OUTA, 24, TEGRA_DIVIDER_INT, 16, pll_p_out2_int), PLL_OUT(3, PLLP_OUTB, 8, 0, 0, pll_p_out3), PLL_OUT(4, PLLP_OUTB, 24, 0, 16, pll_p_out4), + PLL_OUT(5, PLLP_OUTC, 24, 0, 16, pll_p_out5), }; static void __init periph_clk_init(void __iomem *clk_base, -- cgit v1.2.3 From 76da314df603a08ebc463853030752251b260ab8 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 9 Sep 2013 13:23:56 +0300 Subject: clk: tegra124: Add support for Tegra124 clocks Implement clock support for Tegra124. Signed-off-by: Peter De Schrijver --- .../bindings/clock/nvidia,tegra124-car.txt | 59 + drivers/clk/tegra/Makefile | 1 + drivers/clk/tegra/clk-tegra124.c | 1370 ++++++++++++++++++++ include/dt-bindings/clock/tegra124-car.h | 341 +++++ 4 files changed, 1771 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt create mode 100644 drivers/clk/tegra/clk-tegra124.c create mode 100644 include/dt-bindings/clock/tegra124-car.h (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt new file mode 100644 index 000000000000..1a91ec60dee5 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt @@ -0,0 +1,59 @@ +NVIDIA Tegra124 Clock And Reset Controller + +This binding uses the common clock binding: +Documentation/devicetree/bindings/clock/clock-bindings.txt + +The CAR (Clock And Reset) Controller on Tegra is the HW module responsible +for muxing and gating Tegra's clocks, and setting their rates. + +Required properties : +- compatible : Should be "nvidia,tegra124-car" +- reg : Should contain CAR registers location and length +- clocks : Should contain phandle and clock specifiers for two clocks: + the 32 KHz "32k_in", and the board-specific oscillator "osc". +- #clock-cells : Should be 1. + In clock consumers, this cell represents the clock ID exposed by the + CAR. The assignments may be found in header file + . + +Example SoC include file: + +/ { + tegra_car: clock { + compatible = "nvidia,tegra124-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + }; + + usb@c5004000 { + clocks = <&tegra_car TEGRA124_CLK_USB2>; + }; +}; + +Example board file: + +/ { + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + osc: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <112400000>; + }; + + clk_32k: clock@1 { + compatible = "fixed-clock"; + reg = <1>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + &tegra_car { + clocks = <&clk_32k> <&osc>; + }; +}; diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 2d837411dfed..f7dfb72884a4 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -14,3 +14,4 @@ obj-y += clk-tegra-super-gen4.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c new file mode 100644 index 000000000000..f69367a14777 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra124.c @@ -0,0 +1,1370 @@ +/* + * Copyright (c) 2012, 2013, 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-id.h" + +#define CLK_SOURCE_EMC 0x19c +#define CLK_SOURCE_XUSB_SS_SRC 0x610 + +#define PLLC_BASE 0x80 +#define PLLC_OUT 0x84 +#define PLLC_MISC2 0x88 +#define PLLC_MISC 0x8c +#define PLLC2_BASE 0x4e8 +#define PLLC2_MISC 0x4ec +#define PLLC3_BASE 0x4fc +#define PLLC3_MISC 0x500 +#define PLLM_BASE 0x90 +#define PLLM_OUT 0x94 +#define PLLM_MISC 0x9c +#define PLLP_BASE 0xa0 +#define PLLP_MISC 0xac +#define PLLA_BASE 0xb0 +#define PLLA_MISC 0xbc +#define PLLD_BASE 0xd0 +#define PLLD_MISC 0xdc +#define PLLU_BASE 0xc0 +#define PLLU_MISC 0xcc +#define PLLX_BASE 0xe0 +#define PLLX_MISC 0xe4 +#define PLLX_MISC2 0x514 +#define PLLX_MISC3 0x518 +#define PLLE_BASE 0xe8 +#define PLLE_MISC 0xec +#define PLLD2_BASE 0x4b8 +#define PLLD2_MISC 0x4bc +#define PLLE_AUX 0x48c +#define PLLRE_BASE 0x4c4 +#define PLLRE_MISC 0x4c8 +#define PLLDP_BASE 0x590 +#define PLLDP_MISC 0x594 +#define PLLC4_BASE 0x5a4 +#define PLLC4_MISC 0x5a8 + +#define PLLC_IDDQ_BIT 26 +#define PLLRE_IDDQ_BIT 16 +#define PLLSS_IDDQ_BIT 19 + +#define PLL_BASE_LOCK BIT(27) +#define PLLE_MISC_LOCK BIT(11) +#define PLLRE_MISC_LOCK BIT(24) + +#define PLL_MISC_LOCK_ENABLE 18 +#define PLLC_MISC_LOCK_ENABLE 24 +#define PLLDU_MISC_LOCK_ENABLE 22 +#define PLLE_MISC_LOCK_ENABLE 9 +#define PLLRE_MISC_LOCK_ENABLE 30 +#define PLLSS_MISC_LOCK_ENABLE 30 + +#define PLLXC_SW_MAX_P 6 + +#define PMC_PLLM_WB0_OVERRIDE 0x1dc +#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0 + +#define UTMIP_PLL_CFG2 0x488 +#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) +#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4) + +#define UTMIP_PLL_CFG1 0x484 +#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6) +#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) +#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) + +#define UTMIPLL_HW_PWRDN_CFG0 0x52c +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24) +#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4) +#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) + +static void __iomem *clk_base; +static void __iomem *pmc_base; + +static unsigned long osc_freq; +static unsigned long pll_ref_freq; + +static DEFINE_SPINLOCK(pll_d_lock); +static DEFINE_SPINLOCK(pll_d2_lock); +static DEFINE_SPINLOCK(pll_e_lock); +static DEFINE_SPINLOCK(pll_re_lock); +static DEFINE_SPINLOCK(pll_u_lock); + +/* possible OSC frequencies in Hz */ +static unsigned long tegra124_input_freq[] = { + [0] = 13000000, + [1] = 16800000, + [4] = 19200000, + [5] = 38400000, + [8] = 12000000, + [9] = 48000000, + [12] = 260000000, +}; + +static const char *mux_plld_out0_plld2_out0[] = { + "pll_d_out0", "pll_d2_out0", +}; +#define mux_plld_out0_plld2_out0_idx NULL + +static const char *mux_pllmcp_clkm[] = { + "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3", +}; +#define mux_pllmcp_clkm_idx NULL + +static struct div_nmp pllxc_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 4, +}; + +static struct pdiv_map pllxc_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { + /* 1 GHz */ + {12000000, 1000000000, 83, 0, 1}, /* actual: 996.0 MHz */ + {13000000, 1000000000, 76, 0, 1}, /* actual: 988.0 MHz */ + {16800000, 1000000000, 59, 0, 1}, /* actual: 991.2 MHz */ + {19200000, 1000000000, 52, 0, 1}, /* actual: 998.4 MHz */ + {26000000, 1000000000, 76, 1, 1}, /* actual: 988.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_x_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 700000000, + .vco_max = 3000000000UL, + .base_reg = PLLX_BASE, + .misc_reg = PLLX_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLX_MISC3, + .iddq_bit_idx = 3, + .max_p = 6, + .dyn_ramp_reg = PLLX_MISC2, + .stepa_shift = 16, + .stepb_shift = 24, + .pdiv_tohw = pllxc_p, + .div_nmp = &pllxc_nmp, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { + { 12000000, 624000000, 104, 1, 2}, + { 12000000, 600000000, 100, 1, 2}, + { 13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_c_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 600000000, + .vco_max = 1400000000, + .base_reg = PLLC_BASE, + .misc_reg = PLLC_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLC_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLC_MISC, + .iddq_bit_idx = PLLC_IDDQ_BIT, + .max_p = PLLXC_SW_MAX_P, + .dyn_ramp_reg = PLLC_MISC2, + .stepa_shift = 17, + .stepb_shift = 9, + .pdiv_tohw = pllxc_p, + .div_nmp = &pllxc_nmp, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct div_nmp pllcx_nmp = { + .divm_shift = 0, + .divm_width = 2, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 3, +}; + +static struct pdiv_map pllc_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 6, .hw_val = 4 }, + { .pdiv = 8, .hw_val = 5 }, + { .pdiv = 12, .hw_val = 6 }, + { .pdiv = 16, .hw_val = 7 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { + {12000000, 600000000, 100, 1, 2}, + {13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ + {16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ + {19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ + {26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_c2_params = { + .input_min = 12000000, + .input_max = 48000000, + .cf_min = 12000000, + .cf_max = 19200000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC2_BASE, + .misc_reg = PLLC2_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .pdiv_tohw = pllc_p, + .div_nmp = &pllcx_nmp, + .max_p = 7, + .ext_misc_reg[0] = 0x4f0, + .ext_misc_reg[1] = 0x4f4, + .ext_misc_reg[2] = 0x4f8, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_params pll_c3_params = { + .input_min = 12000000, + .input_max = 48000000, + .cf_min = 12000000, + .cf_max = 19200000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC3_BASE, + .misc_reg = PLLC3_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .pdiv_tohw = pllc_p, + .div_nmp = &pllcx_nmp, + .max_p = 7, + .ext_misc_reg[0] = 0x504, + .ext_misc_reg[1] = 0x508, + .ext_misc_reg[2] = 0x50c, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct div_nmp pllss_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 4, +}; + +static struct pdiv_map pll12g_ssd_esd_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_c4_freq_table[] = { + { 12000000, 600000000, 100, 1, 1}, + { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_c4_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC4_BASE, + .misc_reg = PLLC4_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLC4_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .pdiv_tohw = pll12g_ssd_esd_p, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = 0x5ac, + .ext_misc_reg[1] = 0x5b0, + .ext_misc_reg[2] = 0x5b4, + .freq_table = pll_c4_freq_table, +}; + +static struct pdiv_map pllm_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { + {12000000, 800000000, 66, 1, 1}, /* actual: 792.0 MHz */ + {13000000, 800000000, 61, 1, 1}, /* actual: 793.0 MHz */ + {16800000, 800000000, 47, 1, 1}, /* actual: 789.6 MHz */ + {19200000, 800000000, 41, 1, 1}, /* actual: 787.2 MHz */ + {26000000, 800000000, 61, 2, 1}, /* actual: 793.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct div_nmp pllm_nmp = { + .divm_shift = 0, + .divm_width = 8, + .override_divm_shift = 0, + .divn_shift = 8, + .divn_width = 8, + .override_divn_shift = 8, + .divp_shift = 20, + .divp_width = 1, + .override_divp_shift = 27, +}; + +static struct tegra_clk_pll_params pll_m_params = { + .input_min = 12000000, + .input_max = 500000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 400000000, + .vco_max = 1066000000, + .base_reg = PLLM_BASE, + .misc_reg = PLLM_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .max_p = 2, + .pdiv_tohw = pllm_p, + .div_nmp = &pllm_nmp, + .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, + .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { + /* PLLE special case: use cpcon field to store cml divider value */ + {336000000, 100000000, 100, 21, 16, 11}, + {312000000, 100000000, 200, 26, 24, 13}, + {13000000, 100000000, 200, 1, 26, 13}, + {12000000, 100000000, 200, 1, 24, 13}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct div_nmp plle_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 24, + .divp_width = 4, +}; + +static struct tegra_clk_pll_params pll_e_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 75000000, + .vco_min = 1600000000, + .vco_max = 2400000000U, + .base_reg = PLLE_BASE, + .misc_reg = PLLE_MISC, + .aux_reg = PLLE_AUX, + .lock_mask = PLLE_MISC_LOCK, + .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, + .lock_delay = 300, + .div_nmp = &plle_nmp, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLL_FIXED, + .fixed_rate = 100000000, +}; + +static const struct clk_div_table pll_re_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 3 }, + { .val = 3, .div = 4 }, + { .val = 4, .div = 5 }, + { .val = 5, .div = 6 }, + { .val = 0, .div = 0 }, +}; + +static struct div_nmp pllre_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 16, + .divp_width = 4, +}; + +static struct tegra_clk_pll_params pll_re_vco_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 300000000, + .vco_max = 600000000, + .base_reg = PLLRE_BASE, + .misc_reg = PLLRE_MISC, + .lock_mask = PLLRE_MISC_LOCK, + .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLRE_MISC, + .iddq_bit_idx = PLLRE_IDDQ_BIT, + .div_nmp = &pllre_nmp, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct div_nmp pllp_nmp = { + .divm_shift = 0, + .divm_width = 5, + .divn_shift = 8, + .divn_width = 10, + .divp_shift = 20, + .divp_width = 3, +}; + +static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { + {12000000, 216000000, 432, 12, 1, 8}, + {13000000, 216000000, 432, 13, 1, 8}, + {16800000, 216000000, 360, 14, 1, 8}, + {19200000, 216000000, 360, 16, 1, 8}, + {26000000, 216000000, 432, 26, 1, 8}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_p_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 200000000, + .vco_max = 700000000, + .base_reg = PLLP_BASE, + .misc_reg = PLLP_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .div_nmp = &pllp_nmp, + .freq_table = pll_p_freq_table, + .fixed_rate = 408000000, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { + {9600000, 282240000, 147, 5, 0, 4}, + {9600000, 368640000, 192, 5, 0, 4}, + {9600000, 240000000, 200, 8, 0, 8}, + + {28800000, 282240000, 245, 25, 0, 8}, + {28800000, 368640000, 320, 25, 0, 8}, + {28800000, 240000000, 200, 24, 0, 8}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_a_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 200000000, + .vco_max = 700000000, + .base_reg = PLLA_BASE, + .misc_reg = PLLA_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .div_nmp = &pllp_nmp, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { + {12000000, 216000000, 864, 12, 4, 12}, + {13000000, 216000000, 864, 13, 4, 12}, + {16800000, 216000000, 720, 14, 4, 12}, + {19200000, 216000000, 720, 16, 4, 12}, + {26000000, 216000000, 864, 26, 4, 12}, + + {12000000, 594000000, 594, 12, 1, 12}, + {13000000, 594000000, 594, 13, 1, 12}, + {16800000, 594000000, 495, 14, 1, 12}, + {19200000, 594000000, 495, 16, 1, 12}, + {26000000, 594000000, 594, 26, 1, 12}, + + {12000000, 1000000000, 1000, 12, 1, 12}, + {13000000, 1000000000, 1000, 13, 1, 12}, + {19200000, 1000000000, 625, 12, 1, 12}, + {26000000, 1000000000, 1000, 26, 1, 12}, + + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_d_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 500000000, + .vco_max = 1000000000, + .base_reg = PLLD_BASE, + .misc_reg = PLLD_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, + .div_nmp = &pllp_nmp, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { + { 12000000, 148500000, 99, 1, 8}, + { 12000000, 594000000, 99, 1, 1}, + { 13000000, 594000000, 91, 1, 1}, /* actual: 591.5 MHz */ + { 16800000, 594000000, 71, 1, 1}, /* actual: 596.4 MHz */ + { 19200000, 594000000, 62, 1, 1}, /* actual: 595.2 MHz */ + { 26000000, 594000000, 91, 2, 1}, /* actual: 591.5 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params tegra124_pll_d2_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLD2_BASE, + .misc_reg = PLLD2_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLD2_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .pdiv_tohw = pll12g_ssd_esd_p, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = 0x570, + .ext_misc_reg[1] = 0x574, + .ext_misc_reg[2] = 0x578, + .max_p = 15, + .freq_table = tegra124_pll_d2_freq_table, +}; + +static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = { + { 12000000, 600000000, 100, 1, 1}, + { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_dp_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLDP_BASE, + .misc_reg = PLLDP_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLDP_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .pdiv_tohw = pll12g_ssd_esd_p, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = 0x598, + .ext_misc_reg[1] = 0x59c, + .ext_misc_reg[2] = 0x5a0, + .max_p = 5, + .freq_table = pll_dp_freq_table, +}; + +static struct pdiv_map pllu_p[] = { + { .pdiv = 1, .hw_val = 1 }, + { .pdiv = 2, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct div_nmp pllu_nmp = { + .divm_shift = 0, + .divm_width = 5, + .divn_shift = 8, + .divn_width = 10, + .divp_shift = 20, + .divp_width = 1, +}; + +static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { + {12000000, 480000000, 960, 12, 2, 12}, + {13000000, 480000000, 960, 13, 2, 12}, + {16800000, 480000000, 400, 7, 2, 5}, + {19200000, 480000000, 200, 4, 2, 3}, + {26000000, 480000000, 960, 26, 2, 12}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_u_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 480000000, + .vco_max = 960000000, + .base_reg = PLLU_BASE, + .misc_reg = PLLU_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, + .pdiv_tohw = pllu_p, + .div_nmp = &pllu_nmp, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, +}; + +struct utmi_clk_param { + /* Oscillator Frequency in KHz */ + u32 osc_frequency; + /* UTMIP PLL Enable Delay Count */ + u8 enable_delay_count; + /* UTMIP PLL Stable count */ + u8 stable_count; + /* UTMIP PLL Active delay count */ + u8 active_delay_count; + /* UTMIP PLL Xtal frequency count */ + u8 xtal_freq_count; +}; + +static const struct utmi_clk_param utmi_parameters[] = { + {.osc_frequency = 13000000, .enable_delay_count = 0x02, + .stable_count = 0x33, .active_delay_count = 0x05, + .xtal_freq_count = 0x7F}, + {.osc_frequency = 19200000, .enable_delay_count = 0x03, + .stable_count = 0x4B, .active_delay_count = 0x06, + .xtal_freq_count = 0xBB}, + {.osc_frequency = 12000000, .enable_delay_count = 0x02, + .stable_count = 0x2F, .active_delay_count = 0x04, + .xtal_freq_count = 0x76}, + {.osc_frequency = 26000000, .enable_delay_count = 0x04, + .stable_count = 0x66, .active_delay_count = 0x09, + .xtal_freq_count = 0xFE}, + {.osc_frequency = 16800000, .enable_delay_count = 0x03, + .stable_count = 0x41, .active_delay_count = 0x0A, + .xtal_freq_count = 0xA4}, +}; + +static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { + [tegra_clk_ispb] = { .dt_id = TEGRA124_CLK_ISPB, .present = true }, + [tegra_clk_rtc] = { .dt_id = TEGRA124_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA124_CLK_TIMER, .present = true }, + [tegra_clk_uarta] = { .dt_id = TEGRA124_CLK_UARTA, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, + [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, + [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, + [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, + [tegra_clk_i2s2] = { .dt_id = TEGRA124_CLK_I2S2, .present = true }, + [tegra_clk_gr2d] = { .dt_id = TEGRA124_CLK_GR_2D, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA124_CLK_USBD, .present = true }, + [tegra_clk_isp_8] = { .dt_id = TEGRA124_CLK_ISP, .present = true }, + [tegra_clk_gr3d] = { .dt_id = TEGRA124_CLK_GR_3D, .present = true }, + [tegra_clk_disp2] = { .dt_id = TEGRA124_CLK_DISP2, .present = true }, + [tegra_clk_disp1] = { .dt_id = TEGRA124_CLK_DISP1, .present = true }, + [tegra_clk_host1x] = { .dt_id = TEGRA124_CLK_HOST1X, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA124_CLK_VCP, .present = true }, + [tegra_clk_i2s0] = { .dt_id = TEGRA124_CLK_I2S0, .present = true }, + [tegra_clk_apbdma] = { .dt_id = TEGRA124_CLK_APBDMA, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA124_CLK_KBC, .present = true }, + [tegra_clk_kfuse] = { .dt_id = TEGRA124_CLK_KFUSE, .present = true }, + [tegra_clk_sbc1] = { .dt_id = TEGRA124_CLK_SBC1, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA124_CLK_NOR, .present = true }, + [tegra_clk_sbc2] = { .dt_id = TEGRA124_CLK_SBC2, .present = true }, + [tegra_clk_sbc3] = { .dt_id = TEGRA124_CLK_SBC3, .present = true }, + [tegra_clk_i2c5] = { .dt_id = TEGRA124_CLK_I2C5, .present = true }, + [tegra_clk_dsia] = { .dt_id = TEGRA124_CLK_DSIA, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA124_CLK_MIPI, .present = true }, + [tegra_clk_hdmi] = { .dt_id = TEGRA124_CLK_HDMI, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA124_CLK_CSI, .present = true }, + [tegra_clk_i2c2] = { .dt_id = TEGRA124_CLK_I2C2, .present = true }, + [tegra_clk_uartc] = { .dt_id = TEGRA124_CLK_UARTC, .present = true }, + [tegra_clk_mipi_cal] = { .dt_id = TEGRA124_CLK_MIPI_CAL, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA124_CLK_EMC, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA124_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA124_CLK_USB3, .present = true }, + [tegra_clk_vde_8] = { .dt_id = TEGRA124_CLK_VDE, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA124_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA124_CLK_BSEV, .present = true }, + [tegra_clk_uartd] = { .dt_id = TEGRA124_CLK_UARTD, .present = true }, + [tegra_clk_i2c3] = { .dt_id = TEGRA124_CLK_I2C3, .present = true }, + [tegra_clk_sbc4] = { .dt_id = TEGRA124_CLK_SBC4, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA124_CLK_SDMMC3, .present = true }, + [tegra_clk_pcie] = { .dt_id = TEGRA124_CLK_PCIE, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA124_CLK_OWR, .present = true }, + [tegra_clk_afi] = { .dt_id = TEGRA124_CLK_AFI, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA124_CLK_CSITE, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA124_CLK_LA, .present = true }, + [tegra_clk_trace] = { .dt_id = TEGRA124_CLK_TRACE, .present = true }, + [tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true }, + [tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true }, + [tegra_clk_ndspeed] = { .dt_id = TEGRA124_CLK_NDSPEED, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true }, + [tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true }, + [tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true }, + [tegra_clk_xusb_host] = { .dt_id = TEGRA124_CLK_XUSB_HOST, .present = true }, + [tegra_clk_msenc] = { .dt_id = TEGRA124_CLK_MSENC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA124_CLK_CSUS, .present = true }, + [tegra_clk_mselect] = { .dt_id = TEGRA124_CLK_MSELECT, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA124_CLK_TSENSOR, .present = true }, + [tegra_clk_i2s3] = { .dt_id = TEGRA124_CLK_I2S3, .present = true }, + [tegra_clk_i2s4] = { .dt_id = TEGRA124_CLK_I2S4, .present = true }, + [tegra_clk_i2c4] = { .dt_id = TEGRA124_CLK_I2C4, .present = true }, + [tegra_clk_sbc5] = { .dt_id = TEGRA124_CLK_SBC5, .present = true }, + [tegra_clk_sbc6] = { .dt_id = TEGRA124_CLK_SBC6, .present = true }, + [tegra_clk_d_audio] = { .dt_id = TEGRA124_CLK_D_AUDIO, .present = true }, + [tegra_clk_apbif] = { .dt_id = TEGRA124_CLK_APBIF, .present = true }, + [tegra_clk_dam0] = { .dt_id = TEGRA124_CLK_DAM0, .present = true }, + [tegra_clk_dam1] = { .dt_id = TEGRA124_CLK_DAM1, .present = true }, + [tegra_clk_dam2] = { .dt_id = TEGRA124_CLK_DAM2, .present = true }, + [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA124_CLK_HDA2CODEC_2X, .present = true }, + [tegra_clk_audio0_2x] = { .dt_id = TEGRA124_CLK_AUDIO0_2X, .present = true }, + [tegra_clk_audio1_2x] = { .dt_id = TEGRA124_CLK_AUDIO1_2X, .present = true }, + [tegra_clk_audio2_2x] = { .dt_id = TEGRA124_CLK_AUDIO2_2X, .present = true }, + [tegra_clk_audio3_2x] = { .dt_id = TEGRA124_CLK_AUDIO3_2X, .present = true }, + [tegra_clk_audio4_2x] = { .dt_id = TEGRA124_CLK_AUDIO4_2X, .present = true }, + [tegra_clk_spdif_2x] = { .dt_id = TEGRA124_CLK_SPDIF_2X, .present = true }, + [tegra_clk_actmon] = { .dt_id = TEGRA124_CLK_ACTMON, .present = true }, + [tegra_clk_extern1] = { .dt_id = TEGRA124_CLK_EXTERN1, .present = true }, + [tegra_clk_extern2] = { .dt_id = TEGRA124_CLK_EXTERN2, .present = true }, + [tegra_clk_extern3] = { .dt_id = TEGRA124_CLK_EXTERN3, .present = true }, + [tegra_clk_sata_oob] = { .dt_id = TEGRA124_CLK_SATA_OOB, .present = true }, + [tegra_clk_sata] = { .dt_id = TEGRA124_CLK_SATA, .present = true }, + [tegra_clk_hda] = { .dt_id = TEGRA124_CLK_HDA, .present = true }, + [tegra_clk_se] = { .dt_id = TEGRA124_CLK_SE, .present = true }, + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA124_CLK_HDA2HDMI, .present = true }, + [tegra_clk_sata_cold] = { .dt_id = TEGRA124_CLK_SATA_COLD, .present = true }, + [tegra_clk_cilab] = { .dt_id = TEGRA124_CLK_CILAB, .present = true }, + [tegra_clk_cilcd] = { .dt_id = TEGRA124_CLK_CILCD, .present = true }, + [tegra_clk_cile] = { .dt_id = TEGRA124_CLK_CILE, .present = true }, + [tegra_clk_dsialp] = { .dt_id = TEGRA124_CLK_DSIALP, .present = true }, + [tegra_clk_dsiblp] = { .dt_id = TEGRA124_CLK_DSIBLP, .present = true }, + [tegra_clk_entropy] = { .dt_id = TEGRA124_CLK_ENTROPY, .present = true }, + [tegra_clk_dds] = { .dt_id = TEGRA124_CLK_DDS, .present = true }, + [tegra_clk_dp2] = { .dt_id = TEGRA124_CLK_DP2, .present = true }, + [tegra_clk_amx] = { .dt_id = TEGRA124_CLK_AMX, .present = true }, + [tegra_clk_adx] = { .dt_id = TEGRA124_CLK_ADX, .present = true }, + [tegra_clk_xusb_ss] = { .dt_id = TEGRA124_CLK_XUSB_SS, .present = true }, + [tegra_clk_i2c6] = { .dt_id = TEGRA124_CLK_I2C6, .present = true }, + [tegra_clk_vim2_clk] = { .dt_id = TEGRA124_CLK_VIM2_CLK, .present = true }, + [tegra_clk_hdmi_audio] = { .dt_id = TEGRA124_CLK_HDMI_AUDIO, .present = true }, + [tegra_clk_clk72Mhz] = { .dt_id = TEGRA124_CLK_CLK72MHZ, .present = true }, + [tegra_clk_vic03] = { .dt_id = TEGRA124_CLK_VIC03, .present = true }, + [tegra_clk_adx1] = { .dt_id = TEGRA124_CLK_ADX1, .present = true }, + [tegra_clk_dpaux] = { .dt_id = TEGRA124_CLK_DPAUX, .present = true }, + [tegra_clk_sor0] = { .dt_id = TEGRA124_CLK_SOR0, .present = true }, + [tegra_clk_sor0_lvds] = { .dt_id = TEGRA124_CLK_SOR0_LVDS, .present = true }, + [tegra_clk_gpu] = { .dt_id = TEGRA124_CLK_GPU, .present = true }, + [tegra_clk_amx1] = { .dt_id = TEGRA124_CLK_AMX1, .present = true }, + [tegra_clk_uartb] = { .dt_id = TEGRA124_CLK_UARTB, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA124_CLK_VFIR, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA124_CLK_SPDIF_IN, .present = true }, + [tegra_clk_spdif_out] = { .dt_id = TEGRA124_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_vi_9] = { .dt_id = TEGRA124_CLK_VI, .present = true }, + [tegra_clk_vi_sensor] = { .dt_id = TEGRA124_CLK_VI_SENSOR, .present = true }, + [tegra_clk_fuse] = { .dt_id = TEGRA124_CLK_FUSE, .present = true }, + [tegra_clk_fuse_burn] = { .dt_id = TEGRA124_CLK_FUSE_BURN, .present = true }, + [tegra_clk_clk_32k] = { .dt_id = TEGRA124_CLK_CLK_32K, .present = true }, + [tegra_clk_clk_m] = { .dt_id = TEGRA124_CLK_CLK_M, .present = true }, + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA124_CLK_CLK_M_DIV2, .present = true }, + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA124_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_pll_ref] = { .dt_id = TEGRA124_CLK_PLL_REF, .present = true }, + [tegra_clk_pll_c] = { .dt_id = TEGRA124_CLK_PLL_C, .present = true }, + [tegra_clk_pll_c_out1] = { .dt_id = TEGRA124_CLK_PLL_C_OUT1, .present = true }, + [tegra_clk_pll_c2] = { .dt_id = TEGRA124_CLK_PLL_C2, .present = true }, + [tegra_clk_pll_c3] = { .dt_id = TEGRA124_CLK_PLL_C3, .present = true }, + [tegra_clk_pll_m] = { .dt_id = TEGRA124_CLK_PLL_M, .present = true }, + [tegra_clk_pll_m_out1] = { .dt_id = TEGRA124_CLK_PLL_M_OUT1, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA124_CLK_PLL_P, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA124_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2] = { .dt_id = TEGRA124_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA124_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA124_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_a] = { .dt_id = TEGRA124_CLK_PLL_A, .present = true }, + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA124_CLK_PLL_A_OUT0, .present = true }, + [tegra_clk_pll_d] = { .dt_id = TEGRA124_CLK_PLL_D, .present = true }, + [tegra_clk_pll_d_out0] = { .dt_id = TEGRA124_CLK_PLL_D_OUT0, .present = true }, + [tegra_clk_pll_d2] = { .dt_id = TEGRA124_CLK_PLL_D2, .present = true }, + [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA124_CLK_PLL_D2_OUT0, .present = true }, + [tegra_clk_pll_u] = { .dt_id = TEGRA124_CLK_PLL_U, .present = true }, + [tegra_clk_pll_u_480m] = { .dt_id = TEGRA124_CLK_PLL_U_480M, .present = true }, + [tegra_clk_pll_u_60m] = { .dt_id = TEGRA124_CLK_PLL_U_60M, .present = true }, + [tegra_clk_pll_u_48m] = { .dt_id = TEGRA124_CLK_PLL_U_48M, .present = true }, + [tegra_clk_pll_u_12m] = { .dt_id = TEGRA124_CLK_PLL_U_12M, .present = true }, + [tegra_clk_pll_x] = { .dt_id = TEGRA124_CLK_PLL_X, .present = true }, + [tegra_clk_pll_x_out0] = { .dt_id = TEGRA124_CLK_PLL_X_OUT0, .present = true }, + [tegra_clk_pll_re_vco] = { .dt_id = TEGRA124_CLK_PLL_RE_VCO, .present = true }, + [tegra_clk_pll_re_out] = { .dt_id = TEGRA124_CLK_PLL_RE_OUT, .present = true }, + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA124_CLK_SPDIF_IN_SYNC, .present = true }, + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA124_CLK_I2S0_SYNC, .present = true }, + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA124_CLK_I2S1_SYNC, .present = true }, + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA124_CLK_I2S2_SYNC, .present = true }, + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA124_CLK_I2S3_SYNC, .present = true }, + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA124_CLK_I2S4_SYNC, .present = true }, + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA124_CLK_VIMCLK_SYNC, .present = true }, + [tegra_clk_audio0] = { .dt_id = TEGRA124_CLK_AUDIO0, .present = true }, + [tegra_clk_audio1] = { .dt_id = TEGRA124_CLK_AUDIO1, .present = true }, + [tegra_clk_audio2] = { .dt_id = TEGRA124_CLK_AUDIO2, .present = true }, + [tegra_clk_audio3] = { .dt_id = TEGRA124_CLK_AUDIO3, .present = true }, + [tegra_clk_audio4] = { .dt_id = TEGRA124_CLK_AUDIO4, .present = true }, + [tegra_clk_spdif] = { .dt_id = TEGRA124_CLK_SPDIF, .present = true }, + [tegra_clk_clk_out_1] = { .dt_id = TEGRA124_CLK_CLK_OUT_1, .present = true }, + [tegra_clk_clk_out_2] = { .dt_id = TEGRA124_CLK_CLK_OUT_2, .present = true }, + [tegra_clk_clk_out_3] = { .dt_id = TEGRA124_CLK_CLK_OUT_3, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA124_CLK_BLINK, .present = true }, + [tegra_clk_xusb_host_src] = { .dt_id = TEGRA124_CLK_XUSB_HOST_SRC, .present = true }, + [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true }, + [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true }, + [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA124_CLK_XUSB_SS_SRC, .present = true }, + [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA124_CLK_XUSB_DEV_SRC, .present = true }, + [tegra_clk_xusb_dev] = { .dt_id = TEGRA124_CLK_XUSB_DEV, .present = true }, + [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA124_CLK_XUSB_HS_SRC, .present = true }, + [tegra_clk_sclk] = { .dt_id = TEGRA124_CLK_SCLK, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA124_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA124_CLK_PCLK, .present = true }, + [tegra_clk_cclk_g] = { .dt_id = TEGRA124_CLK_CCLK_G, .present = true }, + [tegra_clk_cclk_lp] = { .dt_id = TEGRA124_CLK_CCLK_LP, .present = true }, + [tegra_clk_dfll_ref] = { .dt_id = TEGRA124_CLK_DFLL_REF, .present = true }, + [tegra_clk_dfll_soc] = { .dt_id = TEGRA124_CLK_DFLL_SOC, .present = true }, + [tegra_clk_vi_sensor2] = { .dt_id = TEGRA124_CLK_VI_SENSOR2, .present = true }, + [tegra_clk_pll_p_out5] = { .dt_id = TEGRA124_CLK_PLL_P_OUT5, .present = true }, + [tegra_clk_pll_c4] = { .dt_id = TEGRA124_CLK_PLL_C4, .present = true }, + [tegra_clk_pll_dp] = { .dt_id = TEGRA124_CLK_PLL_DP, .present = true }, + [tegra_clk_audio0_mux] = { .dt_id = TEGRA124_CLK_AUDIO0_MUX, .present = true }, + [tegra_clk_audio1_mux] = { .dt_id = TEGRA124_CLK_AUDIO1_MUX, .present = true }, + [tegra_clk_audio2_mux] = { .dt_id = TEGRA124_CLK_AUDIO2_MUX, .present = true }, + [tegra_clk_audio3_mux] = { .dt_id = TEGRA124_CLK_AUDIO3_MUX, .present = true }, + [tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true }, + [tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true }, + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true }, + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true }, + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true }, + [tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true }, + [tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true }, + [tegra_clk_uarte] = { .dt_id = TEGRA124_CLK_UARTE, .present = true }, +}; + +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "clk_m", .dt_id = TEGRA124_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA124_CLK_PLL_REF }, + { .con_id = "clk_32k", .dt_id = TEGRA124_CLK_CLK_32K }, + { .con_id = "clk_m_div2", .dt_id = TEGRA124_CLK_CLK_M_DIV2 }, + { .con_id = "clk_m_div4", .dt_id = TEGRA124_CLK_CLK_M_DIV4 }, + { .con_id = "pll_c", .dt_id = TEGRA124_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA124_CLK_PLL_C_OUT1 }, + { .con_id = "pll_c2", .dt_id = TEGRA124_CLK_PLL_C2 }, + { .con_id = "pll_c3", .dt_id = TEGRA124_CLK_PLL_C3 }, + { .con_id = "pll_p", .dt_id = TEGRA124_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA124_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA124_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA124_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA124_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA124_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA124_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA124_CLK_PLL_X }, + { .con_id = "pll_x_out0", .dt_id = TEGRA124_CLK_PLL_X_OUT0 }, + { .con_id = "pll_u", .dt_id = TEGRA124_CLK_PLL_U }, + { .con_id = "pll_u_480M", .dt_id = TEGRA124_CLK_PLL_U_480M }, + { .con_id = "pll_u_60M", .dt_id = TEGRA124_CLK_PLL_U_60M }, + { .con_id = "pll_u_48M", .dt_id = TEGRA124_CLK_PLL_U_48M }, + { .con_id = "pll_u_12M", .dt_id = TEGRA124_CLK_PLL_U_12M }, + { .con_id = "pll_d", .dt_id = TEGRA124_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA124_CLK_PLL_D_OUT0 }, + { .con_id = "pll_d2", .dt_id = TEGRA124_CLK_PLL_D2 }, + { .con_id = "pll_d2_out0", .dt_id = TEGRA124_CLK_PLL_D2_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA124_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA124_CLK_PLL_A_OUT0 }, + { .con_id = "pll_re_vco", .dt_id = TEGRA124_CLK_PLL_RE_VCO }, + { .con_id = "pll_re_out", .dt_id = TEGRA124_CLK_PLL_RE_OUT }, + { .con_id = "spdif_in_sync", .dt_id = TEGRA124_CLK_SPDIF_IN_SYNC }, + { .con_id = "i2s0_sync", .dt_id = TEGRA124_CLK_I2S0_SYNC }, + { .con_id = "i2s1_sync", .dt_id = TEGRA124_CLK_I2S1_SYNC }, + { .con_id = "i2s2_sync", .dt_id = TEGRA124_CLK_I2S2_SYNC }, + { .con_id = "i2s3_sync", .dt_id = TEGRA124_CLK_I2S3_SYNC }, + { .con_id = "i2s4_sync", .dt_id = TEGRA124_CLK_I2S4_SYNC }, + { .con_id = "vimclk_sync", .dt_id = TEGRA124_CLK_VIMCLK_SYNC }, + { .con_id = "audio0", .dt_id = TEGRA124_CLK_AUDIO0 }, + { .con_id = "audio1", .dt_id = TEGRA124_CLK_AUDIO1 }, + { .con_id = "audio2", .dt_id = TEGRA124_CLK_AUDIO2 }, + { .con_id = "audio3", .dt_id = TEGRA124_CLK_AUDIO3 }, + { .con_id = "audio4", .dt_id = TEGRA124_CLK_AUDIO4 }, + { .con_id = "spdif", .dt_id = TEGRA124_CLK_SPDIF }, + { .con_id = "audio0_2x", .dt_id = TEGRA124_CLK_AUDIO0_2X }, + { .con_id = "audio1_2x", .dt_id = TEGRA124_CLK_AUDIO1_2X }, + { .con_id = "audio2_2x", .dt_id = TEGRA124_CLK_AUDIO2_2X }, + { .con_id = "audio3_2x", .dt_id = TEGRA124_CLK_AUDIO3_2X }, + { .con_id = "audio4_2x", .dt_id = TEGRA124_CLK_AUDIO4_2X }, + { .con_id = "spdif_2x", .dt_id = TEGRA124_CLK_SPDIF_2X }, + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA124_CLK_EXTERN1 }, + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA124_CLK_EXTERN2 }, + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA124_CLK_EXTERN3 }, + { .con_id = "blink", .dt_id = TEGRA124_CLK_BLINK }, + { .con_id = "cclk_g", .dt_id = TEGRA124_CLK_CCLK_G }, + { .con_id = "cclk_lp", .dt_id = TEGRA124_CLK_CCLK_LP }, + { .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA124_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA124_CLK_PCLK }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA124_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA124_CLK_TIMER }, +}; + +static struct clk **clks; + +static void tegra124_utmi_param_configure(void __iomem *clk_base) +{ + u32 reg; + int i; + + for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { + if (osc_freq == utmi_parameters[i].osc_frequency) + break; + } + + if (i >= ARRAY_SIZE(utmi_parameters)) { + pr_err("%s: Unexpected oscillator freq %lu\n", __func__, + osc_freq); + return; + } + + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL stable and active counts */ + /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */ + reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); + reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); + + reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i]. + active_delay_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN; + + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL delay and oscillator frequency counts */ + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i]. + enable_delay_count); + + reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); + reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i]. + xtal_freq_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + /* Setup HW control of UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET; + reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL; + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + udelay(1); + + /* Setup SW override of UTMIPLL assuming USB2.0 + ports are assigned to USB2 */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL; + reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + udelay(1); + + /* Enable HW control UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); +} + +static __init void tegra124_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base) +{ + struct clk *clk; + u32 val; + + /* xusb_hs_src */ + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); + val |= BIT(25); /* always select PLLU_60M */ + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); + + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, + 1, 1); + clks[TEGRA124_CLK_XUSB_HS_SRC] = clk; + + /* dsia mux */ + clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, + clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); + clks[TEGRA124_CLK_DSIA_MUX] = clk; + + /* dsib mux */ + clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, + clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); + clks[TEGRA124_CLK_DSIB_MUX] = clk; + + /* emc mux */ + clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, + ARRAY_SIZE(mux_pllmcp_clkm), 0, + clk_base + CLK_SOURCE_EMC, + 29, 3, 0, NULL); + + /* cml0 */ + clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, + 0, 0, &pll_e_lock); + clk_register_clkdev(clk, "cml0", NULL); + clks[TEGRA124_CLK_CML0] = clk; + + /* cml1 */ + clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, + 1, 0, &pll_e_lock); + clk_register_clkdev(clk, "cml1", NULL); + clks[TEGRA124_CLK_CML1] = clk; + + tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params); +} + +static void __init tegra124_pll_init(void __iomem *clk_base, + void __iomem *pmc) +{ + u32 val; + struct clk *clk; + + /* PLLC */ + clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, + pmc, 0, &pll_c_params, NULL); + clk_register_clkdev(clk, "pll_c", NULL); + clks[TEGRA124_CLK_PLL_C] = clk; + + /* PLLC_OUT1 */ + clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", + clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", + clk_base + PLLC_OUT, 1, 0, + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_c_out1", NULL); + clks[TEGRA124_CLK_PLL_C_OUT1] = clk; + + /* PLLC2 */ + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, + &pll_c2_params, NULL); + clk_register_clkdev(clk, "pll_c2", NULL); + clks[TEGRA124_CLK_PLL_C2] = clk; + + /* PLLC3 */ + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, + &pll_c3_params, NULL); + clk_register_clkdev(clk, "pll_c3", NULL); + clks[TEGRA124_CLK_PLL_C3] = clk; + + /* PLLM */ + clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clk_register_clkdev(clk, "pll_m", NULL); + clks[TEGRA124_CLK_PLL_M] = clk; + + /* PLLM_OUT1 */ + clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", + clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", + clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_m_out1", NULL); + clks[TEGRA124_CLK_PLL_M_OUT1] = clk; + + /* PLLM_UD */ + clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", + CLK_SET_RATE_PARENT, 1, 1); + + /* PLLU */ + val = readl(clk_base + pll_u_params.base_reg); + val &= ~BIT(24); /* disable PLLU_OVERRIDE */ + writel(val, clk_base + pll_u_params.base_reg); + + clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, + &pll_u_params, &pll_u_lock); + clk_register_clkdev(clk, "pll_u", NULL); + clks[TEGRA124_CLK_PLL_U] = clk; + + tegra124_utmi_param_configure(clk_base); + + /* PLLU_480M */ + clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 22, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_480M", NULL); + clks[TEGRA124_CLK_PLL_U_480M] = clk; + + /* PLLU_60M */ + clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", + CLK_SET_RATE_PARENT, 1, 8); + clk_register_clkdev(clk, "pll_u_60M", NULL); + clks[TEGRA124_CLK_PLL_U_60M] = clk; + + /* PLLU_48M */ + clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", + CLK_SET_RATE_PARENT, 1, 10); + clk_register_clkdev(clk, "pll_u_48M", NULL); + clks[TEGRA124_CLK_PLL_U_48M] = clk; + + /* PLLU_12M */ + clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", + CLK_SET_RATE_PARENT, 1, 40); + clk_register_clkdev(clk, "pll_u_12M", NULL); + clks[TEGRA124_CLK_PLL_U_12M] = clk; + + /* PLLD */ + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, + &pll_d_params, &pll_d_lock); + clk_register_clkdev(clk, "pll_d", NULL); + clks[TEGRA124_CLK_PLL_D] = clk; + + /* PLLD_OUT0 */ + clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_d_out0", NULL); + clks[TEGRA124_CLK_PLL_D_OUT0] = clk; + + /* PLLRE */ + clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, + 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); + clk_register_clkdev(clk, "pll_re_vco", NULL); + clks[TEGRA124_CLK_PLL_RE_VCO] = clk; + + clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, + clk_base + PLLRE_BASE, 16, 4, 0, + pll_re_div_table, &pll_re_lock); + clk_register_clkdev(clk, "pll_re_out", NULL); + clks[TEGRA124_CLK_PLL_RE_OUT] = clk; + + /* PLLE */ + clk = tegra_clk_register_plle_tegra114("pll_e", "pll_ref", + clk_base, 0, &pll_e_params, NULL); + clk_register_clkdev(clk, "pll_e", NULL); + clks[TEGRA124_CLK_PLL_E] = clk; + + /* PLLC4 */ + clk = tegra_clk_register_pllss("pll_c4", "pll_ref", clk_base, 0, + &pll_c4_params, NULL); + clk_register_clkdev(clk, "pll_c4", NULL); + clks[TEGRA124_CLK_PLL_C4] = clk; + + /* PLLDP */ + clk = tegra_clk_register_pllss("pll_dp", "pll_ref", clk_base, 0, + &pll_dp_params, NULL); + clk_register_clkdev(clk, "pll_dp", NULL); + clks[TEGRA124_CLK_PLL_DP] = clk; + + /* PLLD2 */ + clk = tegra_clk_register_pllss("pll_d2", "pll_ref", clk_base, 0, + &tegra124_pll_d2_params, NULL); + clk_register_clkdev(clk, "pll_d2", NULL); + clks[TEGRA124_CLK_PLL_D2] = clk; + + /* PLLD2_OUT0 ?? */ + clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_d2_out0", NULL); + clks[TEGRA124_CLK_PLL_D2_OUT0] = clk; + +} + +static const struct of_device_id pmc_match[] __initconst = { + { .compatible = "nvidia,tegra124-pmc" }, + {}, +}; + +static struct tegra_clk_init_table init_table[] __initdata = { + {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1}, + {TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1}, + {TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1}, + {TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1}, + {TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1}, + {TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0}, + {TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1}, + {TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1}, + {TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1}, + {TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1}, + {TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0}, + {TEGRA124_CLK_PLL_C_OUT1, TEGRA124_CLK_CLK_MAX, 100000000, 0}, + {TEGRA124_CLK_SBC4, TEGRA124_CLK_PLL_P, 12000000, 1}, + {TEGRA124_CLK_TSEC, TEGRA124_CLK_PLL_C3, 0, 0}, + {TEGRA124_CLK_MSENC, TEGRA124_CLK_PLL_C3, 0, 0}, + /* This MUST be the last entry. */ + {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, +}; + +static void __init tegra124_clock_apply_init_table(void) +{ + tegra_init_from_table(init_table, clks, TEGRA124_CLK_CLK_MAX); +} + +static void __init tegra124_clock_init(struct device_node *np) +{ + struct device_node *node; + + clk_base = of_iomap(np, 0); + if (!clk_base) { + pr_err("ioremap tegra124 CAR failed\n"); + return; + } + + node = of_find_matching_node(NULL, pmc_match); + if (!node) { + pr_err("Failed to find pmc node\n"); + WARN_ON(1); + return; + } + + pmc_base = of_iomap(node, 0); + if (!pmc_base) { + pr_err("Can't map pmc registers\n"); + WARN_ON(1); + return; + } + + clks = tegra_clk_init(TEGRA124_CLK_CLK_MAX, 6); + if (!clks) + return; + + if (tegra_osc_clk_init(clk_base, tegra124_clks, tegra124_input_freq, + ARRAY_SIZE(tegra124_input_freq), &osc_freq, &pll_ref_freq) < 0) + return; + + tegra_fixed_clk_init(tegra124_clks); + tegra124_pll_init(clk_base, pmc_base); + tegra124_periph_clk_init(clk_base, pmc_base); + tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params); + tegra_pmc_clk_init(pmc_base, tegra124_clks); + + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, + &pll_x_params); + tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); + + tegra_clk_apply_init_table = tegra124_clock_apply_init_table; +} +CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init); diff --git a/include/dt-bindings/clock/tegra124-car.h b/include/dt-bindings/clock/tegra124-car.h new file mode 100644 index 000000000000..a1116a3b54ef --- /dev/null +++ b/include/dt-bindings/clock/tegra124-car.h @@ -0,0 +1,341 @@ +/* + * This header provides constants for binding nvidia,tegra124-car. + * + * The first 192 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB + * registers. These IDs often match those in the CAR's RST_DEVICES registers, + * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In + * this case, those clocks are assigned IDs above 185 in order to highlight + * this issue. Implementations that interpret these clock IDs as bit values + * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to + * explicitly handle these special cases. + * + * The balance of the clocks controlled by the CAR are assigned IDs of 185 and + * above. + */ + +#ifndef _DT_BINDINGS_CLOCK_TEGRA124_CAR_H +#define _DT_BINDINGS_CLOCK_TEGRA124_CAR_H + +/* 0 */ +/* 1 */ +/* 2 */ +#define TEGRA124_CLK_ISPB 3 +#define TEGRA124_CLK_RTC 4 +#define TEGRA124_CLK_TIMER 5 +#define TEGRA124_CLK_UARTA 6 +/* 7 (register bit affects uartb and vfir) */ +/* 8 */ +#define TEGRA124_CLK_SDMMC2 9 +/* 10 (register bit affects spdif_in and spdif_out) */ +#define TEGRA124_CLK_I2S1 11 +#define TEGRA124_CLK_I2C1 12 +#define TEGRA124_CLK_NDFLASH 13 +#define TEGRA124_CLK_SDMMC1 14 +#define TEGRA124_CLK_SDMMC4 15 +/* 16 */ +#define TEGRA124_CLK_PWM 17 +#define TEGRA124_CLK_I2S2 18 +/* 20 (register bit affects vi and vi_sensor) */ +#define TEGRA124_CLK_GR_2D 21 +#define TEGRA124_CLK_USBD 22 +#define TEGRA124_CLK_ISP 23 +#define TEGRA124_CLK_GR_3D 24 +/* 25 */ +#define TEGRA124_CLK_DISP2 26 +#define TEGRA124_CLK_DISP1 27 +#define TEGRA124_CLK_HOST1X 28 +#define TEGRA124_CLK_VCP 29 +#define TEGRA124_CLK_I2S0 30 +/* 31 */ + +/* 32 */ +/* 33 */ +#define TEGRA124_CLK_APBDMA 34 +/* 35 */ +#define TEGRA124_CLK_KBC 36 +/* 37 */ +/* 38 */ +/* 39 (register bit affects fuse and fuse_burn) */ +#define TEGRA124_CLK_KFUSE 40 +#define TEGRA124_CLK_SBC1 41 +#define TEGRA124_CLK_NOR 42 +/* 43 */ +#define TEGRA124_CLK_SBC2 44 +/* 45 */ +#define TEGRA124_CLK_SBC3 46 +#define TEGRA124_CLK_I2C5 47 +#define TEGRA124_CLK_DSIA 48 +/* 49 */ +#define TEGRA124_CLK_MIPI 50 +#define TEGRA124_CLK_HDMI 51 +#define TEGRA124_CLK_CSI 52 +/* 53 */ +#define TEGRA124_CLK_I2C2 54 +#define TEGRA124_CLK_UARTC 55 +#define TEGRA124_CLK_MIPI_CAL 56 +#define TEGRA124_CLK_EMC 57 +#define TEGRA124_CLK_USB2 58 +#define TEGRA124_CLK_USB3 59 +/* 60 */ +#define TEGRA124_CLK_VDE 61 +#define TEGRA124_CLK_BSEA 62 +#define TEGRA124_CLK_BSEV 63 + +/* 64 */ +#define TEGRA124_CLK_UARTD 65 +#define TEGRA124_CLK_UARTE 66 +#define TEGRA124_CLK_I2C3 67 +#define TEGRA124_CLK_SBC4 68 +#define TEGRA124_CLK_SDMMC3 69 +#define TEGRA124_CLK_PCIE 70 +#define TEGRA124_CLK_OWR 71 +#define TEGRA124_CLK_AFI 72 +#define TEGRA124_CLK_CSITE 73 +/* 74 */ +/* 75 */ +#define TEGRA124_CLK_LA 76 +#define TEGRA124_CLK_TRACE 77 +#define TEGRA124_CLK_SOC_THERM 78 +#define TEGRA124_CLK_DTV 79 +#define TEGRA124_CLK_NDSPEED 80 +#define TEGRA124_CLK_I2CSLOW 81 +#define TEGRA124_CLK_DSIB 82 +#define TEGRA124_CLK_TSEC 83 +/* 84 */ +/* 85 */ +/* 86 */ +/* 87 */ +/* 88 */ +#define TEGRA124_CLK_XUSB_HOST 89 +/* 90 */ +#define TEGRA124_CLK_MSENC 91 +#define TEGRA124_CLK_CSUS 92 +/* 93 */ +/* 94 */ +/* 95 (bit affects xusb_dev and xusb_dev_src) */ + +/* 96 */ +/* 97 */ +/* 98 */ +#define TEGRA124_CLK_MSELECT 99 +#define TEGRA124_CLK_TSENSOR 100 +#define TEGRA124_CLK_I2S3 101 +#define TEGRA124_CLK_I2S4 102 +#define TEGRA124_CLK_I2C4 103 +#define TEGRA124_CLK_SBC5 104 +#define TEGRA124_CLK_SBC6 105 +#define TEGRA124_CLK_D_AUDIO 106 +#define TEGRA124_CLK_APBIF 107 +#define TEGRA124_CLK_DAM0 108 +#define TEGRA124_CLK_DAM1 109 +#define TEGRA124_CLK_DAM2 110 +#define TEGRA124_CLK_HDA2CODEC_2X 111 +/* 112 */ +#define TEGRA124_CLK_AUDIO0_2X 113 +#define TEGRA124_CLK_AUDIO1_2X 114 +#define TEGRA124_CLK_AUDIO2_2X 115 +#define TEGRA124_CLK_AUDIO3_2X 116 +#define TEGRA124_CLK_AUDIO4_2X 117 +#define TEGRA124_CLK_SPDIF_2X 118 +#define TEGRA124_CLK_ACTMON 119 +#define TEGRA124_CLK_EXTERN1 120 +#define TEGRA124_CLK_EXTERN2 121 +#define TEGRA124_CLK_EXTERN3 122 +#define TEGRA124_CLK_SATA_OOB 123 +#define TEGRA124_CLK_SATA 124 +#define TEGRA124_CLK_HDA 125 +/* 126 */ +#define TEGRA124_CLK_SE 127 + +#define TEGRA124_CLK_HDA2HDMI 128 +#define TEGRA124_CLK_SATA_COLD 129 +/* 130 */ +/* 131 */ +/* 132 */ +/* 133 */ +/* 134 */ +/* 135 */ +/* 136 */ +/* 137 */ +/* 138 */ +/* 139 */ +/* 140 */ +/* 141 */ +/* 142 */ +/* 143 (bit affects xusb_falcon_src, xusb_fs_src, */ +/* xusb_host_src and xusb_ss_src) */ +#define TEGRA124_CLK_CILAB 144 +#define TEGRA124_CLK_CILCD 145 +#define TEGRA124_CLK_CILE 146 +#define TEGRA124_CLK_DSIALP 147 +#define TEGRA124_CLK_DSIBLP 148 +#define TEGRA124_CLK_ENTROPY 149 +#define TEGRA124_CLK_DDS 150 +/* 151 */ +#define TEGRA124_CLK_DP2 152 +#define TEGRA124_CLK_AMX 153 +#define TEGRA124_CLK_ADX 154 +/* 155 (bit affects dfll_ref and dfll_soc) */ +#define TEGRA124_CLK_XUSB_SS 156 +/* 157 */ +/* 158 */ +/* 159 */ + +/* 160 */ +/* 161 */ +/* 162 */ +/* 163 */ +/* 164 */ +/* 165 */ +#define TEGRA124_CLK_I2C6 166 +/* 167 */ +/* 168 */ +/* 169 */ +/* 170 */ +#define TEGRA124_CLK_VIM2_CLK 171 +/* 172 */ +/* 173 */ +/* 174 */ +/* 175 */ +#define TEGRA124_CLK_HDMI_AUDIO 176 +#define TEGRA124_CLK_CLK72MHZ 177 +#define TEGRA124_CLK_VIC03 178 +/* 179 */ +#define TEGRA124_CLK_ADX1 180 +#define TEGRA124_CLK_DPAUX 181 +#define TEGRA124_CLK_SOR0 182 +/* 183 */ +#define TEGRA124_CLK_GPU 184 +#define TEGRA124_CLK_AMX1 185 +/* 186 */ +/* 187 */ +/* 188 */ +/* 189 */ +/* 190 */ +/* 191 */ +#define TEGRA124_CLK_UARTB 192 +#define TEGRA124_CLK_VFIR 193 +#define TEGRA124_CLK_SPDIF_IN 194 +#define TEGRA124_CLK_SPDIF_OUT 195 +#define TEGRA124_CLK_VI 196 +#define TEGRA124_CLK_VI_SENSOR 197 +#define TEGRA124_CLK_FUSE 198 +#define TEGRA124_CLK_FUSE_BURN 199 +#define TEGRA124_CLK_CLK_32K 200 +#define TEGRA124_CLK_CLK_M 201 +#define TEGRA124_CLK_CLK_M_DIV2 202 +#define TEGRA124_CLK_CLK_M_DIV4 203 +#define TEGRA124_CLK_PLL_REF 204 +#define TEGRA124_CLK_PLL_C 205 +#define TEGRA124_CLK_PLL_C_OUT1 206 +#define TEGRA124_CLK_PLL_C2 207 +#define TEGRA124_CLK_PLL_C3 208 +#define TEGRA124_CLK_PLL_M 209 +#define TEGRA124_CLK_PLL_M_OUT1 210 +#define TEGRA124_CLK_PLL_P 211 +#define TEGRA124_CLK_PLL_P_OUT1 212 +#define TEGRA124_CLK_PLL_P_OUT2 213 +#define TEGRA124_CLK_PLL_P_OUT3 214 +#define TEGRA124_CLK_PLL_P_OUT4 215 +#define TEGRA124_CLK_PLL_A 216 +#define TEGRA124_CLK_PLL_A_OUT0 217 +#define TEGRA124_CLK_PLL_D 218 +#define TEGRA124_CLK_PLL_D_OUT0 219 +#define TEGRA124_CLK_PLL_D2 220 +#define TEGRA124_CLK_PLL_D2_OUT0 221 +#define TEGRA124_CLK_PLL_U 222 +#define TEGRA124_CLK_PLL_U_480M 223 + +#define TEGRA124_CLK_PLL_U_60M 224 +#define TEGRA124_CLK_PLL_U_48M 225 +#define TEGRA124_CLK_PLL_U_12M 226 +#define TEGRA124_CLK_PLL_X 227 +#define TEGRA124_CLK_PLL_X_OUT0 228 +#define TEGRA124_CLK_PLL_RE_VCO 229 +#define TEGRA124_CLK_PLL_RE_OUT 230 +#define TEGRA124_CLK_PLL_E 231 +#define TEGRA124_CLK_SPDIF_IN_SYNC 232 +#define TEGRA124_CLK_I2S0_SYNC 233 +#define TEGRA124_CLK_I2S1_SYNC 234 +#define TEGRA124_CLK_I2S2_SYNC 235 +#define TEGRA124_CLK_I2S3_SYNC 236 +#define TEGRA124_CLK_I2S4_SYNC 237 +#define TEGRA124_CLK_VIMCLK_SYNC 238 +#define TEGRA124_CLK_AUDIO0 239 +#define TEGRA124_CLK_AUDIO1 240 +#define TEGRA124_CLK_AUDIO2 241 +#define TEGRA124_CLK_AUDIO3 242 +#define TEGRA124_CLK_AUDIO4 243 +#define TEGRA124_CLK_SPDIF 244 +#define TEGRA124_CLK_CLK_OUT_1 245 +#define TEGRA124_CLK_CLK_OUT_2 246 +#define TEGRA124_CLK_CLK_OUT_3 247 +#define TEGRA124_CLK_BLINK 248 +/* 249 */ +/* 250 */ +/* 251 */ +#define TEGRA124_CLK_XUSB_HOST_SRC 252 +#define TEGRA124_CLK_XUSB_FALCON_SRC 253 +#define TEGRA124_CLK_XUSB_FS_SRC 254 +#define TEGRA124_CLK_XUSB_SS_SRC 255 + +#define TEGRA124_CLK_XUSB_DEV_SRC 256 +#define TEGRA124_CLK_XUSB_DEV 257 +#define TEGRA124_CLK_XUSB_HS_SRC 258 +#define TEGRA124_CLK_SCLK 259 +#define TEGRA124_CLK_HCLK 260 +#define TEGRA124_CLK_PCLK 261 +#define TEGRA124_CLK_CCLK_G 262 +#define TEGRA124_CLK_CCLK_LP 263 +#define TEGRA124_CLK_DFLL_REF 264 +#define TEGRA124_CLK_DFLL_SOC 265 +#define TEGRA124_CLK_VI_SENSOR2 266 +#define TEGRA124_CLK_PLL_P_OUT5 267 +#define TEGRA124_CLK_CML0 268 +#define TEGRA124_CLK_CML1 269 +#define TEGRA124_CLK_PLL_C4 270 +#define TEGRA124_CLK_PLL_DP 271 +#define TEGRA124_CLK_PLL_E_MUX 272 +/* 273 */ +/* 274 */ +/* 275 */ +/* 276 */ +/* 277 */ +/* 278 */ +/* 279 */ +/* 280 */ +/* 281 */ +/* 282 */ +/* 283 */ +/* 284 */ +/* 285 */ +/* 286 */ +/* 287 */ + +/* 288 */ +/* 289 */ +/* 290 */ +/* 291 */ +/* 292 */ +/* 293 */ +/* 294 */ +/* 295 */ +/* 296 */ +/* 297 */ +/* 298 */ +/* 299 */ +#define TEGRA124_CLK_AUDIO0_MUX 300 +#define TEGRA124_CLK_AUDIO1_MUX 301 +#define TEGRA124_CLK_AUDIO2_MUX 302 +#define TEGRA124_CLK_AUDIO3_MUX 303 +#define TEGRA124_CLK_AUDIO4_MUX 304 +#define TEGRA124_CLK_SPDIF_MUX 305 +#define TEGRA124_CLK_CLK_OUT_1_MUX 306 +#define TEGRA124_CLK_CLK_OUT_2_MUX 307 +#define TEGRA124_CLK_CLK_OUT_3_MUX 308 +#define TEGRA124_CLK_DSIA_MUX 309 +#define TEGRA124_CLK_DSIB_MUX 310 +#define TEGRA124_CLK_SOR0_LVDS 311 +#define TEGRA124_CLK_CLK_MAX 312 + +#endif /* _DT_BINDINGS_CLOCK_TEGRA124_CAR_H */ -- cgit v1.2.3 From 9e036d3ef0b9fcb34acce5a89d1f2157f4f7b4ab Mon Sep 17 00:00:00 2001 From: Joseph Lo Date: Wed, 25 Sep 2013 17:27:51 +0800 Subject: clk: tegra124: add wait_for_reset and disable_clock for tegra_cpu_car_ops Hook the functions for CPU hotplug support. After the CPU is hot unplugged, the flow controller will handle to clock gate the CPU clock. But still need to implement an empty function to avoid warning message. Cc: Mike Turquette Signed-off-by: Joseph Lo --- drivers/clk/tegra/clk-tegra124.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index f69367a14777..345192233871 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -112,6 +112,9 @@ #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) +/* Tegra CPU clock and reset control regs */ +#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 + static void __iomem *clk_base; static void __iomem *pmc_base; @@ -1283,6 +1286,27 @@ static void __init tegra124_pll_init(void __iomem *clk_base, } +/* Tegra124 CPU clock and reset control functions */ +static void tegra124_wait_cpu_in_reset(u32 cpu) +{ + unsigned int reg; + + do { + reg = readl(clk_base + CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); + cpu_relax(); + } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ +} + +static void tegra124_disable_cpu_clock(u32 cpu) +{ + /* flow controller would take care in the power sequence. */ +} + +static struct tegra_cpu_car_ops tegra124_cpu_car_ops = { + .wait_for_reset = tegra124_wait_cpu_in_reset, + .disable_clock = tegra124_disable_cpu_clock, +}; + static const struct of_device_id pmc_match[] __initconst = { { .compatible = "nvidia,tegra124-pmc" }, {}, @@ -1366,5 +1390,7 @@ static void __init tegra124_clock_init(struct device_node *np) tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra124_clock_apply_init_table; + + tegra_cpu_car_ops = &tegra124_cpu_car_ops; } CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init); -- cgit v1.2.3 From 61792e40ca008d60331bb55df5faaa8fe220ac24 Mon Sep 17 00:00:00 2001 From: Joseph Lo Date: Thu, 26 Sep 2013 17:46:23 +0800 Subject: clk: tegra124: add suspend/resume function for tegra_cpu_car_ops Adding suspend/resume function for tegra_cpu_car_ops. We only save and restore the setting of the clock of CoreSight. Other clocks still need to be taken care by clock driver. Cc: Mike Turquette Signed-off-by: Joseph Lo Acked-by: Stephen Warren --- drivers/clk/tegra/clk-tegra124.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 345192233871..8af9d3929016 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -28,6 +28,7 @@ #include "clk.h" #include "clk-id.h" +#define CLK_SOURCE_CSITE 0x1d4 #define CLK_SOURCE_EMC 0x19c #define CLK_SOURCE_XUSB_SS_SRC 0x610 @@ -115,6 +116,12 @@ /* Tegra CPU clock and reset control regs */ #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 +#ifdef CONFIG_PM_SLEEP +static struct cpu_clk_suspend_context { + u32 clk_csite_src; +} tegra124_cpu_clk_sctx; +#endif + static void __iomem *clk_base; static void __iomem *pmc_base; @@ -1302,9 +1309,29 @@ static void tegra124_disable_cpu_clock(u32 cpu) /* flow controller would take care in the power sequence. */ } +#ifdef CONFIG_PM_SLEEP +static void tegra124_cpu_clock_suspend(void) +{ + /* switch coresite to clk_m, save off original source */ + tegra124_cpu_clk_sctx.clk_csite_src = + readl(clk_base + CLK_SOURCE_CSITE); + writel(3 << 30, clk_base + CLK_SOURCE_CSITE); +} + +static void tegra124_cpu_clock_resume(void) +{ + writel(tegra124_cpu_clk_sctx.clk_csite_src, + clk_base + CLK_SOURCE_CSITE); +} +#endif + static struct tegra_cpu_car_ops tegra124_cpu_car_ops = { .wait_for_reset = tegra124_wait_cpu_in_reset, .disable_clock = tegra124_disable_cpu_clock, +#ifdef CONFIG_PM_SLEEP + .suspend = tegra124_cpu_clock_suspend, + .resume = tegra124_cpu_clock_resume, +#endif }; static const struct of_device_id pmc_match[] __initconst = { -- cgit v1.2.3 From 77f71730341e9072766eabc5bbd001aa286e7a23 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 29 Oct 2013 16:51:10 +0100 Subject: clk: tegra114: Initialize clocks needed for HDMI Add disp1 and disp2 clocks to the clock initialization table. These clocks are required for display and HDMI support. Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra114.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 0b8c9af5bff3..875859d9ab5f 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1294,6 +1294,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { {TEGRA114_CLK_HOST1X, TEGRA114_CLK_PLL_P, 136000000, 0}, {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, + {TEGRA114_CLK_DISP1, TEGRA114_CLK_PLL_P, 0, 0}, + {TEGRA114_CLK_DISP2, TEGRA114_CLK_PLL_P, 0, 0}, {TEGRA114_CLK_GR2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, {TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, -- cgit v1.2.3 From 43e36a9646ec7d0180d638c095cca36484cc6f82 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 29 Oct 2013 16:51:11 +0100 Subject: clk: tegra: Initialize secondary gr3d clock on Tegra30 There are two GPUs on Tegra30 and each of them uses a separate clock, so the secondary clock needs to be initialized in order for the gr3d module to work properly. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra30.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index f7ebf2bacdd9..153ae1acd2fa 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1368,6 +1368,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { {TEGRA30_CLK_TWD, TEGRA30_CLK_CLK_MAX, 0, 1}, {TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0}, {TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0}, + {TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0}, {TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry. */ }; -- cgit v1.2.3 From c04bf559264de4f986463c639fabef2028542924 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 29 Oct 2013 16:51:12 +0100 Subject: clk: tegra: Properly setup PWM clock on Tegra30 The clock for the PWM controller is slightly different from other peripheral clocks on Tegra30. The clock source mux field start at bit position 28 rather than 30. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra30.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 153ae1acd2fa..3afa09761bb3 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -102,6 +102,7 @@ #define AUDIO_SYNC_CLK_SPDIF 0x4b4 #define CLK_SOURCE_SPDIF_OUT 0x108 +#define CLK_SOURCE_PWM 0x110 #define CLK_SOURCE_D_AUDIO 0x3d0 #define CLK_SOURCE_DAM0 0x3d8 #define CLK_SOURCE_DAM1 0x3dc @@ -827,7 +828,6 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [tegra_clk_extern1] = { .dt_id = TEGRA30_CLK_EXTERN1, .present = true }, [tegra_clk_extern2] = { .dt_id = TEGRA30_CLK_EXTERN2, .present = true }, [tegra_clk_extern3] = { .dt_id = TEGRA30_CLK_EXTERN3, .present = true }, - [tegra_clk_pwm] = { .dt_id = TEGRA30_CLK_PWM, .present = true }, [tegra_clk_disp1] = { .dt_id = TEGRA30_CLK_DISP1, .present = true }, [tegra_clk_disp2] = { .dt_id = TEGRA30_CLK_DISP2, .present = true }, [tegra_clk_apbdma] = { .dt_id = TEGRA30_CLK_APBDMA, .present = true }, @@ -1111,6 +1111,7 @@ static const char *mux_pllpmdacd2_clkm[] = { "pll_p", "pll_m", "pll_d_out0", "pll_d2_out0", "clk_m" }; static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", "pll_d2_out0" }; +static const char *pwm_parents[] = { "pll_p", "pll_c", "clk_32k", "clk_m" }; static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX("spdif_out", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_SPDIF_OUT), @@ -1121,6 +1122,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_INT("3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, TEGRA_PERIPH_MANUAL_RESET, TEGRA30_CLK_GR3D2), TEGRA_INIT_DATA_INT("se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, 0, TEGRA30_CLK_SE), TEGRA_INIT_DATA_MUX8("hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA30_CLK_HDMI), + TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_PWM), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { -- cgit v1.2.3 From 5ab5d4048e6ed8811245a4ea45264456c180545e Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Thu, 21 Nov 2013 03:38:10 +0100 Subject: clk: tegra: add FUSE clock device This clock is needed to ensure the FUSE registers can be accessed without freezing the system. Signed-off-by: Alexandre Courbot --- drivers/clk/tegra/clk-tegra114.c | 1 + drivers/clk/tegra/clk-tegra124.c | 1 + drivers/clk/tegra/clk-tegra20.c | 1 + drivers/clk/tegra/clk-tegra30.c | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 875859d9ab5f..2a1b0b82462a 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -918,6 +918,7 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "sclk", .dt_id = TEGRA114_CLK_SCLK }, { .con_id = "hclk", .dt_id = TEGRA114_CLK_HCLK }, { .con_id = "pclk", .dt_id = TEGRA114_CLK_PCLK }, + { .con_id = "fuse", .dt_id = TEGRA114_CLK_FUSE }, { .dev_id = "rtc-tegra", .dt_id = TEGRA114_CLK_RTC }, { .dev_id = "timer", .dt_id = TEGRA114_CLK_TIMER }, }; diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 8af9d3929016..0ef4485e9b0a 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -1009,6 +1009,7 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK }, { .con_id = "hclk", .dt_id = TEGRA124_CLK_HCLK }, { .con_id = "pclk", .dt_id = TEGRA124_CLK_PCLK }, + { .con_id = "fuse", .dt_id = TEGRA124_CLK_FUSE }, { .dev_id = "rtc-tegra", .dt_id = TEGRA124_CLK_RTC }, { .dev_id = "timer", .dt_id = TEGRA124_CLK_TIMER }, }; diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index be5bdbab78a6..b3b7204acfe7 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -446,6 +446,7 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "sclk", .dt_id = TEGRA20_CLK_SCLK }, { .con_id = "hclk", .dt_id = TEGRA20_CLK_HCLK }, { .con_id = "pclk", .dt_id = TEGRA20_CLK_PCLK }, + { .con_id = "fuse", .dt_id = TEGRA20_CLK_FUSE }, { .con_id = "twd", .dt_id = TEGRA20_CLK_TWD }, { .con_id = "audio", .dt_id = TEGRA20_CLK_AUDIO }, { .con_id = "audio_2x", .dt_id = TEGRA20_CLK_AUDIO_2X }, diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 3afa09761bb3..dcb6843b3a89 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -650,7 +650,7 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE }, { .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI }, { .con_id = "pciex", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIEX }, - { .con_id = "fuse", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE }, + { .con_id = "fuse", .dt_id = TEGRA30_CLK_FUSE }, { .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN }, { .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF }, { .con_id = "hda2hdmi", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2HDMI }, -- cgit v1.2.3 From 39409aa4244f22eae3fa8f8db4b0cf9466b73c44 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 18 Nov 2013 16:11:36 +0100 Subject: clk: tegra: Initialize DSI low-power clocks The low-power DSI clocks are used during host-driven transactions on the DSI bus. Documentation recommends that they be children of PLLP and run at a frequency of at least 52 MHz. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra114.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 2a1b0b82462a..29b912582e3d 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1299,6 +1299,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { {TEGRA114_CLK_DISP2, TEGRA114_CLK_PLL_P, 0, 0}, {TEGRA114_CLK_GR2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, {TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, + {TEGRA114_CLK_DSIALP, TEGRA114_CLK_PLL_P, 68000000, 0}, + {TEGRA114_CLK_DSIBLP, TEGRA114_CLK_PLL_P, 68000000, 0}, /* This MUST be the last entry. */ {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, -- cgit v1.2.3 From 14883a75ec76b44759385fb12629f4a0f1aef4e3 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Wed, 20 Nov 2013 12:11:35 -0800 Subject: xen/gnttab: leave lazy MMU mode in the case of a m2p override failure Commit f62805f1 introduced a bug where lazy MMU mode isn't exited if a m2p_add/remove_override call fails. Acked-by: Stefano Stabellini Cc: Boris Ostrovsky Reviewed-by: David Vrabel Reviewed-by: Anthony Liguori Cc: xen-devel@lists.xenproject.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Matt Wilson Signed-off-by: Konrad Rzeszutek Wilk CC: stable@vger.kernel.org --- drivers/xen/grant-table.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 62ccf5424ba8..028387192b60 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -930,9 +930,10 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, ret = m2p_add_override(mfn, pages[i], kmap_ops ? &kmap_ops[i] : NULL); if (ret) - return ret; + goto out; } + out: if (lazy) arch_leave_lazy_mmu_mode(); @@ -969,9 +970,10 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, ret = m2p_remove_override(pages[i], kmap_ops ? &kmap_ops[i] : NULL); if (ret) - return ret; + goto out; } + out: if (lazy) arch_leave_lazy_mmu_mode(); -- cgit v1.2.3 From ae5fbae0ccd982dfca0ce363036ed92f5b13f150 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 22 Oct 2013 18:35:19 -0700 Subject: [SCSI] libsas: fix usage of ata_tf_to_fis Since commit 110dd8f19df5 "[SCSI] libsas: fix scr_read/write users and update the libata documentation" we have been passing pmp=1 and is_cmd=0 to ata_tf_to_fis(). Praveen reports that eSATA attached drives do not discover correctly. His investigation found that the BIOS was passing pmp=0 while Linux was passing pmp=1 and failing to discover the drives. Update libsas to follow the libata example of pulling the pmp setting from the ata_link and correct is_cmd to be 1 since all tf's submitted through ->qc_issue are commands. Presumably libsas lldds do not care about is_cmd as they have sideband mechanisms to perform link management. http://marc.info/?l=linux-scsi&m=138179681726990 [jejb: checkpatch fix] Signed-off-by: Dan Williams Reported-by: Praveen Murali Tested-by: Praveen Murali Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/libsas/sas_ata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 161c98efade9..d2895836f9fa 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -211,7 +211,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) qc->tf.nsect = 0; } - ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis); + ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *)&task->ata_task.fis); task->uldd_task = qc; if (ata_is_atapi(qc->tf.protocol)) { memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); -- cgit v1.2.3 From c50325f7bcb8a3ceaacb9dbc41180b1cbbae7b5e Mon Sep 17 00:00:00 2001 From: "Chew, Chiau Ee" Date: Fri, 29 Nov 2013 02:13:11 +0800 Subject: spi/pxa2xx: Restore private register bits. The Intel LPSS SPI private register bits have to be restored when system resume from S3 suspend. Signed-off-by: Chew, Chiau Ee Acked-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 7028180a020a..7765b1999537 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1293,6 +1293,9 @@ static int pxa2xx_spi_resume(struct device *dev) /* Enable the SSP clock */ clk_prepare_enable(ssp->clk); + /* Restore LPSS private register bits */ + lpss_ssp_setup(drv_data); + /* Start the queue running */ status = spi_master_resume(drv_data->master); if (status != 0) { -- cgit v1.2.3 From 8ba4b3b9cc3d95714b31467614205fc26b91fb7c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 27 Nov 2013 17:26:03 +0100 Subject: clk: tegra: Do not print errors for clk_round_rate() clk_round_rate() can be used by drivers to determine whether or not a frequency is supported by the clock. The current Tegra clock driver outputs an error message and a stacktrace when the requested rate isn't supported. That's fine for clk_set_rate(), but it's confusing when all the driver does is query whether or not a frequency is supported. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 689c468aca2f..8eb2755c71b3 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -435,9 +435,6 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || (1 << p_div) > divp_max(pll) || cfg->output_rate > pll->params->vco_max) { - pr_err("%s: Failed to set %s rate %lu\n", - __func__, __clk_get_name(hw->clk), rate); - WARN_ON(1); return -EINVAL; } @@ -584,6 +581,8 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, if (_get_table_rate(hw, &cfg, rate, parent_rate) && _calc_rate(hw, &cfg, rate, parent_rate)) { + pr_err("%s: Failed to set %s rate %lu\n", __func__, + __clk_get_name(hw->clk), rate); WARN_ON(1); return -EINVAL; } @@ -615,10 +614,8 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, return __clk_get_rate(hw->clk); if (_get_table_rate(hw, &cfg, rate, *prate) && - _calc_rate(hw, &cfg, rate, *prate)) { - WARN_ON(1); + _calc_rate(hw, &cfg, rate, *prate)) return -EINVAL; - } return cfg.output_rate; } -- cgit v1.2.3 From 62ce7cd62f534023224912dc9b909963f26a38da Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 29 Oct 2013 03:07:57 +0100 Subject: clk: tegra: fix __clk_lookup() return value checks In case of error, the function __clk_lookup() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test. Signed-off-by: Wei Yongjun Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-pll.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 8eb2755c71b3..2dd432266ef6 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1490,7 +1490,7 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, u32 val, val_iddq; parent = __clk_lookup(parent_name); - if (IS_ERR(parent)) { + if (!parent) { WARN(1, "parent clk %s of %s must be registered first\n", name, parent_name); return ERR_PTR(-EINVAL); @@ -1591,7 +1591,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); parent = __clk_lookup(parent_name); - if (IS_ERR(parent)) { + if (!parent) { WARN(1, "parent clk %s of %s must be registered first\n", name, parent_name); return ERR_PTR(-EINVAL); @@ -1632,7 +1632,7 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); parent = __clk_lookup(parent_name); - if (IS_ERR(parent)) { + if (!parent) { WARN(1, "parent clk %s of %s must be registered first\n", name, parent_name); return ERR_PTR(-EINVAL); @@ -1756,7 +1756,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); parent = __clk_lookup(parent_name); - if (IS_ERR(parent)) { + if (!parent) { WARN(1, "parent clk %s of %s must be registered first\n", name, parent_name); return ERR_PTR(-EINVAL); -- cgit v1.2.3 From 22e580d07f6529a395c129575127ea6d860aed3a Mon Sep 17 00:00:00 2001 From: Bockholdt Arne Date: Tue, 26 Nov 2013 07:13:57 +0000 Subject: intel_idle: Fixed C6 state on Avoton/Rangeley processors Corrected the MWAIT flag for C-State C6 on Intel Avoton/Rangeley processors. Signed-off-by: Arne Bockholdt Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- drivers/idle/intel_idle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index cbd4e9abc47e..92d1206482a6 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -329,7 +329,7 @@ static struct cpuidle_state atom_cstates[] __initdata = { { .enter = NULL } }; -static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = { +static struct cpuidle_state avn_cstates[] __initdata = { { .name = "C1-AVN", .desc = "MWAIT 0x00", @@ -340,7 +340,7 @@ static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = { { .name = "C6-AVN", .desc = "MWAIT 0x51", - .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 15, .target_residency = 45, .enter = &intel_idle }, -- cgit v1.2.3 From 5a87182aa21d6d5d306840feab9321818dd3e2a3 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 27 Nov 2013 09:09:42 +0530 Subject: cpufreq: suspend governors on system suspend/hibernate This patch adds cpufreq suspend/resume calls to dpm_{suspend|resume}_noirq() for handling suspend/resume of cpufreq governors. Lan Tianyu (Intel) & Jinhyuk Choi (Broadcom) found anr issue where tunables configuration for clusters/sockets with non-boot CPUs was getting lost after suspend/resume, as we were notifying governors with CPUFREQ_GOV_POLICY_EXIT on removal of the last cpu for that policy and so deallocating memory for tunables. This is fixed by this patch as we don't allow any operation on governors after device suspend and before device resume now. Reported-and-tested-by: Lan Tianyu Reported-by: Jinhyuk Choi Signed-off-by: Viresh Kumar [rjw: Changelog, minor cleanups] Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 3 +++ drivers/cpufreq/cpufreq.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/linux/cpufreq.h | 8 ++++++++ 3 files changed, 54 insertions(+) (limited to 'drivers') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 9f098a82cf04..10c3510d72a9 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "../base.h" #include "power.h" @@ -473,6 +474,7 @@ static void dpm_resume_noirq(pm_message_t state) dpm_show_time(starttime, state, "noirq"); resume_device_irqs(); cpuidle_resume(); + cpufreq_resume(); } /** @@ -885,6 +887,7 @@ static int dpm_suspend_noirq(pm_message_t state) ktime_t starttime = ktime_get(); int error = 0; + cpufreq_suspend(); cpuidle_pause(); suspend_device_irqs(); mutex_lock(&dpm_list_mtx); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 02d534da22dd..606224a8abc2 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,9 @@ static LIST_HEAD(cpufreq_policy_list); static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); #endif +/* Flag to suspend/resume CPUFreq governors */ +static bool cpufreq_suspended; + static inline bool has_target(void) { return cpufreq_driver->target_index || cpufreq_driver->target; @@ -1462,6 +1466,41 @@ static struct subsys_interface cpufreq_interface = { .remove_dev = cpufreq_remove_dev, }; +void cpufreq_suspend(void) +{ + struct cpufreq_policy *policy; + + if (!has_target()) + return; + + pr_debug("%s: Suspending Governors\n", __func__); + + list_for_each_entry(policy, &cpufreq_policy_list, policy_list) + if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) + pr_err("%s: Failed to stop governor for policy: %p\n", + __func__, policy); + + cpufreq_suspended = true; +} + +void cpufreq_resume(void) +{ + struct cpufreq_policy *policy; + + if (!has_target()) + return; + + pr_debug("%s: Resuming Governors\n", __func__); + + cpufreq_suspended = false; + + list_for_each_entry(policy, &cpufreq_policy_list, policy_list) + if (__cpufreq_governor(policy, CPUFREQ_GOV_START) + || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS)) + pr_err("%s: Failed to start governor for policy: %p\n", + __func__, policy); +} + /** * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. * @@ -1764,6 +1803,10 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, struct cpufreq_governor *gov = NULL; #endif + /* Don't start any governor operations if we are entering suspend */ + if (cpufreq_suspended) + return 0; + if (policy->governor->max_transition_latency && policy->cpuinfo.transition_latency > policy->governor->max_transition_latency) { diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 5bd6ab9b0c27..91716658e9a1 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -272,6 +272,14 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) policy->cpuinfo.max_freq); } +#ifdef CONFIG_CPU_FREQ +void cpufreq_suspend(void); +void cpufreq_resume(void); +#else +static inline void cpufreq_suspend(void) {} +static inline void cpufreq_resume(void) {} +#endif + /********************************************************************* * CPUFREQ NOTIFIER INTERFACE * *********************************************************************/ -- cgit v1.2.3 From 935e99a3afda0a58c2eada0ff7c613d3844d738c Mon Sep 17 00:00:00 2001 From: Horia Geanta Date: Tue, 19 Nov 2013 14:57:49 +0200 Subject: crypto: talitos - corrrectly handle zero-length assoc data talitos does not handle well zero-length assoc data. From dmesg: talitos ffe30000.crypto: master data transfer error talitos ffe30000.crypto: gather return/length error Check whether assoc data is provided by inspecting assoclen, not assoc pointer. This is needed in order to pass testmgr tests. Signed-off-by: Horia Geanta Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 905de4427e7c..81ab42cd14b2 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -790,7 +790,7 @@ static void ipsec_esp_unmap(struct device *dev, if (edesc->assoc_chained) talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE); - else + else if (areq->assoclen) /* assoc_nents counts also for IV in non-contiguous cases */ dma_unmap_sg(dev, areq->assoc, edesc->assoc_nents ? edesc->assoc_nents - 1 : 1, @@ -973,7 +973,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, dma_sync_single_for_device(dev, edesc->dma_link_tbl, edesc->dma_len, DMA_BIDIRECTIONAL); } else { - to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->assoc)); + if (areq->assoclen) + to_talitos_ptr(&desc->ptr[1], + sg_dma_address(areq->assoc)); + else + to_talitos_ptr(&desc->ptr[1], edesc->iv_dma); desc->ptr[1].j_extent = 0; } @@ -1122,10 +1126,10 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, return ERR_PTR(-EINVAL); } - if (iv) + if (ivsize) iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE); - if (assoc) { + if (assoclen) { /* * Currently it is assumed that iv is provided whenever assoc * is. @@ -1173,9 +1177,16 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, edesc = kmalloc(alloc_len, GFP_DMA | flags); if (!edesc) { - talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE); + if (assoc_chained) + talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE); + else if (assoclen) + dma_unmap_sg(dev, assoc, + assoc_nents ? assoc_nents - 1 : 1, + DMA_TO_DEVICE); + if (iv_dma) dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE); + dev_err(dev, "could not allocate edescriptor\n"); return ERR_PTR(-ENOMEM); } -- cgit v1.2.3 From bbf9c8934ba2bfd5fd809562f945deaf5a565898 Mon Sep 17 00:00:00 2001 From: Horia Geanta Date: Thu, 28 Nov 2013 15:11:16 +0200 Subject: crypto: caam - fix aead sglen for case 'dst != src' For aead case when source and destination buffers are different, there is an incorrect assumption that the source length includes the ICV length. Fix this, since it leads to an oops when using sg_count() to find the number of nents in the scatterlist: Unable to handle kernel paging request for data at address 0x00000004 Faulting instruction address: 0xf91f7634 Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=8 P4080 DS Modules linked in: caamalg(+) caam_jr caam CPU: 1 PID: 1053 Comm: cryptomgr_test Not tainted 3.11.0 #16 task: eeb24ab0 ti: eeafa000 task.ti: eeafa000 NIP: f91f7634 LR: f91f7f24 CTR: f91f7ef0 REGS: eeafbbc0 TRAP: 0300 Not tainted (3.11.0) MSR: 00029002 CR: 44044044 XER: 00000000 DEAR: 00000004, ESR: 00000000 GPR00: f91f7f24 eeafbc70 eeb24ab0 00000002 ee8e0900 ee8e0800 00000024 c45c4462 GPR08: 00000010 00000000 00000014 0c0e4000 24044044 00000000 00000000 c0691590 GPR16: eeab0000 eeb23000 00000000 00000000 00000000 00000001 00000001 eeafbcc8 GPR24: 000000d1 00000010 ee2d5000 ee49ea10 ee49ea10 ee46f640 ee46f640 c0691590 NIP [f91f7634] aead_edesc_alloc.constprop.14+0x144/0x780 [caamalg] LR [f91f7f24] aead_encrypt+0x34/0x288 [caamalg] Call Trace: [eeafbc70] [a1004000] 0xa1004000 (unreliable) [eeafbcc0] [f91f7f24] aead_encrypt+0x34/0x288 [caamalg] [eeafbcf0] [c020d77c] __test_aead+0x3ec/0xe20 [eeafbe20] [c020f35c] test_aead+0x6c/0xe0 [eeafbe40] [c020f420] alg_test_aead+0x50/0xd0 [eeafbe60] [c020e5e4] alg_test+0x114/0x2e0 [eeafbee0] [c020bd1c] cryptomgr_test+0x4c/0x60 [eeafbef0] [c0047058] kthread+0xa8/0xb0 [eeafbf40] [c000eb0c] ret_from_kernel_thread+0x5c/0x64 Instruction dump: 69084321 7d080034 5508d97e 69080001 0f080000 81290024 552807fe 0f080000 3a600001 5529003a 2f8a0000 40dd0028 <80e90004> 3ab50001 8109000c 70e30002 ---[ end trace b3c3e23925c7484e ]--- While here, add a tcrypt mode for making it easy to test authenc (needed for triggering case above). Signed-off-by: Horia Geanta Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 4 ++++ drivers/crypto/caam/caamalg.c | 51 ++++++++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 1ab8258fcf56..001f07cdb828 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1242,6 +1242,10 @@ static int do_test(int m) ret += tcrypt_test("cmac(des3_ede)"); break; + case 155: + ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))"); + break; + case 200: test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, speed_template_16_24_32); diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 4f44b71b9e24..4cf5dec826e1 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -818,7 +818,7 @@ static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err, ivsize, 1); print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->dst), - req->cryptlen, 1); + req->cryptlen - ctx->authsize, 1); #endif if (err) { @@ -972,12 +972,9 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, (edesc->src_nents ? : 1); in_options = LDST_SGF; } - if (encrypt) - append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + - req->cryptlen - authsize, in_options); - else - append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + - req->cryptlen, in_options); + + append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen, + in_options); if (likely(req->src == req->dst)) { if (all_contig) { @@ -998,7 +995,8 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, } } if (encrypt) - append_seq_out_ptr(desc, dst_dma, req->cryptlen, out_options); + append_seq_out_ptr(desc, dst_dma, req->cryptlen + authsize, + out_options); else append_seq_out_ptr(desc, dst_dma, req->cryptlen - authsize, out_options); @@ -1048,8 +1046,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents; in_options = LDST_SGF; } - append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + - req->cryptlen - authsize, in_options); + append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen, + in_options); if (contig & GIV_DST_CONTIG) { dst_dma = edesc->iv_dma; @@ -1066,7 +1064,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, } } - append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen, out_options); + append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen + authsize, + out_options); } /* @@ -1130,7 +1129,8 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr, * allocate and map the aead extended descriptor */ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, - int desc_bytes, bool *all_contig_ptr) + int desc_bytes, bool *all_contig_ptr, + bool encrypt) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct caam_ctx *ctx = crypto_aead_ctx(aead); @@ -1145,12 +1145,22 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, bool assoc_chained = false, src_chained = false, dst_chained = false; int ivsize = crypto_aead_ivsize(aead); int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; + unsigned int authsize = ctx->authsize; assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); - src_nents = sg_count(req->src, req->cryptlen, &src_chained); - if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); + if (unlikely(req->dst != req->src)) { + src_nents = sg_count(req->src, req->cryptlen, &src_chained); + dst_nents = sg_count(req->dst, + req->cryptlen + + (encrypt ? authsize : (-authsize)), + &dst_chained); + } else { + src_nents = sg_count(req->src, + req->cryptlen + + (encrypt ? authsize : 0), + &src_chained); + } sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, DMA_TO_DEVICE, assoc_chained); @@ -1234,11 +1244,9 @@ static int aead_encrypt(struct aead_request *req) u32 *desc; int ret = 0; - req->cryptlen += ctx->authsize; - /* allocate extended descriptor */ edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN * - CAAM_CMD_SZ, &all_contig); + CAAM_CMD_SZ, &all_contig, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1275,7 +1283,7 @@ static int aead_decrypt(struct aead_request *req) /* allocate extended descriptor */ edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN * - CAAM_CMD_SZ, &all_contig); + CAAM_CMD_SZ, &all_contig, false); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1332,7 +1340,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request src_nents = sg_count(req->src, req->cryptlen, &src_chained); if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); + dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize, + &dst_chained); sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, DMA_TO_DEVICE, assoc_chained); @@ -1426,8 +1435,6 @@ static int aead_givencrypt(struct aead_givcrypt_request *areq) u32 *desc; int ret = 0; - req->cryptlen += ctx->authsize; - /* allocate extended descriptor */ edesc = aead_giv_edesc_alloc(areq, DESC_JOB_IO_LEN * CAAM_CMD_SZ, &contig); -- cgit v1.2.3 From 62293a37de0138b2e9c965f0a3b803c0f40a6581 Mon Sep 17 00:00:00 2001 From: Horia Geanta Date: Thu, 28 Nov 2013 15:11:17 +0200 Subject: crypto: talitos - fix aead sglen for case 'dst != src' For aead case when source and destination buffers are different, there is an incorrect assumption that the source length includes the ICV length. Fix this, since it leads to an oops when using sg_count() to find the number of nents in the scatterlist: Unable to handle kernel paging request for data at address 0x00000004 Faulting instruction address: 0xf2265a28 Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=8 P2020 RDB Modules linked in: talitos(+) CPU: 1 PID: 2187 Comm: cryptomgr_test Not tainted 3.11.0 #12 task: c4e72e20 ti: ef634000 task.ti: ef634000 NIP: f2265a28 LR: f2266ad8 CTR: c000c900 REGS: ef635bb0 TRAP: 0300 Not tainted (3.11.0) MSR: 00029000 CR: 42042084 XER: 00000000 DEAR: 00000004, ESR: 00000000 GPR00: f2266e10 ef635c60 c4e72e20 00000001 00000014 ef635c69 00000001 c11f3082 GPR08: 00000010 00000000 00000002 2f635d58 22044084 00000000 00000000 c0755c80 GPR16: c4bf1000 ef784000 00000000 00000000 00000020 00000014 00000010 ef2f6100 GPR24: ef2f6200 00000024 ef143210 ef2f6000 00000000 ef635d58 00000000 2f635d58 NIP [f2265a28] sg_count+0x1c/0xb4 [talitos] LR [f2266ad8] talitos_edesc_alloc+0x12c/0x410 [talitos] Call Trace: [ef635c60] [c0552068] schedule_timeout+0x148/0x1ac (unreliable) [ef635cc0] [f2266e10] aead_edesc_alloc+0x54/0x64 [talitos] [ef635ce0] [f22680f0] aead_encrypt+0x24/0x70 [talitos] [ef635cf0] [c024b948] __test_aead+0x494/0xf68 [ef635e20] [c024d54c] test_aead+0x64/0xcc [ef635e40] [c024d604] alg_test_aead+0x50/0xc4 [ef635e60] [c024c838] alg_test+0x10c/0x2e4 [ef635ee0] [c0249d1c] cryptomgr_test+0x4c/0x54 [ef635ef0] [c005d598] kthread+0xa8/0xac [ef635f40] [c000e3bc] ret_from_kernel_thread+0x5c/0x64 Instruction dump: 81230024 552807fe 0f080000 5523003a 4bffff24 39000000 2c040000 99050000 408100a0 7c691b78 38c00001 38600000 <80e90004> 38630001 8109000c 70ea0002 ---[ end trace 4498123cd8478591 ]--- Signed-off-by: Horia Geanta Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 81ab42cd14b2..b44f4ddc565c 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1112,7 +1112,8 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, unsigned int authsize, unsigned int ivsize, int icv_stashing, - u32 cryptoflags) + u32 cryptoflags, + bool encrypt) { struct talitos_edesc *edesc; int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len; @@ -1145,19 +1146,17 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, assoc_nents = assoc_nents ? assoc_nents + 1 : 2; } - src_nents = sg_count(src, cryptlen + authsize, &src_chained); - src_nents = (src_nents == 1) ? 0 : src_nents; - - if (!dst) { - dst_nents = 0; - } else { - if (dst == src) { - dst_nents = src_nents; - } else { - dst_nents = sg_count(dst, cryptlen + authsize, - &dst_chained); - dst_nents = (dst_nents == 1) ? 0 : dst_nents; - } + if (!dst || dst == src) { + src_nents = sg_count(src, cryptlen + authsize, &src_chained); + src_nents = (src_nents == 1) ? 0 : src_nents; + dst_nents = dst ? src_nents : 0; + } else { /* dst && dst != src*/ + src_nents = sg_count(src, cryptlen + (encrypt ? 0 : authsize), + &src_chained); + src_nents = (src_nents == 1) ? 0 : src_nents; + dst_nents = sg_count(dst, cryptlen + (encrypt ? authsize : 0), + &dst_chained); + dst_nents = (dst_nents == 1) ? 0 : dst_nents; } /* @@ -1208,7 +1207,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, } static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv, - int icv_stashing) + int icv_stashing, bool encrypt) { struct crypto_aead *authenc = crypto_aead_reqtfm(areq); struct talitos_ctx *ctx = crypto_aead_ctx(authenc); @@ -1217,7 +1216,7 @@ static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv, return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst, iv, areq->assoclen, areq->cryptlen, ctx->authsize, ivsize, icv_stashing, - areq->base.flags); + areq->base.flags, encrypt); } static int aead_encrypt(struct aead_request *req) @@ -1227,7 +1226,7 @@ static int aead_encrypt(struct aead_request *req) struct talitos_edesc *edesc; /* allocate extended descriptor */ - edesc = aead_edesc_alloc(req, req->iv, 0); + edesc = aead_edesc_alloc(req, req->iv, 0, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1250,7 +1249,7 @@ static int aead_decrypt(struct aead_request *req) req->cryptlen -= authsize; /* allocate extended descriptor */ - edesc = aead_edesc_alloc(req, req->iv, 1); + edesc = aead_edesc_alloc(req, req->iv, 1, false); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1296,7 +1295,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req) struct talitos_edesc *edesc; /* allocate extended descriptor */ - edesc = aead_edesc_alloc(areq, req->giv, 0); + edesc = aead_edesc_alloc(areq, req->giv, 0, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1452,7 +1451,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc, } static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request * - areq) + areq, bool encrypt) { struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); @@ -1460,7 +1459,7 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request * return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst, areq->info, 0, areq->nbytes, 0, ivsize, 0, - areq->base.flags); + areq->base.flags, encrypt); } static int ablkcipher_encrypt(struct ablkcipher_request *areq) @@ -1470,7 +1469,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq) struct talitos_edesc *edesc; /* allocate extended descriptor */ - edesc = ablkcipher_edesc_alloc(areq); + edesc = ablkcipher_edesc_alloc(areq, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1487,7 +1486,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq) struct talitos_edesc *edesc; /* allocate extended descriptor */ - edesc = ablkcipher_edesc_alloc(areq); + edesc = ablkcipher_edesc_alloc(areq, false); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -1639,7 +1638,7 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq, struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0, - nbytes, 0, 0, 0, areq->base.flags); + nbytes, 0, 0, 0, areq->base.flags, false); } static int ahash_init(struct ahash_request *areq) -- cgit v1.2.3 From 08332dff8adebb74171e98e008d6c20de6658c42 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 28 Nov 2013 14:21:40 +0000 Subject: irqchip: Gic: fix boot for chained gics As of c0114709ed: "irqchip: gic: Perform the gic_secondary_init() call via CPU notifier", booting on a platform with chained gics (e.g. Realview EB ARM11MPCore) will result in the gic_cpu_notifier being registered twice, corrupting the cpu notifier list and rendering the platform unbootable. This patch ensures that we only register the notifier for the first gic, allowing platforms with chained gics to boot. At the same time we limit the pointlessly duplicated calls to set_smp_cross_call and set_handle_irq to the first gic registered. Signed-off-by: Mark Rutland Reviewed-by: Catalin Marinas Cc: linux-arm-kernel@lists.infradead.org Cc: marc.zyngier@arm.com Cc: rob.herring@calxeda.com Cc: olof@lixom.net Link: http://lkml.kernel.org/r/1385648500-29048-1-git-send-email-mark.rutland@arm.com Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-gic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index d0e948084eaf..e219a5bf0cac 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -814,12 +814,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, if (WARN_ON(!gic->domain)) return; + if (gic_nr == 0) { #ifdef CONFIG_SMP - set_smp_cross_call(gic_raise_softirq); - register_cpu_notifier(&gic_cpu_notifier); + set_smp_cross_call(gic_raise_softirq); + register_cpu_notifier(&gic_cpu_notifier); #endif - - set_handle_irq(gic_handle_irq); + set_handle_irq(gic_handle_irq); + } gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); -- cgit v1.2.3 From e0d59733f6b1796b8d6692642c87d7dd862c3e3a Mon Sep 17 00:00:00 2001 From: Seiji Aguchi Date: Wed, 30 Oct 2013 15:27:26 -0400 Subject: efivars, efi-pstore: Hold off deletion of sysfs entry until the scan is completed Currently, when mounting pstore file system, a read callback of efi_pstore driver runs mutiple times as below. - In the first read callback, scan efivar_sysfs_list from head and pass a kmsg buffer of a entry to an upper pstore layer. - In the second read callback, rescan efivar_sysfs_list from the entry and pass another kmsg buffer to it. - Repeat the scan and pass until the end of efivar_sysfs_list. In this process, an entry is read across the multiple read function calls. To avoid race between the read and erasion, the whole process above is protected by a spinlock, holding in open() and releasing in close(). At the same time, kmemdup() is called to pass the buffer to pstore filesystem during it. And then, it causes a following lockdep warning. To make the dynamic memory allocation runnable without taking spinlock, holding off a deletion of sysfs entry if it happens while scanning it via efi_pstore, and deleting it after the scan is completed. To implement it, this patch introduces two flags, scanning and deleting, to efivar_entry. On the code basis, it seems that all the scanning and deleting logic is not needed because __efivars->lock are not dropped when reading from the EFI variable store. But, the scanning and deleting logic is still needed because an efi-pstore and a pstore filesystem works as follows. In case an entry(A) is found, the pointer is saved to psi->data. And efi_pstore_read() passes the entry(A) to a pstore filesystem by releasing __efivars->lock. And then, the pstore filesystem calls efi_pstore_read() again and the same entry(A), which is saved to psi->data, is used for resuming to scan a sysfs-list. So, to protect the entry(A), the logic is needed. [ 1.143710] ------------[ cut here ]------------ [ 1.144058] WARNING: CPU: 1 PID: 1 at kernel/lockdep.c:2740 lockdep_trace_alloc+0x104/0x110() [ 1.144058] DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags)) [ 1.144058] Modules linked in: [ 1.144058] CPU: 1 PID: 1 Comm: systemd Not tainted 3.11.0-rc5 #2 [ 1.144058] 0000000000000009 ffff8800797e9ae0 ffffffff816614a5 ffff8800797e9b28 [ 1.144058] ffff8800797e9b18 ffffffff8105510d 0000000000000080 0000000000000046 [ 1.144058] 00000000000000d0 00000000000003af ffffffff81ccd0c0 ffff8800797e9b78 [ 1.144058] Call Trace: [ 1.144058] [] dump_stack+0x54/0x74 [ 1.144058] [] warn_slowpath_common+0x7d/0xa0 [ 1.144058] [] warn_slowpath_fmt+0x4c/0x50 [ 1.144058] [] ? vsscanf+0x57f/0x7b0 [ 1.144058] [] lockdep_trace_alloc+0x104/0x110 [ 1.144058] [] __kmalloc_track_caller+0x50/0x280 [ 1.144058] [] ? efi_pstore_read_func.part.1+0x12b/0x170 [ 1.144058] [] kmemdup+0x20/0x50 [ 1.144058] [] efi_pstore_read_func.part.1+0x12b/0x170 [ 1.144058] [] ? efi_pstore_read_func.part.1+0x170/0x170 [ 1.144058] [] efi_pstore_read_func+0xb4/0xe0 [ 1.144058] [] __efivar_entry_iter+0xfb/0x120 [ 1.144058] [] efi_pstore_read+0x3f/0x50 [ 1.144058] [] pstore_get_records+0x9a/0x150 [ 1.158207] [] ? selinux_d_instantiate+0x1c/0x20 [ 1.158207] [] ? parse_options+0x80/0x80 [ 1.158207] [] pstore_fill_super+0xa5/0xc0 [ 1.158207] [] mount_single+0xa2/0xd0 [ 1.158207] [] pstore_mount+0x18/0x20 [ 1.158207] [] mount_fs+0x39/0x1b0 [ 1.158207] [] ? __alloc_percpu+0x10/0x20 [ 1.158207] [] vfs_kern_mount+0x63/0xf0 [ 1.158207] [] do_mount+0x23e/0xa20 [ 1.158207] [] ? strndup_user+0x4b/0xf0 [ 1.158207] [] SyS_mount+0x83/0xc0 [ 1.158207] [] system_call_fastpath+0x16/0x1b [ 1.158207] ---[ end trace 61981bc62de9f6f4 ]--- Signed-off-by: Seiji Aguchi Tested-by: Madper Xie Cc: stable@kernel.org Signed-off-by: Matt Fleming --- drivers/firmware/efi/efi-pstore.c | 143 +++++++++++++++++++++++++++++++++++--- drivers/firmware/efi/efivars.c | 12 ++-- drivers/firmware/efi/vars.c | 12 +++- include/linux/efi.h | 4 ++ 4 files changed, 155 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index 5002d50e3781..6ce31e93da55 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c @@ -18,14 +18,12 @@ module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644); static int efi_pstore_open(struct pstore_info *psi) { - efivar_entry_iter_begin(); psi->data = NULL; return 0; } static int efi_pstore_close(struct pstore_info *psi) { - efivar_entry_iter_end(); psi->data = NULL; return 0; } @@ -91,19 +89,125 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data) __efivar_entry_get(entry, &entry->var.Attributes, &entry->var.DataSize, entry->var.Data); size = entry->var.DataSize; + memcpy(*cb_data->buf, entry->var.Data, + (size_t)min_t(unsigned long, EFIVARS_DATA_SIZE_MAX, size)); - *cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL); - if (*cb_data->buf == NULL) - return -ENOMEM; return size; } +/** + * efi_pstore_scan_sysfs_enter + * @entry: scanning entry + * @next: next entry + * @head: list head + */ +static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos, + struct efivar_entry *next, + struct list_head *head) +{ + pos->scanning = true; + if (&next->list != head) + next->scanning = true; +} + +/** + * __efi_pstore_scan_sysfs_exit + * @entry: deleting entry + * @turn_off_scanning: Check if a scanning flag should be turned off + */ +static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry, + bool turn_off_scanning) +{ + if (entry->deleting) { + list_del(&entry->list); + efivar_entry_iter_end(); + efivar_unregister(entry); + efivar_entry_iter_begin(); + } else if (turn_off_scanning) + entry->scanning = false; +} + +/** + * efi_pstore_scan_sysfs_exit + * @pos: scanning entry + * @next: next entry + * @head: list head + * @stop: a flag checking if scanning will stop + */ +static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos, + struct efivar_entry *next, + struct list_head *head, bool stop) +{ + __efi_pstore_scan_sysfs_exit(pos, true); + if (stop) + __efi_pstore_scan_sysfs_exit(next, &next->list != head); +} + +/** + * efi_pstore_sysfs_entry_iter + * + * @data: function-specific data to pass to callback + * @pos: entry to begin iterating from + * + * You MUST call efivar_enter_iter_begin() before this function, and + * efivar_entry_iter_end() afterwards. + * + * It is possible to begin iteration from an arbitrary entry within + * the list by passing @pos. @pos is updated on return to point to + * the next entry of the last one passed to efi_pstore_read_func(). + * To begin iterating from the beginning of the list @pos must be %NULL. + */ +static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos) +{ + struct efivar_entry *entry, *n; + struct list_head *head = &efivar_sysfs_list; + int size = 0; + + if (!*pos) { + list_for_each_entry_safe(entry, n, head, list) { + efi_pstore_scan_sysfs_enter(entry, n, head); + + size = efi_pstore_read_func(entry, data); + efi_pstore_scan_sysfs_exit(entry, n, head, size < 0); + if (size) + break; + } + *pos = n; + return size; + } + + list_for_each_entry_safe_from((*pos), n, head, list) { + efi_pstore_scan_sysfs_enter((*pos), n, head); + + size = efi_pstore_read_func((*pos), data); + efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0); + if (size) + break; + } + *pos = n; + return size; +} + +/** + * efi_pstore_read + * + * This function returns a size of NVRAM entry logged via efi_pstore_write(). + * The meaning and behavior of efi_pstore/pstore are as below. + * + * size > 0: Got data of an entry logged via efi_pstore_write() successfully, + * and pstore filesystem will continue reading subsequent entries. + * size == 0: Entry was not logged via efi_pstore_write(), + * and efi_pstore driver will continue reading subsequent entries. + * size < 0: Failed to get data of entry logging via efi_pstore_write(), + * and pstore will stop reading entry. + */ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count, struct timespec *timespec, char **buf, bool *compressed, struct pstore_info *psi) { struct pstore_read_data data; + ssize_t size; data.id = id; data.type = type; @@ -112,8 +216,17 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, data.compressed = compressed; data.buf = buf; - return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data, - (struct efivar_entry **)&psi->data); + *data.buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL); + if (!*data.buf) + return -ENOMEM; + + efivar_entry_iter_begin(); + size = efi_pstore_sysfs_entry_iter(&data, + (struct efivar_entry **)&psi->data); + efivar_entry_iter_end(); + if (size <= 0) + kfree(*data.buf); + return size; } static int efi_pstore_write(enum pstore_type_id type, @@ -184,9 +297,17 @@ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data) return 0; } + if (entry->scanning) { + /* + * Skip deletion because this entry will be deleted + * after scanning is completed. + */ + entry->deleting = true; + } else + list_del(&entry->list); + /* found */ __efivar_entry_delete(entry); - list_del(&entry->list); return 1; } @@ -214,10 +335,12 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, efivar_entry_iter_begin(); found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry); - efivar_entry_iter_end(); - if (found) + if (found && !entry->scanning) { + efivar_entry_iter_end(); efivar_unregister(entry); + } else + efivar_entry_iter_end(); return 0; } diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index 933eb027d527..3dc248239197 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -383,12 +383,16 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, else if (__efivar_entry_delete(entry)) err = -EIO; - efivar_entry_iter_end(); - - if (err) + if (err) { + efivar_entry_iter_end(); return err; + } - efivar_unregister(entry); + if (!entry->scanning) { + efivar_entry_iter_end(); + efivar_unregister(entry); + } else + efivar_entry_iter_end(); /* It's dead Jim.... */ return count; diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 391c67b182d9..b22659cccca4 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -683,8 +683,16 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid, if (!found) return NULL; - if (remove) - list_del(&entry->list); + if (remove) { + if (entry->scanning) { + /* + * The entry will be deleted + * after scanning is completed. + */ + entry->deleting = true; + } else + list_del(&entry->list); + } return entry; } diff --git a/include/linux/efi.h b/include/linux/efi.h index bc5687d0f315..11ce6784a196 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -801,6 +801,8 @@ struct efivar_entry { struct efi_variable var; struct list_head list; struct kobject kobj; + bool scanning; + bool deleting; }; @@ -866,6 +868,8 @@ void efivar_run_worker(void); #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) int efivars_sysfs_init(void); +#define EFIVARS_DATA_SIZE_MAX 1024 + #endif /* CONFIG_EFI_VARS */ #endif /* _LINUX_EFI_H */ -- cgit v1.2.3 From fe9d04afe9bee0ec37a9724937443b2c0e39ce4b Mon Sep 17 00:00:00 2001 From: dingtianhong Date: Fri, 22 Nov 2013 22:28:43 +0800 Subject: bonding: disable arp and enable mii monitoring when bond change to no uses arp mode Because the ARP monitoring is not support for 802.3ad, but I still could change the mode to 802.3ad from ab mode while ARP monitoring is running, it is incorrect. So add a check for 802.3ad in bonding_store_mode to fix the problem, and make a new macro BOND_NO_USES_ARP() to simplify the code. v2: according to the Dan Williams's suggestion, bond mode is the most important bond option, it should override any of the other sub-options. So when the mode is changed, the conficting values should be cleared or reset, otherwise the user has to duplicate more operations to modify the logic. I disable the arp and enable mii monitoring when the bond mode is changed to AB, TB and 8023AD if the arp interval is true. v3: according to the Nik's suggestion, the default value of miimon should need a name, there is several place to use it, and the bond_store_arp_interval() could use micro BOND_NO_USES_ARP to make the code more simpify. Suggested-by: Dan Williams Suggested-by: Nikolay Aleksandrov Signed-off-by: Ding Tianhong Reviewed-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++-- drivers/net/bonding/bond_options.c | 13 +++++++++---- drivers/net/bonding/bond_sysfs.c | 4 +--- drivers/net/bonding/bonding.h | 7 +++++++ 4 files changed, 19 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4dd5ee2a34cc..36eab0c4fb33 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4110,7 +4110,7 @@ static int bond_check_params(struct bond_params *params) if (!miimon) { pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n"); pr_warning("Forcing miimon to 100msec\n"); - miimon = 100; + miimon = BOND_DEFAULT_MIIMON; } } @@ -4147,7 +4147,7 @@ static int bond_check_params(struct bond_params *params) if (!miimon) { pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing\n"); pr_warning("Forcing miimon to 100msec\n"); - miimon = 100; + miimon = BOND_DEFAULT_MIIMON; } } diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 9a5223c7b4d1..ea6f640782b7 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -45,10 +45,15 @@ int bond_option_mode_set(struct bonding *bond, int mode) return -EPERM; } - if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) { - pr_err("%s: %s mode is incompatible with arp monitoring.\n", - bond->dev->name, bond_mode_tbl[mode].modename); - return -EINVAL; + if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) { + pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n", + bond->dev->name, bond_mode_tbl[mode].modename); + /* disable arp monitoring */ + bond->params.arp_interval = 0; + /* set miimon to default value */ + bond->params.miimon = BOND_DEFAULT_MIIMON; + pr_info("%s: Setting MII monitoring interval to %d.\n", + bond->dev->name, bond->params.miimon); } /* don't cache arp_validate between modes */ diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 0ec2a7e8c8a9..abf5e106edc5 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -523,9 +523,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, ret = -EINVAL; goto out; } - if (bond->params.mode == BOND_MODE_ALB || - bond->params.mode == BOND_MODE_TLB || - bond->params.mode == BOND_MODE_8023AD) { + if (BOND_NO_USES_ARP(bond->params.mode)) { pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n", bond->dev->name, bond->dev->name); ret = -EINVAL; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index ca31286aa028..a9f4f9f4d8ce 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -35,6 +35,8 @@ #define BOND_MAX_ARP_TARGETS 16 +#define BOND_DEFAULT_MIIMON 100 + #define IS_UP(dev) \ ((((dev)->flags & IFF_UP) == IFF_UP) && \ netif_running(dev) && \ @@ -55,6 +57,11 @@ ((mode) == BOND_MODE_TLB) || \ ((mode) == BOND_MODE_ALB)) +#define BOND_NO_USES_ARP(mode) \ + (((mode) == BOND_MODE_8023AD) || \ + ((mode) == BOND_MODE_TLB) || \ + ((mode) == BOND_MODE_ALB)) + #define TX_QUEUE_OVERRIDE(mode) \ (((mode) == BOND_MODE_ACTIVEBACKUP) || \ ((mode) == BOND_MODE_ROUNDROBIN)) -- cgit v1.2.3 From a2f4dfba9e736ebe339d560cb92678280b1eb5db Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 22 Nov 2013 22:07:57 -0800 Subject: tg3: Convert to use hwmon_device_register_with_groups Use new hwmon API to simplify code, provide missing mandatory 'name' sysfs attribute, and attach hwmon attributes to hwmon device instead of pci device. Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare Acked-by: Nithin Nayak Sujir Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a9e068423ba0..369b736dde05 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -10629,10 +10629,8 @@ static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir) static ssize_t tg3_show_temp(struct device *dev, struct device_attribute *devattr, char *buf) { - struct pci_dev *pdev = to_pci_dev(dev); - struct net_device *netdev = pci_get_drvdata(pdev); - struct tg3 *tp = netdev_priv(netdev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct tg3 *tp = dev_get_drvdata(dev); u32 temperature; spin_lock_bh(&tp->lock); @@ -10650,29 +10648,25 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, tg3_show_temp, NULL, static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL, TG3_TEMP_MAX_OFFSET); -static struct attribute *tg3_attributes[] = { +static struct attribute *tg3_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, NULL }; - -static const struct attribute_group tg3_group = { - .attrs = tg3_attributes, -}; +ATTRIBUTE_GROUPS(tg3); static void tg3_hwmon_close(struct tg3 *tp) { if (tp->hwmon_dev) { hwmon_device_unregister(tp->hwmon_dev); tp->hwmon_dev = NULL; - sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group); } } static void tg3_hwmon_open(struct tg3 *tp) { - int i, err; + int i; u32 size = 0; struct pci_dev *pdev = tp->pdev; struct tg3_ocir ocirs[TG3_SD_NUM_RECS]; @@ -10690,18 +10684,11 @@ static void tg3_hwmon_open(struct tg3 *tp) if (!size) return; - /* Register hwmon sysfs hooks */ - err = sysfs_create_group(&pdev->dev.kobj, &tg3_group); - if (err) { - dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n"); - return; - } - - tp->hwmon_dev = hwmon_device_register(&pdev->dev); + tp->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, "tg3", + tp, tg3_groups); if (IS_ERR(tp->hwmon_dev)) { tp->hwmon_dev = NULL; dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n"); - sysfs_remove_group(&pdev->dev.kobj, &tg3_group); } } -- cgit v1.2.3 From 5e53e689b737526308db2b5c9f56e9d0371a1676 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Nov 2013 21:09:26 +0100 Subject: genetlink/pmcraid: use proper genetlink multicast API The pmcraid driver is abusing the genetlink API and is using its family ID as the multicast group ID, which is invalid and may belong to somebody else (and likely will.) Make it use the correct API, but since this may already be used as-is by userspace, reserve a family ID for this code and also reserve that group ID to not break userspace assumptions. My previous patch broke event delivery in the driver as I missed that it wasn't using the right API and forgot to update it later in my series. While changing this, I noticed that the genetlink code could use the static group ID instead of a strcmp(), so also do that for the VFS_DQUOT family. Cc: Anil Ravindranath Cc: "James E.J. Bottomley" Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- drivers/scsi/pmcraid.c | 20 +++++++++++++++----- include/uapi/linux/genetlink.h | 1 + net/netlink/genetlink.c | 11 +++++++++-- 3 files changed, 25 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index bd6f743d87a7..892ea6161376 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -1404,11 +1404,22 @@ enum { }; #define PMCRAID_AEN_CMD_MAX (__PMCRAID_AEN_CMD_MAX - 1) +static struct genl_multicast_group pmcraid_mcgrps[] = { + { .name = "events", /* not really used - see ID discussion below */ }, +}; + static struct genl_family pmcraid_event_family = { - .id = GENL_ID_GENERATE, + /* + * Due to prior multicast group abuse (the code having assumed that + * the family ID can be used as a multicast group ID) we need to + * statically allocate a family (and thus group) ID. + */ + .id = GENL_ID_PMCRAID, .name = "pmcraid", .version = 1, - .maxattr = PMCRAID_AEN_ATTR_MAX + .maxattr = PMCRAID_AEN_ATTR_MAX, + .mcgrps = pmcraid_mcgrps, + .n_mcgrps = ARRAY_SIZE(pmcraid_mcgrps), }; /** @@ -1511,9 +1522,8 @@ static int pmcraid_notify_aen( return result; } - result = - genlmsg_multicast(&pmcraid_event_family, skb, 0, - pmcraid_event_family.id, GFP_ATOMIC); + result = genlmsg_multicast(&pmcraid_event_family, skb, + 0, 0, GFP_ATOMIC); /* If there are no listeners, genlmsg_multicast may return non-zero * value. diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h index 1af72d8228e0..c3363ba1ae05 100644 --- a/include/uapi/linux/genetlink.h +++ b/include/uapi/linux/genetlink.h @@ -28,6 +28,7 @@ struct genlmsghdr { #define GENL_ID_GENERATE 0 #define GENL_ID_CTRL NLMSG_MIN_TYPE #define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) +#define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) /************************************************************************** * Controller diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 803206e82450..713671ae45af 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -74,9 +74,12 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE]; * Bit 17 is marked as already used since the VFS quota code * also abused this API and relied on family == group ID, we * cater to that by giving it a static family and group ID. + * Bit 18 is marked as already used since the PMCRAID driver + * did the same thing as the VFS quota code (maybe copied?) */ static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) | - BIT(GENL_ID_VFS_DQUOT); + BIT(GENL_ID_VFS_DQUOT) | + BIT(GENL_ID_PMCRAID); static unsigned long *mc_groups = &mc_group_start; static unsigned long mc_groups_longs = 1; @@ -139,6 +142,7 @@ static u16 genl_generate_id(void) for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) { if (id_gen_idx != GENL_ID_VFS_DQUOT && + id_gen_idx != GENL_ID_PMCRAID && !genl_family_find_byid(id_gen_idx)) return id_gen_idx; if (++id_gen_idx > GENL_MAX_ID) @@ -236,9 +240,12 @@ static int genl_validate_assign_mc_groups(struct genl_family *family) } else if (strcmp(family->name, "NET_DM") == 0) { first_id = 1; BUG_ON(n_groups != 1); - } else if (strcmp(family->name, "VFS_DQUOT") == 0) { + } else if (family->id == GENL_ID_VFS_DQUOT) { first_id = GENL_ID_VFS_DQUOT; BUG_ON(n_groups != 1); + } else if (family->id == GENL_ID_PMCRAID) { + first_id = GENL_ID_PMCRAID; + BUG_ON(n_groups != 1); } else { groups_allocated = true; err = genl_allocate_reserve_groups(n_groups, &first_id); -- cgit v1.2.3 From 167f76a87743dfaf1fec954db5233715ddad49ef Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Mon, 25 Nov 2013 12:40:49 +0800 Subject: phy: Add Vitesse 8514 phy ID Phy is compatible with Vitesse 82xx Signed-off-by: Shaohui Xie Signed-off-by: David S. Miller --- drivers/net/phy/vitesse.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 508e4359338b..14372c65a7e8 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -64,6 +64,7 @@ #define PHY_ID_VSC8234 0x000fc620 #define PHY_ID_VSC8244 0x000fc6c0 +#define PHY_ID_VSC8514 0x00070670 #define PHY_ID_VSC8574 0x000704a0 #define PHY_ID_VSC8662 0x00070660 #define PHY_ID_VSC8221 0x000fc550 @@ -131,6 +132,7 @@ static int vsc82xx_config_intr(struct phy_device *phydev) err = phy_write(phydev, MII_VSC8244_IMASK, (phydev->drv->phy_id == PHY_ID_VSC8234 || phydev->drv->phy_id == PHY_ID_VSC8244 || + phydev->drv->phy_id == PHY_ID_VSC8514 || phydev->drv->phy_id == PHY_ID_VSC8574) ? MII_VSC8244_IMASK_MASK : MII_VSC8221_IMASK_MASK); @@ -245,6 +247,18 @@ static struct phy_driver vsc82xx_driver[] = { .ack_interrupt = &vsc824x_ack_interrupt, .config_intr = &vsc82xx_config_intr, .driver = { .owner = THIS_MODULE,}, +}, { + .phy_id = PHY_ID_VSC8514, + .name = "Vitesse VSC8514", + .phy_id_mask = 0x000ffff0, + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &vsc824x_config_init, + .config_aneg = &vsc82x4_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &vsc824x_ack_interrupt, + .config_intr = &vsc82xx_config_intr, + .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_VSC8574, .name = "Vitesse VSC8574", @@ -315,6 +329,7 @@ module_exit(vsc82xx_exit); static struct mdio_device_id __maybe_unused vitesse_tbl[] = { { PHY_ID_VSC8234, 0x000ffff0 }, { PHY_ID_VSC8244, 0x000fffc0 }, + { PHY_ID_VSC8514, 0x000ffff0 }, { PHY_ID_VSC8574, 0x000ffff0 }, { PHY_ID_VSC8662, 0x000ffff0 }, { PHY_ID_VSC8221, 0x000ffff0 }, -- cgit v1.2.3 From cd3e22b75c01fe1e075d91504b29019a05d8d373 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 25 Nov 2013 17:19:04 +0800 Subject: macvtap: fix tx_dropped counting error After commit 8ffab51b3dfc54876f145f15b351c41f3f703195 (macvlan: lockless tx path), tx stat counter were converted to percpu stat structure. So we need use to this also for tx_dropped in macvtap. Otherwise, the management won't notice the dropping packet in macvtap tx path. Cc: Michael S. Tsirkin Cc: Vlad Yasevich Cc: Eric Dumazet Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index dc76670c2f2a..0605da8e25f5 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -744,7 +744,7 @@ err: rcu_read_lock(); vlan = rcu_dereference(q->vlan); if (vlan) - vlan->dev->stats.tx_dropped++; + this_cpu_inc(vlan->pcpu_stats->tx_dropped); rcu_read_unlock(); return err; -- cgit v1.2.3 From ae5e8127b712313ec1b99356019ce9226fea8b88 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Mon, 25 Nov 2013 16:52:34 +0000 Subject: xen-netback: include definition of csum_ipv6_magic We are now using csum_ipv6_magic, include the appropriate header. Avoids the following error: drivers/net/xen-netback/netback.c:1313:4: error: implicit declaration of function 'csum_ipv6_magic' [-Werror=implicit-function-declaration] tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, Signed-off-by: Andy Whitcroft Acked-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 919b6509455c..64f0e0d18b81 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -39,6 +39,7 @@ #include #include +#include #include #include -- cgit v1.2.3 From bc9627e7e918a85e906c1a3f6d01d9b8ef911a96 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Tue, 26 Nov 2013 00:40:58 +0100 Subject: via-velocity: fix netif_receive_skb use in irq disabled section. 2fdac010bdcf10a30711b6924612dfc40daf19b8 ("via-velocity.c: update napi implementation") overlooked an irq disabling spinlock when the Rx part of the NAPI poll handler was converted from netif_rx to netif_receive_skb. NAPI Rx processing can be taken out of the locked section with a pair of napi_{disable / enable} since it only races with the MTU change function. An heavier rework of the NAPI locking would be able to perform NAPI Tx before Rx where I simply removed one of velocity_tx_srv calls. References: https://bugzilla.redhat.com/show_bug.cgi?id=1022733 Fixes: 2fdac010bdcf (via-velocity.c: update napi implementation) Signed-off-by: Francois Romieu Tested-by: Alex A. Schmidt Cc: Jamie Heilman Cc: Michele Baldessari Cc: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/ethernet/via/via-velocity.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index d022bf936572..ad61d26a44f3 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -2172,16 +2172,13 @@ static int velocity_poll(struct napi_struct *napi, int budget) unsigned int rx_done; unsigned long flags; - spin_lock_irqsave(&vptr->lock, flags); /* * Do rx and tx twice for performance (taken from the VIA * out-of-tree driver). */ - rx_done = velocity_rx_srv(vptr, budget / 2); - velocity_tx_srv(vptr); - rx_done += velocity_rx_srv(vptr, budget - rx_done); + rx_done = velocity_rx_srv(vptr, budget); + spin_lock_irqsave(&vptr->lock, flags); velocity_tx_srv(vptr); - /* If budget not fully consumed, exit the polling mode */ if (rx_done < budget) { napi_complete(napi); @@ -2342,6 +2339,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) if (ret < 0) goto out_free_tmp_vptr_1; + napi_disable(&vptr->napi); + spin_lock_irqsave(&vptr->lock, flags); netif_stop_queue(dev); @@ -2362,6 +2361,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) velocity_give_many_rx_descs(vptr); + napi_enable(&vptr->napi); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev); -- cgit v1.2.3 From 55485e7b417b640870b14eceec4cfbcb2b3e7a92 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Tue, 26 Nov 2013 17:54:41 +0100 Subject: be2net: call napi_disable() for all event queues The recent be2net commit 6384a4d (adds a support for busy polling) introduces a regression that results in kernel crash. It incorrectly modified be_close() so napi_disable() is called only for the first queue. This breaks a correct pairing of napi_enable/_disable for the rest of event queues and causes a crash in subsequent be_open() call. Cc: Sathya Perla Cc: Subbu Seetharaman Cc: Ajit Khaparde Signed-off-by: Ivan Vecera Acked-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 78a0e859760b..0aec4d23eb58 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2663,8 +2663,8 @@ static int be_close(struct net_device *netdev) napi_disable(&eqo->napi); be_disable_busy_poll(eqo); } - adapter->flags &= ~BE_FLAGS_NAPI_ENABLED; } + adapter->flags &= ~BE_FLAGS_NAPI_ENABLED; be_async_mcc_disable(adapter); -- cgit v1.2.3 From 71237b6feb8361a00a1cb481a0c901fbee8f82a5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Nov 2013 18:53:36 -0500 Subject: Revert "be2net: call napi_disable() for all event queues" This reverts commit 55485e7b417b640870b14eceec4cfbcb2b3e7a92. I applied the wrong version of this patch, the right one is coming up next. Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 0aec4d23eb58..78a0e859760b 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2663,8 +2663,8 @@ static int be_close(struct net_device *netdev) napi_disable(&eqo->napi); be_disable_busy_poll(eqo); } + adapter->flags &= ~BE_FLAGS_NAPI_ENABLED; } - adapter->flags &= ~BE_FLAGS_NAPI_ENABLED; be_async_mcc_disable(adapter); -- cgit v1.2.3 From dff345c5c85df3c5853491b007f6b1b578dc28a4 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Wed, 27 Nov 2013 08:59:32 +0100 Subject: be2net: call napi_disable() for all event queues The recent be2net commit 6384a4d (adds a support for busy polling) introduces a regression that results in kernel crash. It incorrectly modified be_close() so napi_disable() is called only for the first queue. This breaks a correct pairing of napi_enable/_disable for the rest of event queues and causes a crash in subsequent be_open() call. v2: Applied suggestions from Sathya Fixes: 6384a4d ("be2net: add support for ndo_busy_poll") Cc: Sathya Perla Cc: Subbu Seetharaman Cc: Ajit Khaparde Signed-off-by: Ivan Vecera Acked-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 78a0e859760b..fee64bf10446 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2658,8 +2658,8 @@ static int be_close(struct net_device *netdev) be_roce_dev_close(adapter); - for_all_evt_queues(adapter, eqo, i) { - if (adapter->flags & BE_FLAGS_NAPI_ENABLED) { + if (adapter->flags & BE_FLAGS_NAPI_ENABLED) { + for_all_evt_queues(adapter, eqo, i) { napi_disable(&eqo->napi); be_disable_busy_poll(eqo); } -- cgit v1.2.3 From 54b2b50c20a61b51199bedb6e5d2f8ec2568fb43 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 23 Oct 2013 06:25:40 -0400 Subject: [SCSI] Disable WRITE SAME for RAID and virtual host adapter drivers Some host adapters do not pass commands through to the target disk directly. Instead they provide an emulated target which may or may not accurately report its capabilities. In some cases the physical device characteristics are reported even when the host adapter is processing commands on the device's behalf. This can lead to adapter firmware hangs or excessive I/O errors. This patch disables WRITE SAME for devices connected to host adapters that provide an emulated target. Driver writers can disable WRITE SAME by setting the no_write_same flag in the host adapter template. [jejb: fix up rejections due to eh_deadline patch] Signed-off-by: Martin K. Petersen Cc: stable@kernel.org Signed-off-by: James Bottomley --- drivers/ata/libata-scsi.c | 1 + drivers/firewire/sbp2.c | 1 + drivers/scsi/3w-9xxx.c | 3 ++- drivers/scsi/3w-sas.c | 3 ++- drivers/scsi/3w-xxxx.c | 3 ++- drivers/scsi/aacraid/linit.c | 1 + drivers/scsi/arcmsr/arcmsr_hba.c | 1 + drivers/scsi/gdth.c | 1 + drivers/scsi/hosts.c | 1 + drivers/scsi/hpsa.c | 1 + drivers/scsi/ipr.c | 3 ++- drivers/scsi/ips.c | 1 + drivers/scsi/megaraid.c | 1 + drivers/scsi/megaraid/megaraid_mbox.c | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 1 + drivers/scsi/pmcraid.c | 1 + drivers/scsi/sd.c | 6 ++++++ drivers/scsi/storvsc_drv.c | 1 + include/scsi/scsi_host.h | 6 ++++++ 19 files changed, 33 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index db6dfcfa3e2e..ab58556d347c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3625,6 +3625,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) shost->max_lun = 1; shost->max_channel = 1; shost->max_cmd_len = 16; + shost->no_write_same = 1; /* Schedule policy is determined by ->qc_defer() * callback and it needs to see every deferred qc. diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 281029daf98c..b0bb056458a3 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1623,6 +1623,7 @@ static struct scsi_host_template scsi_driver_template = { .cmd_per_lun = 1, .can_queue = 1, .sdev_attrs = sbp2_scsi_sysfs_attrs, + .no_write_same = 1, }; MODULE_AUTHOR("Kristian Hoegsberg "); diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 5e1e12c0cf42..0a7325361d29 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -2025,7 +2025,8 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = TW_MAX_CMDS_PER_LUN, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = twa_host_attrs, - .emulated = 1 + .emulated = 1, + .no_write_same = 1, }; /* This function will probe and initialize a card */ diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index c845bdbeb6c0..4de346017e9f 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -1600,7 +1600,8 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = TW_MAX_CMDS_PER_LUN, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = twl_host_attrs, - .emulated = 1 + .emulated = 1, + .no_write_same = 1, }; /* This function will probe and initialize a card */ diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index b9276d10b25c..752624e6bc00 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2279,7 +2279,8 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = TW_MAX_CMDS_PER_LUN, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = tw_host_attrs, - .emulated = 1 + .emulated = 1, + .no_write_same = 1, }; /* This function will probe and initialize a card */ diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index f0d432c139d0..4921ed19a027 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1081,6 +1081,7 @@ static struct scsi_host_template aac_driver_template = { #endif .use_clustering = ENABLE_CLUSTERING, .emulated = 1, + .no_write_same = 1, }; static void __aac_shutdown(struct aac_dev * aac) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 97fd450aff09..4f6a30b8e5f9 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -137,6 +137,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = arcmsr_host_attrs, + .no_write_same = 1, }; static struct pci_device_id arcmsr_device_id_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index ee4fa40a50b1..ce5ef0190bad 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -4684,6 +4684,7 @@ static struct scsi_host_template gdth_template = { .cmd_per_lun = GDTH_MAXC_P_L, .unchecked_isa_dma = 1, .use_clustering = ENABLE_CLUSTERING, + .no_write_same = 1, }; #ifdef CONFIG_ISA diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index f334859024c0..f2c5005f312a 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -395,6 +395,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) shost->use_clustering = sht->use_clustering; shost->ordered_tag = sht->ordered_tag; shost->eh_deadline = shost_eh_deadline * HZ; + shost->no_write_same = sht->no_write_same; if (sht->supported_mode == MODE_UNKNOWN) /* means we didn't set it ... default to INITIATOR */ diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 22f6432eb475..2336beff7a48 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -561,6 +561,7 @@ static struct scsi_host_template hpsa_driver_template = { .sdev_attrs = hpsa_sdev_attrs, .shost_attrs = hpsa_shost_attrs, .max_sectors = 8192, + .no_write_same = 1, }; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 36ac1c34ce97..573f4128b6b6 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6305,7 +6305,8 @@ static struct scsi_host_template driver_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = ipr_ioa_attrs, .sdev_attrs = ipr_dev_attrs, - .proc_name = IPR_NAME + .proc_name = IPR_NAME, + .no_write_same = 1, }; /** diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 8d5ea8a1e5a6..52a216f21ae5 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -374,6 +374,7 @@ static struct scsi_host_template ips_driver_template = { .sg_tablesize = IPS_MAX_SG, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, + .no_write_same = 1, }; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 90c95a3385d1..816db12ef5d5 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -4244,6 +4244,7 @@ static struct scsi_host_template megaraid_template = { .eh_device_reset_handler = megaraid_reset, .eh_bus_reset_handler = megaraid_reset, .eh_host_reset_handler = megaraid_reset, + .no_write_same = 1, }; static int diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index d1a4b82836ea..e2237a97cb9d 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -367,6 +367,7 @@ static struct scsi_host_template megaraid_template_g = { .eh_host_reset_handler = megaraid_reset_handler, .change_queue_depth = megaraid_change_queue_depth, .use_clustering = ENABLE_CLUSTERING, + .no_write_same = 1, .sdev_attrs = megaraid_sdev_attrs, .shost_attrs = megaraid_shost_attrs, }; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 0a743a5d1647..c99812bf2a73 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2148,6 +2148,7 @@ static struct scsi_host_template megasas_template = { .bios_param = megasas_bios_param, .use_clustering = ENABLE_CLUSTERING, .change_queue_depth = megasas_change_queue_depth, + .no_write_same = 1, }; /** diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index bd6f743d87a7..f413ef796b43 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4315,6 +4315,7 @@ static struct scsi_host_template pmcraid_host_template = { .this_id = -1, .sg_tablesize = PMCRAID_MAX_IOADLS, .max_sectors = PMCRAID_IOA_MAX_SECTORS, + .no_write_same = 1, .cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = pmcraid_host_attrs, diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e6c4bff04339..69725f7c32c1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2659,6 +2659,12 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) { struct scsi_device *sdev = sdkp->device; + if (sdev->host->no_write_same) { + sdev->no_write_same = 1; + + return; + } + if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) { /* too large values might cause issues with arcmsr */ int vpd_buf_len = 64; diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 1a28f5632797..17d740427240 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1697,6 +1697,7 @@ static struct scsi_host_template scsi_driver = { .use_clustering = DISABLE_CLUSTERING, /* Make sure we dont get a sg segment crosses a page boundary */ .dma_boundary = PAGE_SIZE-1, + .no_write_same = 1, }; enum { diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 546084964d55..fe3b58e836c8 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -475,6 +475,9 @@ struct scsi_host_template { */ unsigned ordered_tag:1; + /* True if the controller does not support WRITE SAME */ + unsigned no_write_same:1; + /* * Countdown for host blocking with no commands outstanding. */ @@ -677,6 +680,9 @@ struct Scsi_Host { /* Don't resume host in EH */ unsigned eh_noresume:1; + /* The controller does not support WRITE SAME */ + unsigned no_write_same:1; + /* * Optional work queue to be utilized by the transport */ -- cgit v1.2.3 From fdeadb43fdf1e7d5698c027b555c389174548e5a Mon Sep 17 00:00:00 2001 From: Madper Xie Date: Fri, 29 Nov 2013 15:58:57 +0800 Subject: efi-pstore: Make efi-pstore return a unique id Pstore fs expects that backends provide a unique id which could avoid pstore making entries as duplication or denominating entries the same name. So I combine the timestamp, part and count into id. Signed-off-by: Madper Xie Cc: Seiji Aguchi Cc: stable@vger.kernel.org Signed-off-by: Matt Fleming --- drivers/firmware/efi/efi-pstore.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index 6ce31e93da55..743fd426f21b 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c @@ -37,6 +37,12 @@ struct pstore_read_data { char **buf; }; +static inline u64 generic_id(unsigned long timestamp, + unsigned int part, int count) +{ + return (timestamp * 100 + part) * 1000 + count; +} + static int efi_pstore_read_func(struct efivar_entry *entry, void *data) { efi_guid_t vendor = LINUX_EFI_CRASH_GUID; @@ -55,7 +61,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data) if (sscanf(name, "dump-type%u-%u-%d-%lu-%c", cb_data->type, &part, &cnt, &time, &data_type) == 5) { - *cb_data->id = part; + *cb_data->id = generic_id(time, part, cnt); *cb_data->count = cnt; cb_data->timespec->tv_sec = time; cb_data->timespec->tv_nsec = 0; @@ -65,7 +71,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data) *cb_data->compressed = false; } else if (sscanf(name, "dump-type%u-%u-%d-%lu", cb_data->type, &part, &cnt, &time) == 4) { - *cb_data->id = part; + *cb_data->id = generic_id(time, part, cnt); *cb_data->count = cnt; cb_data->timespec->tv_sec = time; cb_data->timespec->tv_nsec = 0; @@ -77,7 +83,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data) * which doesn't support holding * multiple logs, remains. */ - *cb_data->id = part; + *cb_data->id = generic_id(time, part, 0); *cb_data->count = 0; cb_data->timespec->tv_sec = time; cb_data->timespec->tv_nsec = 0; @@ -320,14 +326,16 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, char name[DUMP_NAME_LEN]; efi_char16_t efi_name[DUMP_NAME_LEN]; int found, i; + unsigned int part; - sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count, - time.tv_sec); + do_div(id, 1000); + part = do_div(id, 100); + sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, time.tv_sec); for (i = 0; i < DUMP_NAME_LEN; i++) efi_name[i] = name[i]; - edata.id = id; + edata.id = part; edata.type = type; edata.count = count; edata.time = time; -- cgit v1.2.3 From 006da7b07bc4d3a7ffabad17cf639eec6849c9dc Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 26 Nov 2013 12:37:12 -0500 Subject: macvtap: Do not double-count received packets Currently macvlan will count received packets after calling each vlans receive handler. Macvtap attempts to count the packet yet again when the user reads the packet from the tap socket. This code doesn't do this consistently either. Remove the counting from macvtap and let only macvlan count received packets. Signed-off-by: Vlad Yasevich Acked-by: Michael S. Tsirkin Acked-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 0605da8e25f5..9093004f9b63 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -767,7 +767,6 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, const struct sk_buff *skb, const struct iovec *iv, int len) { - struct macvlan_dev *vlan; int ret; int vnet_hdr_len = 0; int vlan_offset = 0; @@ -821,15 +820,6 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, copied += len; done: - rcu_read_lock(); - vlan = rcu_dereference(q->vlan); - if (vlan) { - preempt_disable(); - macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0); - preempt_enable(); - } - rcu_read_unlock(); - return ret ? ret : copied; } -- cgit v1.2.3 From 1bac1072425c86f1ac85bd5967910706677ef8b3 Mon Sep 17 00:00:00 2001 From: David Chang Date: Wed, 27 Nov 2013 15:48:36 +0800 Subject: r8169: check ALDPS bit and disable it if enabled for the 8168g Windows driver will enable ALDPS function, but linux driver and firmware do not have any configuration related to ALDPS function for 8168g. So restart system to linux and remove the NIC cable, LAN enter ALDPS, then LAN RX will be disabled. This issue can be easily reproduced on dual boot windows and linux system with RTL_GIGA_MAC_VER_40 chip. Realtek said, ALDPS function can be disabled by configuring to PHY, switch to page 0x0A43, reg0x10 bit2=0. Signed-off-by: David Chang Acked-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 799387570766..c737f0ea5de7 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3465,6 +3465,11 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x14, 0x9065); rtl_writephy(tp, 0x14, 0x1065); + /* Check ALDPS bit, disable it if enabled */ + rtl_writephy(tp, 0x1f, 0x0a43); + if (rtl_readphy(tp, 0x10) & 0x0004) + rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0004); + rtl_writephy(tp, 0x1f, 0x0000); } -- cgit v1.2.3 From 7fe0ee099ad5e3dea88d4ee1b6f20246b1ca57c3 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 27 Nov 2013 14:32:52 +0800 Subject: net: 8139cp: fix a BUG_ON triggered by wrong bytes_compl Using iperf to send packets(GSO mode is on), a bug is triggered: [ 212.672781] kernel BUG at lib/dynamic_queue_limits.c:26! [ 212.673396] invalid opcode: 0000 [#1] SMP [ 212.673882] Modules linked in: 8139cp(O) nls_utf8 edd fuse loop dm_mod ipv6 i2c_piix4 8139too i2c_core intel_agp joydev pcspkr hid_generic intel_gtt floppy sr_mod mii button sg cdrom ext3 jbd mbcache usbhid hid uhci_hcd ehci_hcd usbcore sd_mod usb_common crc_t10dif crct10dif_common processor thermal_sys hwmon scsi_dh_emc scsi_dh_rdac scsi_dh_hp_sw scsi_dh ata_generic ata_piix libata scsi_mod [last unloaded: 8139cp] [ 212.676084] CPU: 0 PID: 4124 Comm: iperf Tainted: G O 3.12.0-0.7-default+ #16 [ 212.676084] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 [ 212.676084] task: ffff8800d83966c0 ti: ffff8800db4c8000 task.ti: ffff8800db4c8000 [ 212.676084] RIP: 0010:[] [] dql_completed+0x17f/0x190 [ 212.676084] RSP: 0018:ffff880116e03e30 EFLAGS: 00010083 [ 212.676084] RAX: 00000000000005ea RBX: 0000000000000f7c RCX: 0000000000000002 [ 212.676084] RDX: ffff880111dd0dc0 RSI: 0000000000000bd4 RDI: ffff8800db6ffcc0 [ 212.676084] RBP: ffff880116e03e48 R08: 0000000000000992 R09: 0000000000000000 [ 212.676084] R10: ffffffff8181e400 R11: 0000000000000004 R12: 000000000000000f [ 212.676084] R13: ffff8800d94ec840 R14: ffff8800db440c80 R15: 000000000000000e [ 212.676084] FS: 00007f6685a3c700(0000) GS:ffff880116e00000(0000) knlGS:0000000000000000 [ 212.676084] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 212.676084] CR2: 00007f6685ad6460 CR3: 00000000db714000 CR4: 00000000000006f0 [ 212.676084] Stack: [ 212.676084] ffff8800db6ffc00 000000000000000f ffff8800d94ec840 ffff880116e03eb8 [ 212.676084] ffffffffa041509f ffff880116e03e88 0000000f16e03e88 ffff8800d94ec000 [ 212.676084] 00000bd400059858 000000050000000f ffffffff81094c36 ffff880116e03eb8 [ 212.676084] Call Trace: [ 212.676084] [ 212.676084] [] cp_interrupt+0x4ef/0x590 [8139cp] [ 212.676084] [] ? ktime_get+0x56/0xd0 [ 212.676084] [] handle_irq_event_percpu+0x53/0x170 [ 212.676084] [] handle_irq_event+0x3c/0x60 [ 212.676084] [] handle_fasteoi_irq+0x55/0xf0 [ 212.676084] [] handle_irq+0x1f/0x30 [ 212.676084] [] do_IRQ+0x5b/0xe0 [ 212.676084] [] common_interrupt+0x6a/0x6a [ 212.676084] [ 212.676084] [] ? cp_start_xmit+0x621/0x97c [8139cp] [ 212.676084] [] ? cp_start_xmit+0x609/0x97c [8139cp] [ 212.676084] [] dev_hard_start_xmit+0x2c9/0x550 [ 212.676084] [] sch_direct_xmit+0x179/0x1d0 [ 212.676084] [] dev_queue_xmit+0x293/0x440 [ 212.676084] [] ip_finish_output+0x236/0x450 [ 212.676084] [] ? __alloc_pages_nodemask+0x187/0xb10 [ 212.676084] [] ip_output+0x88/0x90 [ 212.676084] [] ip_local_out+0x24/0x30 [ 212.676084] [] ip_queue_xmit+0x14d/0x3e0 [ 212.676084] [] tcp_transmit_skb+0x501/0x840 [ 212.676084] [] tcp_write_xmit+0x1e3/0xb20 [ 212.676084] [] ? skb_page_frag_refill+0x87/0xd0 [ 212.676084] [] tcp_push_one+0x2b/0x40 [ 212.676084] [] tcp_sendmsg+0x926/0xc90 [ 212.676084] [] inet_sendmsg+0x61/0xc0 [ 212.676084] [] sock_aio_write+0x101/0x120 [ 212.676084] [] ? vma_adjust+0x2e1/0x5d0 [ 212.676084] [] ? timerqueue_add+0x60/0xb0 [ 212.676084] [] do_sync_write+0x60/0x90 [ 212.676084] [] ? rw_verify_area+0x54/0xf0 [ 212.676084] [] vfs_write+0x186/0x190 [ 212.676084] [] SyS_write+0x5d/0xa0 [ 212.676084] [] system_call_fastpath+0x16/0x1b [ 212.676084] Code: ca 41 89 dc 41 29 cc 45 31 db 29 c2 41 89 c5 89 d0 45 29 c5 f7 d0 c1 e8 1f e9 43 ff ff ff 66 0f 1f 44 00 00 31 c0 e9 7b ff ff ff <0f> 0b eb fe 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 c7 47 40 00 [ 212.676084] RIP [] dql_completed+0x17f/0x190 ------------[ cut here ]------------ When a skb has frags, bytes_compl plus skb->len nr_frags times in cp_tx(). It's not the correct value(actually, it should plus skb->len once) and it will trigger the BUG_ON(bytes_compl > num_queued - dql->num_completed). So only increase bytes_compl when finish sending all frags. pkts_compl also has a wrong value, fix it too. It's introduced by commit 871f0d4c ("8139cp: enable bql"). Suggested-by: Eric Dumazet Signed-off-by: Yang Yingliang Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/8139cp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index f2a2128165dd..737c1a881f78 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -678,9 +678,6 @@ static void cp_tx (struct cp_private *cp) le32_to_cpu(txd->opts1) & 0xffff, PCI_DMA_TODEVICE); - bytes_compl += skb->len; - pkts_compl++; - if (status & LastFrag) { if (status & (TxError | TxFIFOUnder)) { netif_dbg(cp, tx_err, cp->dev, @@ -702,6 +699,8 @@ static void cp_tx (struct cp_private *cp) netif_dbg(cp, tx_done, cp->dev, "tx done, slot %d\n", tx_tail); } + bytes_compl += skb->len; + pkts_compl++; dev_kfree_skb_irq(skb); } -- cgit v1.2.3 From b268daffdcb9762ad9aa3898096570a9dd92aa9b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 27 Nov 2013 13:33:21 +0100 Subject: net: smc91: fix crash regression on the versatile After commit e9e4ea74f06635f2ffc1dffe5ef40c854faa0a90 "net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data" The Versatile SMSC LAN91C111 is crashing like this: ------------[ cut here ]------------ kernel BUG at /home/linus/linux/drivers/net/ethernet/smsc/smc91x.c:599! Internal error: Oops - BUG: 0 [#1] ARM Modules linked in: CPU: 0 PID: 43 Comm: udhcpc Not tainted 3.13.0-rc1+ #24 task: c6ccfaa0 ti: c6cd0000 task.ti: c6cd0000 PC is at smc_hardware_send_pkt+0x198/0x22c LR is at smc_hardware_send_pkt+0x24/0x22c pc : [] lr : [] psr: 20000013 sp : c6cd1d08 ip : 00000001 fp : 00000000 r10: c02adb08 r9 : 00000000 r8 : c6ced802 r7 : c786fba0 r6 : 00000146 r5 : c8800000 r4 : c78d6000 r3 : 0000000f r2 : 00000146 r1 : 00000000 r0 : 00000031 Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 0005317f Table: 06cf4000 DAC: 00000015 Process udhcpc (pid: 43, stack limit = 0xc6cd01c0) Stack: (0xc6cd1d08 to 0xc6cd2000) 1d00: 00000010 c8800000 c78d6000 c786fba0 c78d6000 c01be868 1d20: c01be7a4 00004000 00000000 c786fba0 c6c12b80 c0208554 000004d0 c780fc60 1d40: 00000220 c01fb734 00000000 00000000 00000000 c6c9a440 c6c12b80 c78d6000 1d60: c786fba0 c6c9a440 00000000 c021d1d8 00000000 00000000 c6c12b80 c78d6000 1d80: c786fba0 00000001 c6c9a440 c02087f8 c6c9a4a0 00080008 00000000 00000000 1da0: c78d6000 c786fba0 c78d6000 00000138 00000000 00000000 00000000 00000000 1dc0: 00000000 c027ba74 00000138 00000138 00000001 00000010 c6cedc00 00000000 1de0: 00000008 c7404400 c6cd1eec c6cd1f14 c067a73c c065c0b8 00000000 c067a740 1e00: 01ffffff 002040d0 00000000 00000000 00000000 00000000 00000000 ffffffff 1e20: 43004400 00110022 c6cdef20 c027ae8c c6ccfaa0 be82d65c 00000014 be82d3cc 1e40: 00000000 00000000 00000000 c01f2870 00000000 00000000 00000000 c6cd1e88 1e60: c6ccfaa0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1e80: 00000000 00000000 00000031 c7802310 c7802300 00000138 c7404400 c0771da0 1ea0: 00000000 c6cd1eec c7800340 00000138 be82d65c 00000014 be82d3cc c6cd1f08 1ec0: 00000014 00000000 c7404400 c7404400 00000138 c01f4628 c78d6000 00000000 1ee0: 00000000 be82d3cc 00000138 c6cd1f08 00000014 c6cd1ee4 00000001 00000000 1f00: 00000000 00000000 00080011 00000002 06000000 ffffffff 0000ffff 00000002 1f20: 06000000 ffffffff 0000ffff c00928c8 c065c520 c6cd1f58 00000003 c009299c 1f40: 00000003 c065c520 c7404400 00000000 c7404400 c01f2218 c78106b0 c7441cb0 1f60: 00000000 00000006 c06799fc 00000000 00000000 00000006 00000000 c01f3ee0 1f80: 00000000 00000000 be82d678 be82d65c 00000014 00000001 00000122 c00139c8 1fa0: c6cd0000 c0013840 be82d65c 00000014 00000006 be82d3cc 00000138 00000000 1fc0: be82d65c 00000014 00000001 00000122 00000000 00000000 00018cb1 00000000 1fe0: 00003801 be82d3a8 0003a0c7 b6e9af08 60000010 00000006 00000000 00000000 [] (smc_hardware_send_pkt+0x198/0x22c) from [] (smc_hard_start_xmit+0xc4/0x1e8) [] (smc_hard_start_xmit+0xc4/0x1e8) from [] (dev_hard_start_xmit+0x460/0x4cc) [] (dev_hard_start_xmit+0x460/0x4cc) from [] (sch_direct_xmit+0x94/0x18c) [] (sch_direct_xmit+0x94/0x18c) from [] (dev_queue_xmit+0x238/0x42c) [] (dev_queue_xmit+0x238/0x42c) from [] (packet_sendmsg+0xbe8/0xd28) [] (packet_sendmsg+0xbe8/0xd28) from [] (sock_sendmsg+0x84/0xa8) [] (sock_sendmsg+0x84/0xa8) from [] (SyS_sendto+0xb8/0xdc) [] (SyS_sendto+0xb8/0xdc) from [] (ret_fast_syscall+0x0/0x2c) Code: e3130002 1a000001 e3130001 0affffcd (e7f001f2) ---[ end trace 81104fe70e8da7fe ]--- Kernel panic - not syncing: Fatal exception in interrupt This is because the macro operations in smc91x.h defined for Versatile are missing SMC_outsw() as used in this commit. The Versatile needs and uses the same accessors as the other platforms in the first if(...) clause, just switch it to using that and we have one problem less to worry about. Checkpatch complains about spacing, but I have opted to follow the style of this .h-file. Cc: Russell King Cc: Nicolas Pitre Cc: Eric Miao Cc: Jonathan Cameron Cc: Will Deacon Cc: stable@vger.kernel.org Signed-off-by: Linus Walleij Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smc91x.h | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index c9d4c872e81d..902a7c268d82 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -46,7 +46,8 @@ defined(CONFIG_MACH_LITTLETON) ||\ defined(CONFIG_MACH_ZYLONITE2) ||\ defined(CONFIG_ARCH_VIPER) ||\ - defined(CONFIG_MACH_STARGATE2) + defined(CONFIG_MACH_STARGATE2) ||\ + defined(CONFIG_ARCH_VERSATILE) #include @@ -206,23 +207,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 -#elif defined(CONFIG_ARCH_VERSATILE) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_NOWAIT 1 - -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) -#define SMC_IRQ_FLAGS (-1) /* from resource */ - #elif defined(CONFIG_MN10300) /* -- cgit v1.2.3 From 9d38d28bd211451533d7a0d1de57485aaf86d00a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 29 Nov 2013 16:23:14 -0500 Subject: Revert "net: smc91: fix crash regression on the versatile" This reverts commit b268daffdcb9762ad9aa3898096570a9dd92aa9b. I applied the wrong version of this patch, the proper version is coming up next. Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smc91x.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index 902a7c268d82..c9d4c872e81d 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -46,8 +46,7 @@ defined(CONFIG_MACH_LITTLETON) ||\ defined(CONFIG_MACH_ZYLONITE2) ||\ defined(CONFIG_ARCH_VIPER) ||\ - defined(CONFIG_MACH_STARGATE2) ||\ - defined(CONFIG_ARCH_VERSATILE) + defined(CONFIG_MACH_STARGATE2) #include @@ -207,6 +206,23 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 +#elif defined(CONFIG_ARCH_VERSATILE) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) +#define SMC_IRQ_FLAGS (-1) /* from resource */ + #elif defined(CONFIG_MN10300) /* -- cgit v1.2.3 From a0c20fb02592d372e744d1d739cda3e1b3defaae Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 28 Nov 2013 14:33:52 +0100 Subject: net: smc91: fix crash regression on the versatile After commit e9e4ea74f06635f2ffc1dffe5ef40c854faa0a90 "net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data" The Versatile SMSC LAN91C111 is crashing like this: ------------[ cut here ]------------ kernel BUG at /home/linus/linux/drivers/net/ethernet/smsc/smc91x.c:599! Internal error: Oops - BUG: 0 [#1] ARM Modules linked in: CPU: 0 PID: 43 Comm: udhcpc Not tainted 3.13.0-rc1+ #24 task: c6ccfaa0 ti: c6cd0000 task.ti: c6cd0000 PC is at smc_hardware_send_pkt+0x198/0x22c LR is at smc_hardware_send_pkt+0x24/0x22c pc : [] lr : [] psr: 20000013 sp : c6cd1d08 ip : 00000001 fp : 00000000 r10: c02adb08 r9 : 00000000 r8 : c6ced802 r7 : c786fba0 r6 : 00000146 r5 : c8800000 r4 : c78d6000 r3 : 0000000f r2 : 00000146 r1 : 00000000 r0 : 00000031 Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 0005317f Table: 06cf4000 DAC: 00000015 Process udhcpc (pid: 43, stack limit = 0xc6cd01c0) Stack: (0xc6cd1d08 to 0xc6cd2000) 1d00: 00000010 c8800000 c78d6000 c786fba0 c78d6000 c01be868 1d20: c01be7a4 00004000 00000000 c786fba0 c6c12b80 c0208554 000004d0 c780fc60 1d40: 00000220 c01fb734 00000000 00000000 00000000 c6c9a440 c6c12b80 c78d6000 1d60: c786fba0 c6c9a440 00000000 c021d1d8 00000000 00000000 c6c12b80 c78d6000 1d80: c786fba0 00000001 c6c9a440 c02087f8 c6c9a4a0 00080008 00000000 00000000 1da0: c78d6000 c786fba0 c78d6000 00000138 00000000 00000000 00000000 00000000 1dc0: 00000000 c027ba74 00000138 00000138 00000001 00000010 c6cedc00 00000000 1de0: 00000008 c7404400 c6cd1eec c6cd1f14 c067a73c c065c0b8 00000000 c067a740 1e00: 01ffffff 002040d0 00000000 00000000 00000000 00000000 00000000 ffffffff 1e20: 43004400 00110022 c6cdef20 c027ae8c c6ccfaa0 be82d65c 00000014 be82d3cc 1e40: 00000000 00000000 00000000 c01f2870 00000000 00000000 00000000 c6cd1e88 1e60: c6ccfaa0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1e80: 00000000 00000000 00000031 c7802310 c7802300 00000138 c7404400 c0771da0 1ea0: 00000000 c6cd1eec c7800340 00000138 be82d65c 00000014 be82d3cc c6cd1f08 1ec0: 00000014 00000000 c7404400 c7404400 00000138 c01f4628 c78d6000 00000000 1ee0: 00000000 be82d3cc 00000138 c6cd1f08 00000014 c6cd1ee4 00000001 00000000 1f00: 00000000 00000000 00080011 00000002 06000000 ffffffff 0000ffff 00000002 1f20: 06000000 ffffffff 0000ffff c00928c8 c065c520 c6cd1f58 00000003 c009299c 1f40: 00000003 c065c520 c7404400 00000000 c7404400 c01f2218 c78106b0 c7441cb0 1f60: 00000000 00000006 c06799fc 00000000 00000000 00000006 00000000 c01f3ee0 1f80: 00000000 00000000 be82d678 be82d65c 00000014 00000001 00000122 c00139c8 1fa0: c6cd0000 c0013840 be82d65c 00000014 00000006 be82d3cc 00000138 00000000 1fc0: be82d65c 00000014 00000001 00000122 00000000 00000000 00018cb1 00000000 1fe0: 00003801 be82d3a8 0003a0c7 b6e9af08 60000010 00000006 00000000 00000000 [] (smc_hardware_send_pkt+0x198/0x22c) from [] (smc_hard_start_xmit+0xc4/0x1e8) [] (smc_hard_start_xmit+0xc4/0x1e8) from [] (dev_hard_start_xmit+0x460/0x4cc) [] (dev_hard_start_xmit+0x460/0x4cc) from [] (sch_direct_xmit+0x94/0x18c) [] (sch_direct_xmit+0x94/0x18c) from [] (dev_queue_xmit+0x238/0x42c) [] (dev_queue_xmit+0x238/0x42c) from [] (packet_sendmsg+0xbe8/0xd28) [] (packet_sendmsg+0xbe8/0xd28) from [] (sock_sendmsg+0x84/0xa8) [] (sock_sendmsg+0x84/0xa8) from [] (SyS_sendto+0xb8/0xdc) [] (SyS_sendto+0xb8/0xdc) from [] (ret_fast_syscall+0x0/0x2c) Code: e3130002 1a000001 e3130001 0affffcd (e7f001f2) ---[ end trace 81104fe70e8da7fe ]--- Kernel panic - not syncing: Fatal exception in interrupt This is because the macro operations in smc91x.h defined for Versatile are missing SMC_outsw() as used in this commit. The Versatile needs and uses the same accessors as the other platforms in the first if(...) clause, just switch it to using that and we have one problem less to worry about. This includes a hunk of a patch from Will Deacon fixin the other 32bit platforms as well: Innokom, Ramses, PXA, PCM027. Checkpatch complains about spacing, but I have opted to follow the style of this .h-file. Cc: Russell King Cc: Nicolas Pitre Cc: Eric Miao Cc: Jonathan Cameron Cc: stable@vger.kernel.org Signed-off-by: Will Deacon Signed-off-by: Linus Walleij Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smc91x.h | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index c9d4c872e81d..749654b976bc 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -46,7 +46,8 @@ defined(CONFIG_MACH_LITTLETON) ||\ defined(CONFIG_MACH_ZYLONITE2) ||\ defined(CONFIG_ARCH_VIPER) ||\ - defined(CONFIG_MACH_STARGATE2) + defined(CONFIG_MACH_STARGATE2) ||\ + defined(CONFIG_ARCH_VERSATILE) #include @@ -154,6 +155,8 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_outl(v, a, r) writel(v, (a) + (r)) #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) +#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) #define SMC_IRQ_FLAGS (-1) /* from resource */ /* We actually can't write halfwords properly if not word aligned */ @@ -206,23 +209,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 -#elif defined(CONFIG_ARCH_VERSATILE) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_NOWAIT 1 - -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) -#define SMC_IRQ_FLAGS (-1) /* from resource */ - #elif defined(CONFIG_MN10300) /* -- cgit v1.2.3 From 85493e6dd42dcaf0eaf0a19f12f1295e35cc3b7f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 27 Nov 2013 18:54:31 -0800 Subject: sfc: Convert to use hwmon_device_register_with_groups Simplify the code. Avoid race conditions caused by attributes being created after hwmon device registration. Implicitly (through hwmon API) add mandatory 'name' sysfs attribute. Reviewed-by: Ben Hutchings Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/mcdi.h | 2 + drivers/net/ethernet/sfc/mcdi_mon.c | 78 ++++++++++++++----------------------- 2 files changed, 32 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index 656a3277c2b2..15816cacb548 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -75,6 +75,8 @@ struct efx_mcdi_mon { unsigned long last_update; struct device *device; struct efx_mcdi_mon_attribute *attrs; + struct attribute_group group; + const struct attribute_group *groups[2]; unsigned int n_attrs; }; diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c index 4cc5d95b2a5a..d72ad4fc3617 100644 --- a/drivers/net/ethernet/sfc/mcdi_mon.c +++ b/drivers/net/ethernet/sfc/mcdi_mon.c @@ -139,17 +139,10 @@ static int efx_mcdi_mon_update(struct efx_nic *efx) return rc; } -static ssize_t efx_mcdi_mon_show_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%s\n", KBUILD_MODNAME); -} - static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index, efx_dword_t *entry) { - struct efx_nic *efx = dev_get_drvdata(dev); + struct efx_nic *efx = dev_get_drvdata(dev->parent); struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); int rc; @@ -263,7 +256,7 @@ static ssize_t efx_mcdi_mon_show_label(struct device *dev, efx_mcdi_sensor_type[mon_attr->type].label); } -static int +static void efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, ssize_t (*reader)(struct device *, struct device_attribute *, char *), @@ -272,7 +265,6 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, { struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs]; - int rc; strlcpy(attr->name, name, sizeof(attr->name)); attr->index = index; @@ -286,10 +278,7 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, attr->dev_attr.attr.name = attr->name; attr->dev_attr.attr.mode = S_IRUGO; attr->dev_attr.show = reader; - rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr); - if (rc == 0) - ++hwmon->n_attrs; - return rc; + hwmon->group.attrs[hwmon->n_attrs++] = &attr->dev_attr.attr; } int efx_mcdi_mon_probe(struct efx_nic *efx) @@ -338,26 +327,22 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) efx_mcdi_mon_update(efx); /* Allocate space for the maximum possible number of - * attributes for this set of sensors: name of the driver plus + * attributes for this set of sensors: * value, min, max, crit, alarm and label for each sensor. */ - n_attrs = 1 + 6 * n_sensors; + n_attrs = 6 * n_sensors; hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL); if (!hwmon->attrs) { rc = -ENOMEM; goto fail; } - - hwmon->device = hwmon_device_register(&efx->pci_dev->dev); - if (IS_ERR(hwmon->device)) { - rc = PTR_ERR(hwmon->device); + hwmon->group.attrs = kcalloc(n_attrs + 1, sizeof(struct attribute *), + GFP_KERNEL); + if (!hwmon->group.attrs) { + rc = -ENOMEM; goto fail; } - rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0); - if (rc) - goto fail; - for (i = 0, j = -1, type = -1; ; i++) { enum efx_hwmon_type hwmon_type; const char *hwmon_prefix; @@ -372,7 +357,7 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) page = type / 32; j = -1; if (page == n_pages) - return 0; + goto hwmon_register; MCDI_SET_DWORD(inbuf, SENSOR_INFO_EXT_IN_PAGE, page); @@ -453,28 +438,22 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) if (min1 != max1) { snprintf(name, sizeof(name), "%s%u_input", hwmon_prefix, hwmon_index); - rc = efx_mcdi_mon_add_attr( + efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_value, i, type, 0); - if (rc) - goto fail; if (hwmon_type != EFX_HWMON_POWER) { snprintf(name, sizeof(name), "%s%u_min", hwmon_prefix, hwmon_index); - rc = efx_mcdi_mon_add_attr( + efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_limit, i, type, min1); - if (rc) - goto fail; } snprintf(name, sizeof(name), "%s%u_max", hwmon_prefix, hwmon_index); - rc = efx_mcdi_mon_add_attr( + efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_limit, i, type, max1); - if (rc) - goto fail; if (min2 != max2) { /* Assume max2 is critical value. @@ -482,32 +461,38 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) */ snprintf(name, sizeof(name), "%s%u_crit", hwmon_prefix, hwmon_index); - rc = efx_mcdi_mon_add_attr( + efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_limit, i, type, max2); - if (rc) - goto fail; } } snprintf(name, sizeof(name), "%s%u_alarm", hwmon_prefix, hwmon_index); - rc = efx_mcdi_mon_add_attr( + efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_alarm, i, type, 0); - if (rc) - goto fail; if (type < ARRAY_SIZE(efx_mcdi_sensor_type) && efx_mcdi_sensor_type[type].label) { snprintf(name, sizeof(name), "%s%u_label", hwmon_prefix, hwmon_index); - rc = efx_mcdi_mon_add_attr( + efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_label, i, type, 0); - if (rc) - goto fail; } } +hwmon_register: + hwmon->groups[0] = &hwmon->group; + hwmon->device = hwmon_device_register_with_groups(&efx->pci_dev->dev, + KBUILD_MODNAME, NULL, + hwmon->groups); + if (IS_ERR(hwmon->device)) { + rc = PTR_ERR(hwmon->device); + goto fail; + } + + return 0; + fail: efx_mcdi_mon_remove(efx); return rc; @@ -516,14 +501,11 @@ fail: void efx_mcdi_mon_remove(struct efx_nic *efx) { struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); - unsigned int i; - for (i = 0; i < hwmon->n_attrs; i++) - device_remove_file(&efx->pci_dev->dev, - &hwmon->attrs[i].dev_attr); - kfree(hwmon->attrs); if (hwmon->device) hwmon_device_unregister(hwmon->device); + kfree(hwmon->attrs); + kfree(hwmon->group.attrs); efx_nic_free_buffer(efx, &hwmon->dma_buf); } -- cgit v1.2.3 From f5e0d34382e18f396d7673a84df8e3342bea7eb6 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 28 Nov 2013 18:01:38 +0100 Subject: team: fix master carrier set when user linkup is enabled When user linkup is enabled and user sets linkup of individual port, we need to recompute linkup (carrier) of master interface so the change is reflected. Fix this by calling __team_carrier_check() which does the needed work. Please apply to all stable kernels as well. Thanks. Reported-by: Jan Tluka Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 34b0de09d881..736050d6b451 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1366,6 +1366,8 @@ static int team_user_linkup_option_get(struct team *team, return 0; } +static void __team_carrier_check(struct team *team); + static int team_user_linkup_option_set(struct team *team, struct team_gsetter_ctx *ctx) { @@ -1373,6 +1375,7 @@ static int team_user_linkup_option_set(struct team *team, port->user.linkup = ctx->data.bool_val; team_refresh_port_linkup(port); + __team_carrier_check(port->team); return 0; } @@ -1392,6 +1395,7 @@ static int team_user_linkup_en_option_set(struct team *team, port->user.linkup_enabled = ctx->data.bool_val; team_refresh_port_linkup(port); + __team_carrier_check(port->team); return 0; } -- cgit v1.2.3 From 42ce4126d8bc2e128e1f207cf79bb0623fac498f Mon Sep 17 00:00:00 2001 From: Akeem G Abodunrin Date: Fri, 8 Nov 2013 01:54:07 +0000 Subject: igb: Fixed Wake On LAN support This patch fixes Wake on LAN being reported as supported on some Ethernet ports, in contrary to Hardware capability. Signed-off-by: Akeem G Abodunrin Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_ethtool.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index b0f3666b1d7f..c3143da497c8 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -2062,14 +2062,15 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { struct igb_adapter *adapter = netdev_priv(netdev); - wol->supported = WAKE_UCAST | WAKE_MCAST | - WAKE_BCAST | WAKE_MAGIC | - WAKE_PHY; wol->wolopts = 0; if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED)) return; + wol->supported = WAKE_UCAST | WAKE_MCAST | + WAKE_BCAST | WAKE_MAGIC | + WAKE_PHY; + /* apply any specific unsupported masks here */ switch (adapter->hw.device_id) { default: -- cgit v1.2.3 From 6a7d64e3e09e11181a07a2e8cd6af5d6355133be Mon Sep 17 00:00:00 2001 From: yzhu1 Date: Sat, 23 Nov 2013 07:07:40 +0000 Subject: e1000: prevent oops when adapter is being closed and reset simultaneously This change is based on a similar change made to e1000e support in commit bb9e44d0d0f4 ("e1000e: prevent oops when adapter is being closed and reset simultaneously"). The same issue has also been observed on the older e1000 cards. Here, we have increased the RESET_COUNT value to 50 because there are too many accesses to e1000 nic on stress tests to e1000 nic, it is not enough to set RESET_COUT 25. Experimentation has shown that it is enough to set RESET_COUNT 50. Signed-off-by: yzhu1 Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000.h | 5 +++++ drivers/net/ethernet/intel/e1000/e1000_main.c | 9 +++++++++ 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 58c147271a36..e4093d1f64cb 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -83,6 +83,11 @@ struct e1000_adapter; #define E1000_MAX_INTR 10 +/* + * Count for polling __E1000_RESET condition every 10-20msec. + */ +#define E1000_CHECK_RESET_COUNT 50 + /* TX/RX descriptor defines */ #define E1000_DEFAULT_TXD 256 #define E1000_MAX_TXD 256 diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index e38622825fa7..c0f52174e4c8 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1440,6 +1440,10 @@ static int e1000_close(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + int count = E1000_CHECK_RESET_COUNT; + + while (test_bit(__E1000_RESETTING, &adapter->flags) && count--) + usleep_range(10000, 20000); WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags)); e1000_down(adapter); @@ -4963,6 +4967,11 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) netif_device_detach(netdev); if (netif_running(netdev)) { + int count = E1000_CHECK_RESET_COUNT; + + while (test_bit(__E1000_RESETTING, &adapter->flags) && count--) + usleep_range(10000, 20000); + WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags)); e1000_down(adapter); } -- cgit v1.2.3 From b2f963bfaebadc9117b29f806630ea3bcaec403d Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Sat, 23 Nov 2013 07:17:56 +0000 Subject: e1000: fix lockdep warning in e1000_reset_task The patch fixes the following lockdep warning, which is 100% reproducible on network restart: ====================================================== [ INFO: possible circular locking dependency detected ] 3.12.0+ #47 Tainted: GF ------------------------------------------------------- kworker/1:1/27 is trying to acquire lock: ((&(&adapter->watchdog_task)->work)){+.+...}, at: [] flush_work+0x0/0x70 but task is already holding lock: (&adapter->mutex){+.+...}, at: [] e1000_reset_task+0x4a/0xa0 [e1000] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&adapter->mutex){+.+...}: [] lock_acquire+0x9d/0x120 [] mutex_lock_nested+0x4c/0x390 [] e1000_watchdog+0x7d/0x5b0 [e1000] [] process_one_work+0x1d2/0x510 [] worker_thread+0x120/0x3a0 [] kthread+0xee/0x110 [] ret_from_fork+0x7c/0xb0 -> #0 ((&(&adapter->watchdog_task)->work)){+.+...}: [] __lock_acquire+0x1710/0x1810 [] lock_acquire+0x9d/0x120 [] flush_work+0x3b/0x70 [] __cancel_work_timer+0x98/0x140 [] cancel_delayed_work_sync+0x13/0x20 [] e1000_down_and_stop+0x3c/0x60 [e1000] [] e1000_down+0x131/0x220 [e1000] [] e1000_reset_task+0x52/0xa0 [e1000] [] process_one_work+0x1d2/0x510 [] worker_thread+0x120/0x3a0 [] kthread+0xee/0x110 [] ret_from_fork+0x7c/0xb0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&adapter->mutex); lock((&(&adapter->watchdog_task)->work)); lock(&adapter->mutex); lock((&(&adapter->watchdog_task)->work)); *** DEADLOCK *** 3 locks held by kworker/1:1/27: #0: (events){.+.+.+}, at: [] process_one_work+0x166/0x510 #1: ((&adapter->reset_task)){+.+...}, at: [] process_one_work+0x166/0x510 #2: (&adapter->mutex){+.+...}, at: [] e1000_reset_task+0x4a/0xa0 [e1000] stack backtrace: CPU: 1 PID: 27 Comm: kworker/1:1 Tainted: GF 3.12.0+ #47 Hardware name: System manufacturer System Product Name/P5B-VM SE, BIOS 0501 05/31/2007 Workqueue: events e1000_reset_task [e1000] ffffffff820f6000 ffff88007b9dba98 ffffffff816b54a2 0000000000000002 ffffffff820f5e50 ffff88007b9dbae8 ffffffff810ba936 ffff88007b9dbac8 ffff88007b9dbb48 ffff88007b9d8f00 ffff88007b9d8780 ffff88007b9d8f00 Call Trace: [] dump_stack+0x49/0x5f [] print_circular_bug+0x216/0x310 [] __lock_acquire+0x1710/0x1810 [] ? __flush_work+0x250/0x250 [] lock_acquire+0x9d/0x120 [] ? __flush_work+0x250/0x250 [] flush_work+0x3b/0x70 [] ? __flush_work+0x250/0x250 [] __cancel_work_timer+0x98/0x140 [] cancel_delayed_work_sync+0x13/0x20 [] e1000_down_and_stop+0x3c/0x60 [e1000] [] e1000_down+0x131/0x220 [e1000] [] e1000_reset_task+0x52/0xa0 [e1000] [] process_one_work+0x1d2/0x510 [] ? process_one_work+0x166/0x510 [] worker_thread+0x120/0x3a0 [] ? manage_workers+0x2c0/0x2c0 [] kthread+0xee/0x110 [] ? __init_kthread_worker+0x70/0x70 [] ret_from_fork+0x7c/0xb0 [] ? __init_kthread_worker+0x70/0x70 == The issue background == The problem occurs, because e1000_down(), which is called under adapter->mutex by e1000_reset_task(), tries to synchronously cancel e1000 auxiliary works (reset_task, watchdog_task, phy_info_task, fifo_stall_task), which take adapter->mutex in their handlers. So the question is what does adapter->mutex protect there? The adapter->mutex was introduced by commit 0ef4ee ("e1000: convert to private mutex from rtnl") as a replacement for rtnl_lock() taken in the asynchronous handlers. It targeted on fixing a similar lockdep warning issued when e1000_down() was called under rtnl_lock(), and it fixed it, but unfortunately it introduced the lockdep warning described above. Anyway, that said the source of this bug is that the asynchronous works were made to take rtnl_lock() some time ago, so let's look deeper and find why it was added there. The rtnl_lock() was added to asynchronous handlers by commit 338c15 ("e1000: fix occasional panic on unload") in order to prevent asynchronous handlers from execution after the module is unloaded (e1000_down() is called) as it follows from the comment to the commit: > Net drivers in general have an issue where timers fired > by mod_timer or work threads with schedule_work are running > outside of the rtnl_lock. > > With no other lock protection these routines are vulnerable > to races with driver unload or reset paths. > > The longer term solution to this might be a redesign with > safer locks being taken in the driver to guarantee no > reentrance, but for now a safe and effective fix is > to take the rtnl_lock in these routines. I'm not sure if this locking scheme fixed the problem or just made it unlikely, although I incline to the latter. Anyway, this was long time ago when e1000 auxiliary works were implemented as timers scheduling real work handlers in their routines. The e1000_down() function only canceled the timers, but left the real handlers running if they were running, which could result in work execution after module unload. Today, the e1000 driver uses sane delayed works instead of the pair timer+work to implement its delayed asynchronous handlers, and the e1000_down() synchronously cancels all the works so that the problem that commit 338c15 tried to cope with disappeared, and we don't need any locks in the handlers any more. Moreover, any locking there can potentially result in a deadlock. So, this patch reverts commits 0ef4ee and 338c15. Fixes: 0ef4eedc2e98 ("e1000: convert to private mutex from rtnl") Fixes: 338c15e470d8 ("e1000: fix occasional panic on unload") Cc: Tushar Dave Cc: Patrick McHardy Signed-off-by: Vladimir Davydov Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000.h | 2 -- drivers/net/ethernet/intel/e1000/e1000_main.c | 36 +++------------------------ 2 files changed, 3 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index e4093d1f64cb..f9313b36c887 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -317,8 +317,6 @@ struct e1000_adapter { struct delayed_work watchdog_task; struct delayed_work fifo_stall_task; struct delayed_work phy_info_task; - - struct mutex mutex; }; enum e1000_state_t { diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index c0f52174e4c8..619b0cb60f2f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -544,21 +544,8 @@ void e1000_down(struct e1000_adapter *adapter) e1000_clean_all_rx_rings(adapter); } -static void e1000_reinit_safe(struct e1000_adapter *adapter) -{ - while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) - msleep(1); - mutex_lock(&adapter->mutex); - e1000_down(adapter); - e1000_up(adapter); - mutex_unlock(&adapter->mutex); - clear_bit(__E1000_RESETTING, &adapter->flags); -} - void e1000_reinit_locked(struct e1000_adapter *adapter) { - /* if rtnl_lock is not held the call path is bogus */ - ASSERT_RTNL(); WARN_ON(in_interrupt()); while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) msleep(1); @@ -1316,7 +1303,6 @@ static int e1000_sw_init(struct e1000_adapter *adapter) e1000_irq_disable(adapter); spin_lock_init(&adapter->stats_lock); - mutex_init(&adapter->mutex); set_bit(__E1000_DOWN, &adapter->flags); @@ -2329,11 +2315,8 @@ static void e1000_update_phy_info_task(struct work_struct *work) struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, phy_info_task.work); - if (test_bit(__E1000_DOWN, &adapter->flags)) - return; - mutex_lock(&adapter->mutex); + e1000_phy_get_info(&adapter->hw, &adapter->phy_info); - mutex_unlock(&adapter->mutex); } /** @@ -2349,9 +2332,6 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) struct net_device *netdev = adapter->netdev; u32 tctl; - if (test_bit(__E1000_DOWN, &adapter->flags)) - return; - mutex_lock(&adapter->mutex); if (atomic_read(&adapter->tx_fifo_stall)) { if ((er32(TDT) == er32(TDH)) && (er32(TDFT) == er32(TDFH)) && @@ -2372,7 +2352,6 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) schedule_delayed_work(&adapter->fifo_stall_task, 1); } } - mutex_unlock(&adapter->mutex); } bool e1000_has_link(struct e1000_adapter *adapter) @@ -2426,10 +2405,6 @@ static void e1000_watchdog(struct work_struct *work) struct e1000_tx_ring *txdr = adapter->tx_ring; u32 link, tctl; - if (test_bit(__E1000_DOWN, &adapter->flags)) - return; - - mutex_lock(&adapter->mutex); link = e1000_has_link(adapter); if ((netif_carrier_ok(netdev)) && link) goto link_up; @@ -2520,7 +2495,7 @@ link_up: adapter->tx_timeout_count++; schedule_work(&adapter->reset_task); /* exit immediately since reset is imminent */ - goto unlock; + return; } } @@ -2548,9 +2523,6 @@ link_up: /* Reschedule the task */ if (!test_bit(__E1000_DOWN, &adapter->flags)) schedule_delayed_work(&adapter->watchdog_task, 2 * HZ); - -unlock: - mutex_unlock(&adapter->mutex); } enum latency_range { @@ -3499,10 +3471,8 @@ static void e1000_reset_task(struct work_struct *work) struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, reset_task); - if (test_bit(__E1000_DOWN, &adapter->flags)) - return; e_err(drv, "Reset adapter\n"); - e1000_reinit_safe(adapter); + e1000_reinit_locked(adapter); } /** -- cgit v1.2.3 From 74a1b1ea8a30b035aaad833bbd6b9263e72acfac Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Sat, 23 Nov 2013 07:18:01 +0000 Subject: e1000: fix possible reset_task running after adapter down On e1000_down(), we should ensure every asynchronous work is canceled before proceeding. Since the watchdog_task can schedule other works apart from itself, it should be stopped first, but currently it is stopped after the reset_task. This can result in the following race leading to the reset_task running after the module unload: e1000_down_and_stop(): e1000_watchdog(): ---------------------- ----------------- cancel_work_sync(reset_task) schedule_work(reset_task) cancel_delayed_work_sync(watchdog_task) The patch moves cancel_delayed_work_sync(watchdog_task) at the beginning of e1000_down_and_stop() thus ensuring the race is impossible. Cc: Tushar Dave Cc: Patrick McHardy Signed-off-by: Vladimir Davydov Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 619b0cb60f2f..46e6544ed1b7 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -494,13 +494,20 @@ static void e1000_down_and_stop(struct e1000_adapter *adapter) { set_bit(__E1000_DOWN, &adapter->flags); - /* Only kill reset task if adapter is not resetting */ - if (!test_bit(__E1000_RESETTING, &adapter->flags)) - cancel_work_sync(&adapter->reset_task); - cancel_delayed_work_sync(&adapter->watchdog_task); + + /* + * Since the watchdog task can reschedule other tasks, we should cancel + * it first, otherwise we can run into the situation when a work is + * still running after the adapter has been turned down. + */ + cancel_delayed_work_sync(&adapter->phy_info_task); cancel_delayed_work_sync(&adapter->fifo_stall_task); + + /* Only kill reset task if adapter is not resetting */ + if (!test_bit(__E1000_RESETTING, &adapter->flags)) + cancel_work_sync(&adapter->reset_task); } void e1000_down(struct e1000_adapter *adapter) -- cgit v1.2.3 From ae72c8d068b3440c0b45df284303794cfbc0f4f2 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 9 Nov 2013 07:11:26 +0000 Subject: ixgbe: ixgbe_fwd_ring_down needs to be static When compiling with -Wstrict-prototypes gcc catches a static I missed. ./ixgbe_main.c:4254: warning: no previous prototype for 'ixgbe_fwd_ring_down' Reported-by: Phillip Schmitt Signed-off-by: John Fastabend Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 0c55079ebee3..ad9d67095d52 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -4251,8 +4251,8 @@ static void ixgbe_disable_fwd_ring(struct ixgbe_fwd_adapter *vadapter, rx_ring->l2_accel_priv = NULL; } -int ixgbe_fwd_ring_down(struct net_device *vdev, - struct ixgbe_fwd_adapter *accel) +static int ixgbe_fwd_ring_down(struct net_device *vdev, + struct ixgbe_fwd_adapter *accel) { struct ixgbe_adapter *adapter = accel->real_adapter; unsigned int rxbase = accel->rx_base_queue; -- cgit v1.2.3 From 8bf1264d2f12c6fa8645d097275568c1b62c246c Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 12 Nov 2013 12:13:29 +0000 Subject: ixgbe: turn NETIF_F_HW_L2FW_DOFFLOAD off by default NETIF_F_HW_L2FW_DOFFLOAD allows upper layer net devices such as macvlan to use queues in the hardware to directly submit and receive skbs. This creates a subtle change in the datapath though. One change being the skb may no longer use the root devices qdisc. Because users may not expect this we can't enable the feature by default unless the hardware can offload all the software functionality above it. So for now disable it by default and let users opt in. Signed-off-by: John Fastabend Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index ad9d67095d52..cc06854296a3 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7986,10 +7986,9 @@ skip_sriov: NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXHASH | - NETIF_F_RXCSUM | - NETIF_F_HW_L2FW_DOFFLOAD; + NETIF_F_RXCSUM; - netdev->hw_features = netdev->features; + netdev->hw_features = netdev->features | NETIF_F_HW_L2FW_DOFFLOAD; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: -- cgit v1.2.3 From 8821754704a661623083a9dedf425114199600ba Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Sat, 23 Nov 2013 03:19:19 +0000 Subject: ixgbe: Make ixgbe_identify_qsfp_module_generic static Correct a namespace complaint by making the function static and moving the prototype into the .c file. Signed-off-by: Mark Rustad Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 3 ++- drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index e4c676006be9..39217e5ff7dc 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -46,6 +46,7 @@ static bool ixgbe_get_i2c_data(u32 *i2cctl); static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); +static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw); /** * ixgbe_identify_phy_generic - Get physical layer module @@ -1164,7 +1165,7 @@ err_read_i2c_eeprom: * * Searches for and identifies the QSFP module and assigns appropriate PHY type **/ -s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) +static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) { struct ixgbe_adapter *adapter = hw->back; s32 status = IXGBE_ERR_PHY_ADDR_INVALID; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h index aae900a256da..fffcbdd2bf0e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h @@ -145,7 +145,6 @@ s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); -s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw); s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, u16 *data_offset); -- cgit v1.2.3 From 99e872ae1eacb560152c0123cf1cef571569e681 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 29 Nov 2013 10:02:19 +0100 Subject: virtio_net: Fixed a trivial typo (fitler --> filter) "MAC filter" sounds more reasonable than "MAC fitler". Signed-off-by: Thomas Huth Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 7bab4de658a9..acda66169973 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1084,7 +1084,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC, VIRTIO_NET_CTRL_MAC_TABLE_SET, sg, NULL)) - dev_warn(&dev->dev, "Failed to set MAC fitler table.\n"); + dev_warn(&dev->dev, "Failed to set MAC filter table.\n"); kfree(buf); } -- cgit v1.2.3 From 2e311fbabdc23b7eaec77313dc3b9a151a5407b5 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 23 Sep 2013 13:33:41 -0500 Subject: [SCSI] hpsa: do not discard scsi status on aborted commands We inadvertantly discarded the scsi status for aborted commands. For some commands (e.g. reads from tape drives) these can't be retried, and if we discarded the scsi status, the scsi mid layer couldn't notice anything was wrong and the error was not reported. Signed-off-by: Stephen M. Cameron Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/hpsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 2336beff7a48..595a2a711548 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1289,7 +1289,7 @@ static void complete_scsi_command(struct CommandList *cp) "has check condition: aborted command: " "ASC: 0x%x, ASCQ: 0x%x\n", cp, asc, ascq); - cmd->result = DID_SOFT_ERROR << 16; + cmd->result |= DID_SOFT_ERROR << 16; break; } /* Must be some other type of check condition */ -- cgit v1.2.3 From 88bf6d62db4393fa03a58bada9d746312d5b496f Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 1 Nov 2013 11:02:25 -0500 Subject: [SCSI] hpsa: return 0 from driver probe function on success, not 1 A return value of 1 is interpreted as an error. See pci_driver. in local_pci_probe(). If you're wondering how this ever could have worked, it's because it used to be the case that only return values less than zero were interpreted as failure. But even in the current kernel if the driver registers its various entry points with the kernel, and then returns a value which is interpreted as failure, those registrations aren't undone, so the driver still mostly works. However, the driver's remove function wouldn't be called on rmmod, and pci power management functions wouldn't work. In the case of Smart Array, since it has a battery backed cache (or else no cache) even if the driver is not shut down properly as long as there is no outstanding i/o, nothing too bad happens, which is why it took so long to notice. Requesting backport to stable because the change to pci-driver.c which requires driver probe functions to return 0 occurred between 2.6.35 and 2.6.36 (the pci power management breakage) and again between 3.7 and 3.8 (pci_dev->driver getting set to NULL in local_pci_probe() preventing driver remove function from being called on rmmod.) Signed-off-by: Stephen M. Cameron Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/hpsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 595a2a711548..20a5e6ecf945 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -4926,7 +4926,7 @@ reinit_after_soft_reset: hpsa_hba_inquiry(h); hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ start_controller_lockup_detector(h); - return 1; + return 0; clean4: hpsa_free_sg_chain_blocks(h); -- cgit v1.2.3 From 8fc3b9e9a229778e5af3aa453c44f1a3857ba769 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 28 Nov 2013 13:30:55 +0200 Subject: virtio_net: fix error handling for mergeable buffers Eric Dumazet noticed that if we encounter an error when processing a mergeable buffer, we don't dequeue all of the buffers from this packet, the result is almost sure to be loss of networking. Jason Wang noticed that we also leak a page and that we don't decrement the rq buf count, so we won't repost buffers (a resource leak). Fix both issues. Cc: Rusty Russell Cc: Michael Dalton Reported-by: Eric Dumazet Reported-by: Jason Wang Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 82 ++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index acda66169973..71a2eac7b039 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -299,35 +299,47 @@ static struct sk_buff *page_to_skb(struct receive_queue *rq, return skb; } -static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb) +static struct sk_buff *receive_mergeable(struct net_device *dev, + struct receive_queue *rq, + void *buf, + unsigned int len) { - struct skb_vnet_hdr *hdr = skb_vnet_hdr(head_skb); + struct skb_vnet_hdr *hdr = buf; + int num_buf = hdr->mhdr.num_buffers; + struct page *page = virt_to_head_page(buf); + int offset = buf - page_address(page); + struct sk_buff *head_skb = page_to_skb(rq, page, offset, len, + MERGE_BUFFER_LEN); struct sk_buff *curr_skb = head_skb; - char *buf; - struct page *page; - int num_buf, len, offset; - num_buf = hdr->mhdr.num_buffers; + if (unlikely(!curr_skb)) + goto err_skb; + while (--num_buf) { - int num_skb_frags = skb_shinfo(curr_skb)->nr_frags; + int num_skb_frags; + buf = virtqueue_get_buf(rq->vq, &len); if (unlikely(!buf)) { - pr_debug("%s: rx error: %d buffers missing\n", - head_skb->dev->name, hdr->mhdr.num_buffers); - head_skb->dev->stats.rx_length_errors++; - return -EINVAL; + pr_debug("%s: rx error: %d buffers out of %d missing\n", + dev->name, num_buf, hdr->mhdr.num_buffers); + dev->stats.rx_length_errors++; + goto err_buf; } if (unlikely(len > MERGE_BUFFER_LEN)) { pr_debug("%s: rx error: merge buffer too long\n", - head_skb->dev->name); + dev->name); len = MERGE_BUFFER_LEN; } + + page = virt_to_head_page(buf); + --rq->num; + + num_skb_frags = skb_shinfo(curr_skb)->nr_frags; if (unlikely(num_skb_frags == MAX_SKB_FRAGS)) { struct sk_buff *nskb = alloc_skb(0, GFP_ATOMIC); - if (unlikely(!nskb)) { - head_skb->dev->stats.rx_dropped++; - return -ENOMEM; - } + + if (unlikely(!nskb)) + goto err_skb; if (curr_skb == head_skb) skb_shinfo(curr_skb)->frag_list = nskb; else @@ -341,8 +353,7 @@ static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb) head_skb->len += len; head_skb->truesize += MERGE_BUFFER_LEN; } - page = virt_to_head_page(buf); - offset = buf - (char *)page_address(page); + offset = buf - page_address(page); if (skb_can_coalesce(curr_skb, num_skb_frags, page, offset)) { put_page(page); skb_coalesce_rx_frag(curr_skb, num_skb_frags - 1, @@ -351,9 +362,28 @@ static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb) skb_add_rx_frag(curr_skb, num_skb_frags, page, offset, len, MERGE_BUFFER_LEN); } + } + + return head_skb; + +err_skb: + put_page(page); + while (--num_buf) { + buf = virtqueue_get_buf(rq->vq, &len); + if (unlikely(!buf)) { + pr_debug("%s: rx error: %d buffers missing\n", + dev->name, num_buf); + dev->stats.rx_length_errors++; + break; + } + page = virt_to_head_page(buf); + put_page(page); --rq->num; } - return 0; +err_buf: + dev->stats.rx_dropped++; + dev_kfree_skb(head_skb); + return NULL; } static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len) @@ -382,19 +412,9 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len) len -= sizeof(struct virtio_net_hdr); skb_trim(skb, len); } else if (vi->mergeable_rx_bufs) { - struct page *page = virt_to_head_page(buf); - skb = page_to_skb(rq, page, - (char *)buf - (char *)page_address(page), - len, MERGE_BUFFER_LEN); - if (unlikely(!skb)) { - dev->stats.rx_dropped++; - put_page(page); + skb = receive_mergeable(dev, rq, buf, len); + if (unlikely(!skb)) return; - } - if (receive_mergeable(rq, skb)) { - dev_kfree_skb(skb); - return; - } } else { page = buf; skb = page_to_skb(rq, page, 0, len, PAGE_SIZE); -- cgit v1.2.3 From f121159d72091f25afb22007c833e60a6845e912 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 28 Nov 2013 13:30:59 +0200 Subject: virtio_net: make all RX paths handle erors consistently receive mergeable now handles errors internally. Do same for big and small packet paths, otherwise the logic is too hard to follow. Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 54 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 71a2eac7b039..916241d16c67 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -299,6 +299,35 @@ static struct sk_buff *page_to_skb(struct receive_queue *rq, return skb; } +static struct sk_buff *receive_small(void *buf, unsigned int len) +{ + struct sk_buff * skb = buf; + + len -= sizeof(struct virtio_net_hdr); + skb_trim(skb, len); + + return skb; +} + +static struct sk_buff *receive_big(struct net_device *dev, + struct receive_queue *rq, + void *buf, + unsigned int len) +{ + struct page *page = buf; + struct sk_buff *skb = page_to_skb(rq, page, 0, len, PAGE_SIZE); + + if (unlikely(!skb)) + goto err; + + return skb; + +err: + dev->stats.rx_dropped++; + give_pages(rq, page); + return NULL; +} + static struct sk_buff *receive_mergeable(struct net_device *dev, struct receive_queue *rq, void *buf, @@ -392,7 +421,6 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len) struct net_device *dev = vi->dev; struct virtnet_stats *stats = this_cpu_ptr(vi->stats); struct sk_buff *skb; - struct page *page; struct skb_vnet_hdr *hdr; if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { @@ -407,23 +435,15 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len) return; } - if (!vi->mergeable_rx_bufs && !vi->big_packets) { - skb = buf; - len -= sizeof(struct virtio_net_hdr); - skb_trim(skb, len); - } else if (vi->mergeable_rx_bufs) { + if (vi->mergeable_rx_bufs) skb = receive_mergeable(dev, rq, buf, len); - if (unlikely(!skb)) - return; - } else { - page = buf; - skb = page_to_skb(rq, page, 0, len, PAGE_SIZE); - if (unlikely(!skb)) { - dev->stats.rx_dropped++; - give_pages(rq, page); - return; - } - } + else if (vi->big_packets) + skb = receive_big(dev, rq, buf, len); + else + skb = receive_small(buf, len); + + if (unlikely(!skb)) + return; hdr = skb_vnet_hdr(skb); -- cgit v1.2.3 From 833846e8fa0c51fb3e47bca8adfdd7b10643b737 Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Sun, 1 Dec 2013 14:19:34 +0200 Subject: net/mlx4_en: Remove selftest TX queues empty condition Remove waiting for TX queues to become empty during selftest. This check is not necessary for any purpose, and might put the driver into an infinite loop. Signed-off-by: Eugenia Emantayev Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c index 40626690e8a8..c11d063473e5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c @@ -140,7 +140,6 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; - struct mlx4_en_tx_ring *tx_ring; int i, carrier_ok; memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST); @@ -150,16 +149,10 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf) carrier_ok = netif_carrier_ok(dev); netif_carrier_off(dev); -retry_tx: /* Wait until all tx queues are empty. * there should not be any additional incoming traffic * since we turned the carrier off */ msleep(200); - for (i = 0; i < priv->tx_ring_num && carrier_ok; i++) { - tx_ring = priv->tx_ring[i]; - if (tx_ring->prod != (tx_ring->cons + tx_ring->last_nr_txbb)) - goto retry_tx; - } if (priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UC_LOOPBACK) { -- cgit v1.2.3 From a9e51fe5e610dce8110ec383f50b96eeadd568e0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 1 Dec 2013 19:41:06 +0800 Subject: pinctrl: abx500: Fix header file include guard Fix a trivial typo. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-abx500.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-abx500.h b/drivers/pinctrl/pinctrl-abx500.h index eeca8f973999..82293806e842 100644 --- a/drivers/pinctrl/pinctrl-abx500.h +++ b/drivers/pinctrl/pinctrl-abx500.h @@ -1,4 +1,4 @@ -#ifndef PINCTRL_PINCTRL_ABx5O0_H +#ifndef PINCTRL_PINCTRL_ABx500_H #define PINCTRL_PINCTRL_ABx500_H /* Package definitions */ -- cgit v1.2.3 From 94f33c16f2108ad02599de2459c903ad45d825dc Mon Sep 17 00:00:00 2001 From: Nikith Ganigarakoppal Date: Wed, 13 Nov 2013 15:35:23 +0530 Subject: [SCSI] pm80xx: Module author addition Signed-off-by: Nikith.Ganigarakoppal@pmcs.com Signed-off-by: Anandkumar.Santhanam@pmcs.com Reviewed-by: Jack Wang Signed-off-by: James Bottomley --- drivers/scsi/pm8001/pm8001_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 34f5f5ffef05..03d3ef41f449 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -1169,6 +1169,7 @@ module_exit(pm8001_exit); MODULE_AUTHOR("Jack Wang "); MODULE_AUTHOR("Anand Kumar Santhanam "); MODULE_AUTHOR("Sangeetha Gnanasekaran "); +MODULE_AUTHOR("Nikith Ganigarakoppal "); MODULE_DESCRIPTION( "PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 " "SAS/SATA controller driver"); -- cgit v1.2.3 From 34a9b81b476ea0fa7a2e7ec642830f690eb093aa Mon Sep 17 00:00:00 2001 From: Nikith Ganigarakoppal Date: Wed, 30 Oct 2013 16:13:22 +0530 Subject: [SCSI] pm80xx: Fix for direct attached device. In case of direct attached SATA device delay is not enough. It will give crash for set device state command response and wait_for_completion is the best solution for this. Signed-off-by: Nikith.Ganigarakoppal@pmcs.com Signed-off-by: Anandkumar.Santhanam@pmcs.com Reviewed-by: Jack Wang Signed-off-by: James Bottomley --- drivers/scsi/pm8001/pm8001_sas.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index f4eb18e51631..f50ac44b950e 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -1098,15 +1098,17 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun) struct pm8001_tmf_task tmf_task; struct pm8001_device *pm8001_dev = dev->lldd_dev; struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev); + DECLARE_COMPLETION_ONSTACK(completion_setstate); if (dev_is_sata(dev)) { struct sas_phy *phy = sas_get_local_phy(dev); rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , dev, 1, 0); rc = sas_phy_reset(phy, 1); sas_put_local_phy(phy); + pm8001_dev->setds_completion = &completion_setstate; rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, pm8001_dev, 0x01); - msleep(2000); + wait_for_completion(&completion_setstate); } else { tmf_task.tmf = TMF_LU_RESET; rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task); -- cgit v1.2.3 From 7d029005484a6125a91a075518b9cfde830bc709 Mon Sep 17 00:00:00 2001 From: Nikith Ganigarakoppal Date: Wed, 30 Oct 2013 16:23:47 +0530 Subject: [SCSI] pm80xx: Resetting the phy state. Setting the phy state for hard reset response. After sending hard reset for a device ,phy down event sets the phy state to zero but for phy up event it will not set the phy state again.This will cause problem to successive hard resets. Signed-off-by: Nikith.Ganigarakoppal@pmcs.com Signed-off-by: Anandkumar.Santhanam@pmcs.com Reviewed-by: Jack Wang Signed-off-by: James Bottomley --- drivers/scsi/pm8001/pm8001_hwi.c | 2 ++ drivers/scsi/pm8001/pm8001_hwi.h | 4 ++++ drivers/scsi/pm8001/pm80xx_hwi.c | 2 ++ drivers/scsi/pm8001/pm80xx_hwi.h | 2 ++ 4 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index f16ece91b94a..0a1296a87d66 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3403,6 +3403,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPC; PM8001_MSG_DBG(pm8001_ha, pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", port_id, phy_id)); @@ -3483,6 +3484,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," " phy id = %d\n", port_id, phy_id)); port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPC; port->port_attached = 1; pm8001_get_lrate_mode(phy, link_rate); phy->phy_type |= PORT_TYPE_SATA; diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index 6d91e2446542..e4867e690c84 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h @@ -131,6 +131,10 @@ #define LINKRATE_30 (0x02 << 8) #define LINKRATE_60 (0x04 << 8) +/* for phy state */ + +#define PHY_STATE_LINK_UP_SPC 0x1 + /* for new SPC controllers MEMBASE III is shared between BIOS and DATA */ #define GSM_SM_BASE 0x4F0000 struct mpi_msg_hdr{ diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 8987b1706216..c950dc5c9943 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -2894,6 +2894,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPCV; PM8001_MSG_DBG(pm8001_ha, pm8001_printk( "portid:%d; phyid:%d; linkrate:%d; " "portstate:%x; devicetype:%x\n", @@ -2978,6 +2979,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) port_id, phy_id, link_rate, portstate)); port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPCV; port->port_attached = 1; pm8001_get_lrate_mode(phy, link_rate); phy->phy_type |= PORT_TYPE_SATA; diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h index c86816bea424..9970a385795d 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.h +++ b/drivers/scsi/pm8001/pm80xx_hwi.h @@ -215,6 +215,8 @@ #define SAS_DOPNRJT_RTRY_TMO 128 #define SAS_COPNRJT_RTRY_TMO 128 +/* for phy state */ +#define PHY_STATE_LINK_UP_SPCV 0x2 /* Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128 -- cgit v1.2.3 From 6cd60b37f72b2d15b8983431546af50b7064935d Mon Sep 17 00:00:00 2001 From: Nikith Ganigarakoppal Date: Mon, 11 Nov 2013 15:28:14 +0530 Subject: [SCSI] pm80xx: Tasklets synchronization fix. When multiple vectors are used, the vector variable is over written, resulting in unhandled operation for those vectors. This fix prevents the problem by maitaining HBA instance and vector values for each irq. [jejb: checkpatch fixes] Signed-off-by: Nikith.Ganigarakoppal@pmcs.com Signed-off-by: Anandkumar.Santhanam@pmcs.com Reviewed-by: Jack Wang Signed-off-by: James Bottomley --- drivers/scsi/pm8001/pm8001_init.c | 90 ++++++++++++++++++++++----------------- drivers/scsi/pm8001/pm8001_sas.h | 9 ++-- 2 files changed, 58 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 03d3ef41f449..73a120d81b4d 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -175,20 +175,16 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha) static void pm8001_tasklet(unsigned long opaque) { struct pm8001_hba_info *pm8001_ha; - u32 vec; - pm8001_ha = (struct pm8001_hba_info *)opaque; + struct isr_param *irq_vector; + + irq_vector = (struct isr_param *)opaque; + pm8001_ha = irq_vector->drv_inst; if (unlikely(!pm8001_ha)) BUG_ON(1); - vec = pm8001_ha->int_vector; - PM8001_CHIP_DISP->isr(pm8001_ha, vec); + PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id); } #endif -static struct pm8001_hba_info *outq_to_hba(u8 *outq) -{ - return container_of((outq - *outq), struct pm8001_hba_info, outq[0]); -} - /** * pm8001_interrupt_handler_msix - main MSIX interrupt handler. * It obtains the vector number and calls the equivalent bottom @@ -198,18 +194,20 @@ static struct pm8001_hba_info *outq_to_hba(u8 *outq) */ static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque) { - struct pm8001_hba_info *pm8001_ha = outq_to_hba(opaque); - u8 outq = *(u8 *)opaque; + struct isr_param *irq_vector; + struct pm8001_hba_info *pm8001_ha; irqreturn_t ret = IRQ_HANDLED; + irq_vector = (struct isr_param *)opaque; + pm8001_ha = irq_vector->drv_inst; + if (unlikely(!pm8001_ha)) return IRQ_NONE; if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) return IRQ_NONE; - pm8001_ha->int_vector = outq; #ifdef PM8001_USE_TASKLET - tasklet_schedule(&pm8001_ha->tasklet); + tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id]); #else - ret = PM8001_CHIP_DISP->isr(pm8001_ha, outq); + ret = PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id); #endif return ret; } @@ -230,9 +228,8 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id) if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) return IRQ_NONE; - pm8001_ha->int_vector = 0; #ifdef PM8001_USE_TASKLET - tasklet_schedule(&pm8001_ha->tasklet); + tasklet_schedule(&pm8001_ha->tasklet[0]); #else ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0); #endif @@ -457,7 +454,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, { struct pm8001_hba_info *pm8001_ha; struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); - + int j; pm8001_ha = sha->lldd_ha; if (!pm8001_ha) @@ -480,12 +477,14 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->iomb_size = IOMB_SIZE_SPC; #ifdef PM8001_USE_TASKLET - /** - * default tasklet for non msi-x interrupt handler/first msi-x - * interrupt handler - **/ - tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet, - (unsigned long)pm8001_ha); + /* Tasklet for non msi-x interrupt handler */ + if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) + tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet, + (unsigned long)&(pm8001_ha->irq_vector[0])); + else + for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) + tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet, + (unsigned long)&(pm8001_ha->irq_vector[j])); #endif pm8001_ioremap(pm8001_ha); if (!pm8001_alloc(pm8001_ha, ent)) @@ -733,19 +732,20 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) "pci_enable_msix request ret:%d no of intr %d\n", rc, pm8001_ha->number_of_intr)); - for (i = 0; i < number_of_intr; i++) - pm8001_ha->outq[i] = i; for (i = 0; i < number_of_intr; i++) { snprintf(intr_drvname[i], sizeof(intr_drvname[0]), DRV_NAME"%d", i); + pm8001_ha->irq_vector[i].irq_id = i; + pm8001_ha->irq_vector[i].drv_inst = pm8001_ha; + if (request_irq(pm8001_ha->msix_entries[i].vector, pm8001_interrupt_handler_msix, flag, - intr_drvname[i], &pm8001_ha->outq[i])) { + intr_drvname[i], &(pm8001_ha->irq_vector[i]))) { for (j = 0; j < i; j++) free_irq( pm8001_ha->msix_entries[j].vector, - &pm8001_ha->outq[j]); + &(pm8001_ha->irq_vector[i])); pci_disable_msix(pm8001_ha->pdev); break; } @@ -907,7 +907,7 @@ static void pm8001_pci_remove(struct pci_dev *pdev) { struct sas_ha_struct *sha = pci_get_drvdata(pdev); struct pm8001_hba_info *pm8001_ha; - int i; + int i, j; pm8001_ha = sha->lldd_ha; sas_unregister_ha(sha); sas_remove_host(pm8001_ha->shost); @@ -921,13 +921,18 @@ static void pm8001_pci_remove(struct pci_dev *pdev) synchronize_irq(pm8001_ha->msix_entries[i].vector); for (i = 0; i < pm8001_ha->number_of_intr; i++) free_irq(pm8001_ha->msix_entries[i].vector, - &pm8001_ha->outq[i]); + &(pm8001_ha->irq_vector[i])); pci_disable_msix(pdev); #else free_irq(pm8001_ha->irq, sha); #endif #ifdef PM8001_USE_TASKLET - tasklet_kill(&pm8001_ha->tasklet); + /* For non-msix and msix interrupts */ + if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) + tasklet_kill(&pm8001_ha->tasklet[0]); + else + for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) + tasklet_kill(&pm8001_ha->tasklet[j]); #endif pm8001_free(pm8001_ha); kfree(sha->sas_phy); @@ -948,7 +953,7 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) { struct sas_ha_struct *sha = pci_get_drvdata(pdev); struct pm8001_hba_info *pm8001_ha; - int i; + int i, j; u32 device_state; pm8001_ha = sha->lldd_ha; flush_workqueue(pm8001_wq); @@ -964,13 +969,18 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) synchronize_irq(pm8001_ha->msix_entries[i].vector); for (i = 0; i < pm8001_ha->number_of_intr; i++) free_irq(pm8001_ha->msix_entries[i].vector, - &pm8001_ha->outq[i]); + &(pm8001_ha->irq_vector[i])); pci_disable_msix(pdev); #else free_irq(pm8001_ha->irq, sha); #endif #ifdef PM8001_USE_TASKLET - tasklet_kill(&pm8001_ha->tasklet); + /* For non-msix and msix interrupts */ + if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) + tasklet_kill(&pm8001_ha->tasklet[0]); + else + for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) + tasklet_kill(&pm8001_ha->tasklet[j]); #endif device_state = pci_choose_state(pdev, state); pm8001_printk("pdev=0x%p, slot=%s, entering " @@ -993,7 +1003,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev) struct sas_ha_struct *sha = pci_get_drvdata(pdev); struct pm8001_hba_info *pm8001_ha; int rc; - u8 i = 0; + u8 i = 0, j; u32 device_state; pm8001_ha = sha->lldd_ha; device_state = pdev->current_state; @@ -1033,10 +1043,14 @@ static int pm8001_pci_resume(struct pci_dev *pdev) if (rc) goto err_out_disable; #ifdef PM8001_USE_TASKLET - /* default tasklet for non msi-x interrupt handler/first msi-x - * interrupt handler */ - tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet, - (unsigned long)pm8001_ha); + /* Tasklet for non msi-x interrupt handler */ + if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) + tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet, + (unsigned long)&(pm8001_ha->irq_vector[0])); + else + for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) + tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet, + (unsigned long)&(pm8001_ha->irq_vector[j])); #endif PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0); if (pm8001_ha->chip_id != chip_8001) { diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 6037d477a183..6c5fd5ee22d3 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -466,6 +466,10 @@ struct pm8001_hba_memspace { u64 membase; u32 memsize; }; +struct isr_param { + struct pm8001_hba_info *drv_inst; + u32 irq_id; +}; struct pm8001_hba_info { char name[PM8001_NAME_LENGTH]; struct list_head list; @@ -519,14 +523,13 @@ struct pm8001_hba_info { int number_of_intr;/*will be used in remove()*/ #endif #ifdef PM8001_USE_TASKLET - struct tasklet_struct tasklet; + struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC]; #endif u32 logging_level; u32 fw_status; u32 smp_exp_mode; - u32 int_vector; const struct firmware *fw_image; - u8 outq[PM8001_MAX_MSIX_VEC]; + struct isr_param irq_vector[PM8001_MAX_MSIX_VEC]; }; struct pm8001_work { -- cgit v1.2.3 From a1470c7bf3a4676e62e4c0fb204e339399eb5c59 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 15 Nov 2013 14:58:00 -0800 Subject: [SCSI] enclosure: fix WARN_ON in dual path device removing Bug report from: wenxiong@linux.vnet.ibm.com The issue is happened in dual controller configuration. We got the sysfs warnings when rmmod the ipr module. enclosure_unregister() in drivers/msic/enclosure.c, call device_unregister() for each componment deivce, device_unregister() ->device_del()->kobject_del() ->sysfs_remove_dir(). In sysfs_remove_dir(), set kobj->sd = NULL. For each componment device, enclosure_component_release()->enclosure_remove_links()->sysfs_remove_link() in which checking kobj->sd again, it has been set as NULL when doing device_unregister. So we saw all these sysfs WARNING. Tested-by: wenxiong@linux.vnet.ibm.com Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/misc/enclosure.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 0e8df41aaf14..2cf2bbc0b927 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -198,6 +198,13 @@ static void enclosure_remove_links(struct enclosure_component *cdev) { char name[ENCLOSURE_NAME_SIZE]; + /* + * In odd circumstances, like multipath devices, something else may + * already have removed the links, so check for this condition first. + */ + if (!cdev->dev->kobj.sd) + return; + enclosure_link_name(cdev, name); sysfs_remove_link(&cdev->dev->kobj, name); sysfs_remove_link(&cdev->cdev.kobj, "device"); -- cgit v1.2.3 From b65502879556d041b45104c6a35abbbba28c8f2d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 2 Dec 2013 11:50:37 -0800 Subject: uio: we cannot mmap unaligned page contents In commit 7314e613d5ff ("Fix a few incorrectly checked [io_]remap_pfn_range() calls") the uio driver started more properly checking the passed-in user mapping arguments against the size of the actual uio driver data. That in turn exposed that some driver authors apparently didn't realize that mmap can only work on a page granularity, and had tried to use it with smaller mappings, with the new size check catching that out. So since it's not just the user mmap() arguments that can be confused, make the uio mmap code also verify that the uio driver has the memory allocated at page boundaries in order for mmap to work. If the device memory isn't properly aligned, we return [ENODEV] The fildes argument refers to a file whose type is not supported by mmap(). as per the open group documentation on mmap. Reported-by: Holger Brunck Acked-by: Greg KH Signed-off-by: Linus Torvalds --- drivers/uio/uio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 67beb8444930..f7beb6eb40c7 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -653,6 +653,8 @@ static int uio_mmap_physical(struct vm_area_struct *vma) return -EINVAL; mem = idev->info->mem + mi; + if (mem->addr & ~PAGE_MASK) + return -ENODEV; if (vma->vm_end - vma->vm_start > mem->size) return -EINVAL; -- cgit v1.2.3 From aa1a6d6d74fff31060e08f6007037e6d807c8130 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 28 Nov 2013 01:06:38 -0800 Subject: leds: pwm: Fix for deferred probe in DT booted mode We need to make sure that the error code from devm_of_pwm_get() is the one the module returns in case of failure. Restructure the code to make this possible for DT booted case. With this patch the driver can ask for deferred probing when the board is booted with DT. Fixes for example omap4-sdp board's keyboard backlight led. Signed-off-by: Peter Ujfalusi Signed-off-by: Bryan Wu --- drivers/leds/leds-pwm.c | 53 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 2848171b8576..b31d8e99c419 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -82,22 +82,12 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds) (sizeof(struct led_pwm_data) * num_leds); } -static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) +static int led_pwm_create_of(struct platform_device *pdev, + struct led_pwm_priv *priv) { struct device_node *node = pdev->dev.of_node; struct device_node *child; - struct led_pwm_priv *priv; - int count, ret; - - /* count LEDs in this device, so we know how much to allocate */ - count = of_get_child_count(node); - if (!count) - return NULL; - - priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count), - GFP_KERNEL); - if (!priv) - return NULL; + int ret; for_each_child_of_node(node, child) { struct led_pwm_data *led_dat = &priv->leds[priv->num_leds]; @@ -109,6 +99,7 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) if (IS_ERR(led_dat->pwm)) { dev_err(&pdev->dev, "unable to request PWM for %s\n", led_dat->cdev.name); + ret = PTR_ERR(led_dat->pwm); goto err; } /* Get the period from PWM core when n*/ @@ -137,28 +128,36 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) priv->num_leds++; } - return priv; + return 0; err: while (priv->num_leds--) led_classdev_unregister(&priv->leds[priv->num_leds].cdev); - return NULL; + return ret; } static int led_pwm_probe(struct platform_device *pdev) { struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev); struct led_pwm_priv *priv; - int i, ret = 0; + int count, i; + int ret = 0; + + if (pdata) + count = pdata->num_leds; + else + count = of_get_child_count(pdev->dev.of_node); + + if (!count) + return -EINVAL; - if (pdata && pdata->num_leds) { - priv = devm_kzalloc(&pdev->dev, - sizeof_pwm_leds_priv(pdata->num_leds), - GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count), + GFP_KERNEL); + if (!priv) + return -ENOMEM; - for (i = 0; i < pdata->num_leds; i++) { + if (pdata) { + for (i = 0; i < count; i++) { struct led_pwm *cur_led = &pdata->leds[i]; struct led_pwm_data *led_dat = &priv->leds[i]; @@ -188,11 +187,11 @@ static int led_pwm_probe(struct platform_device *pdev) if (ret < 0) goto err; } - priv->num_leds = pdata->num_leds; + priv->num_leds = count; } else { - priv = led_pwm_create_of(pdev); - if (!priv) - return -ENODEV; + ret = led_pwm_create_of(pdev, priv); + if (ret) + return ret; } platform_set_drvdata(pdev, priv); -- cgit v1.2.3 From 5d27619498ab468e8c7e67844c640ad0915e8d85 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 28 Nov 2013 16:20:03 +0100 Subject: sh-pfc: r8a7740: Fix pin bias setup When computing the pin configuration register offset the bias setup code erroneously compares the pin number range with the loop index instead of the pin number. Fix it. Signed-off-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index 009174d07767..bc5eb453a45c 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -3720,7 +3720,7 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) const struct r8a7740_portcr_group *group = &r8a7740_portcr_offsets[i]; - if (i <= group->end_pin) + if (pin <= group->end_pin) return pfc->window->virt + group->offset + pin; } -- cgit v1.2.3 From 71493de7e55af589dbe76ce78ae2b762f9cc6f27 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 28 Nov 2013 16:20:04 +0100 Subject: sh-pfc: sh7372: Fix pin bias setup When computing the pin configuration register offset the bias setup code erroneously compares the pin number range with the loop index instead of the pin number. Fix it. Signed-off-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index 70b522d34821..cc097b693820 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -2584,7 +2584,7 @@ static void __iomem *sh7372_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) const struct sh7372_portcr_group *group = &sh7372_portcr_offsets[i]; - if (i <= group->end_pin) + if (pin <= group->end_pin) return pfc->window->virt + group->offset + pin; } -- cgit v1.2.3 From 7cc67b9c74d9728ba6cbf868d7bcd2cc24de0880 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Sat, 23 Nov 2013 14:55:52 +0900 Subject: gpiolib: fix lookup of platform-mapped GPIOs A typo resulted in GPIO lookup failing unconditionally. Signed-off-by: Alexandre Courbot Reported-by: Stephen Warren Reviewed-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ac53a9593662..b73c39f99858 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2368,7 +2368,7 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, continue; } - if (chip->ngpio >= p->chip_hwnum) { + if (chip->ngpio <= p->chip_hwnum) { dev_warn(dev, "GPIO chip %s has %d GPIOs\n", chip->label, chip->ngpio); continue; -- cgit v1.2.3 From 35c5d7fdc4eed4409f9193bf7651315849cc6aa3 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Sat, 23 Nov 2013 19:34:50 +0900 Subject: gpiolib: use platform GPIO mappings as fallback For platforms that use device tree or ACPI as the standard way to look GPIOs up, allow the platform-defined GPIO mappings to be used as a fallback. This may be useful for platforms that need extra GPIOs mappings not defined by the firmware. Signed-off-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index b73c39f99858..dbddace5df42 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2418,7 +2418,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, const char *con_id, unsigned int idx) { - struct gpio_desc *desc; + struct gpio_desc *desc = NULL; int status; enum gpio_lookup_flags flags = 0; @@ -2431,9 +2431,19 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, } else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev)) { dev_dbg(dev, "using ACPI for GPIO lookup\n"); desc = acpi_find_gpio(dev, con_id, idx, &flags); - } else { + } + + /* + * Either we are not using DT or ACPI, or their lookup did not return + * a result. In that case, use platform lookup as a fallback. + */ + if (!desc || IS_ERR(desc)) { + struct gpio_desc *pdesc; dev_dbg(dev, "using lookup tables for GPIO lookup"); - desc = gpiod_find(dev, con_id, idx, &flags); + pdesc = gpiod_find(dev, con_id, idx, &flags); + /* If used as fallback, do not replace the previous error */ + if (!IS_ERR(pdesc) || !desc) + desc = pdesc; } if (IS_ERR(desc)) { -- cgit v1.2.3 From 1aeef303b5d9e243c41d5b80f8bb059366514a10 Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Fri, 22 Nov 2013 16:12:40 +0800 Subject: powerpc/gpio: Fix the wrong GPIO input data on MPC8572/MPC8536 For MPC8572/MPC8536, the status of GPIOs defined as output cannot be determined by reading GPDAT register, so the code use shadow data register instead. But the code may give the wrong status of GPIOs defined as input under some scenarios: 1. If some pins were configured as inputs and were asserted high before booting the kernel, the shadow data has been initialized with those pin values. 2. Some pins have been configured as output first and have been set to the high value, then reconfigured as input. The above cases will make the shadow data for those input pins to be set to high. Then reading the pin status will always return high even if the actual pin status is low. The code should eliminate the effects of the shadow data to the input pins, and the status of those pins should be read directly from GPDAT. Cc: stable@vger.kernel.org Acked-by: Scott Wood Acked-by: Anatolij Gustschin Signed-off-by: Liu Gang Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mpc8xxx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 914e859e3eda..d7d6d72eba33 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -70,10 +70,14 @@ static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) u32 val; struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); + u32 out_mask, out_shadow; - val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); + out_mask = in_be32(mm->regs + GPIO_DIR); - return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); + val = in_be32(mm->regs + GPIO_DAT) & ~out_mask; + out_shadow = mpc8xxx_gc->data & out_mask; + + return (val | out_shadow) & mpc8xxx_gpio2mask(gpio); } static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) -- cgit v1.2.3 From 351cfe0fe810588bb1cc75fb4f1c1d1d01914b82 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 29 Nov 2013 15:47:34 +0200 Subject: gpiolib: change a warning to debug message when failing to get gpio It's the drivers responsibility to react on failure to get the gpio descriptors and not the frameworks. Since there are some common peripherals that may or may not have certain pins connected to gpio lines, depending on the platform, printing the warning there may end up generating useless bug reports. Signed-off-by: Heikki Krogerus Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index dbddace5df42..85f772c0b26a 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2447,7 +2447,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, } if (IS_ERR(desc)) { - dev_warn(dev, "lookup for GPIO %s failed\n", con_id); + dev_dbg(dev, "lookup for GPIO %s failed\n", con_id); return desc; } -- cgit v1.2.3 From 2167e2399dc5e69c62db56d933e9c8cbe107620a Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Tue, 3 Dec 2013 12:14:32 +0100 Subject: cpufreq: fix garbage kobjects on errors during suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is effectively a revert of commit 5302c3fb2e62 ("cpufreq: Perform light-weight init/teardown during suspend/resume"), which enabled suspend/resume optimizations leaving the sysfs files in place. Errors during suspend/resume are not handled properly, leaving dead sysfs attributes in case of failures. There are are number of functions with special code for the "frozen" case, and all these need to also have special error handling. The problem is easy to demonstrate by making cpufreq_driver->init() or cpufreq_driver->get() fail during resume. The code is too complex for a simple fix, with split code paths in multiple blocks within a number of functions. It is therefore best to revert the patch enabling this code until the error handling is in place. Examples of problems resulting from resume errors: WARNING: CPU: 0 PID: 6055 at fs/sysfs/file.c:343 sysfs_open_file+0x77/0x212() missing sysfs attribute operations for kobject: (null) Modules linked in: [stripped as irrelevant] CPU: 0 PID: 6055 Comm: grep Tainted: G D 3.13.0-rc2 #153 Hardware name: LENOVO 2776LEG/2776LEG, BIOS 6EET55WW (3.15 ) 12/19/2011 0000000000000009 ffff8802327ebb78 ffffffff81380b0e 0000000000000006 ffff8802327ebbc8 ffff8802327ebbb8 ffffffff81038635 0000000000000000 ffffffff811823c7 ffff88021a19e688 ffff88021a19e688 ffff8802302f9310 Call Trace: [] dump_stack+0x55/0x76 [] warn_slowpath_common+0x7c/0x96 [] ? sysfs_open_file+0x77/0x212 [] warn_slowpath_fmt+0x41/0x43 [] ? sysfs_get_active+0x6b/0x82 [] ? sysfs_open_file+0x32/0x212 [] sysfs_open_file+0x77/0x212 [] ? sysfs_schedule_callback+0x1ac/0x1ac [] do_dentry_open+0x17c/0x257 [] finish_open+0x41/0x4f [] do_last+0x80c/0x9ba [] ? inode_permission+0x40/0x42 [] path_openat+0x233/0x4a1 [] do_filp_open+0x35/0x85 [] ? __alloc_fd+0x172/0x184 [] do_sys_open+0x6b/0xfa [] SyS_openat+0xf/0x11 [] system_call_fastpath+0x16/0x1b The failure to restore cpufreq devices on cancelled hibernation is not a new bug. It is caused by the ACPI _PPC call failing unless the hibernate is completed. This makes the acpi_cpufreq driver fail its init. Previously, the cpufreq device could be restored by offlining the cpu temporarily. And as a complete hibernation cycle would do this, it would be automatically restored most of the time. But after commit 5302c3fb2e62 the leftover sysfs attributes will block any device add action. Therefore offlining and onlining CPU 1 will no longer restore the cpufreq object, and a complete suspend/resume cycle will replace it with garbage. Fixes: 5302c3fb2e62 ("cpufreq: Perform light-weight init/teardown during suspend/resume") Cc: 3.12+ # 3.12+ Signed-off-by: Bjørn Mork Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 606224a8abc2..81e9d4412db8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2119,9 +2119,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, dev = get_cpu_device(cpu); if (dev) { - if (action & CPU_TASKS_FROZEN) - frozen = true; - switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: __cpufreq_add_dev(dev, NULL, frozen); -- cgit v1.2.3 From 22a08538dca5c0630226f1c0c58dccd12e463d22 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Thu, 21 Nov 2013 01:37:49 -0800 Subject: [SCSI] bfa: Fix crash when symb name set for offline vport This patch fixes a crash when tried setting symbolic name for an offline vport through sysfs. Crash is due to uninitialized pointer lport->ns, which gets initialized only on linkup (port online). Signed-off-by: Vijaya Mohan Guvva Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_fcs.h | 1 + drivers/scsi/bfa/bfa_fcs_lport.c | 14 +++++++++++--- drivers/scsi/bfa/bfad_attr.c | 7 ++----- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 94d5d0102f7d..42bcb970445a 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -296,6 +296,7 @@ wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, struct bfa_fcs_lport_s *bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn); +void bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port, char *symname); void bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port, struct bfa_lport_info_s *port_info); void bfa_fcs_lport_get_attr(struct bfa_fcs_lport_s *port, diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 2f61a5af3658..f5e4e61a0fd7 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -1097,6 +1097,17 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); } +void +bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port, + char *symname) +{ + strcpy(port->port_cfg.sym_name.symname, symname); + + if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) + bfa_fcs_lport_ns_util_send_rspn_id( + BFA_FCS_GET_NS_FROM_PORT(port), NULL); +} + /* * fcs_lport_api */ @@ -5140,9 +5151,6 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) u8 *psymbl = &symbl[0]; int len; - if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) - return; - /* Avoid sending RSPN in the following states. */ if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) || bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) || diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index e9a681d31223..40be670a1cbc 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -593,11 +593,8 @@ bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport) return; spin_lock_irqsave(&bfad->bfad_lock, flags); - if (strlen(sym_name) > 0) { - strcpy(fcs_vport->lport.port_cfg.sym_name.symname, sym_name); - bfa_fcs_lport_ns_util_send_rspn_id( - BFA_FCS_GET_NS_FROM_PORT((&fcs_vport->lport)), NULL); - } + if (strlen(sym_name) > 0) + bfa_fcs_lport_set_symname(&fcs_vport->lport, sym_name); spin_unlock_irqrestore(&bfad->bfad_lock, flags); } -- cgit v1.2.3 From 813e8e3d6aaa0b511126cce15c16a931afffe768 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 3 Dec 2013 10:59:58 -0500 Subject: cpuidle: Check for dev before deregistering it. If not, we could end up in the unfortunate situation where we dereference a NULL pointer b/c we have cpuidle disabled. This is the case when booting under Xen (which uses the ACPI P/C states but disables the CPU idle driver) - and can be easily reproduced when booting with cpuidle.off=1. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] cpuidle_unregister_device+0x2a/0x90 .. snip.. Call Trace: [] acpi_processor_power_exit+0x3c/0x5c [] acpi_processor_stop+0x61/0xb6 [] __device_release_driver+0fffff81421653>] device_release_driver+0x23/0x30 [] bus_remove_device+0x108/0x180 [] device_del+0x129/0x1c0 [] ? unregister_xenbus_watch+0x1f0/0x1f0 [] device_unregister+0x1e/0x60 [] unregister_cpu+0x39/0x60 [] arch_unregister_cpu+0x23/0x30 [] handle_vcpu_hotplug_event+0xc1/0xe0 [] xenwatch_thread+0x45/0x120 [] ? abort_exclusive_wait+0xb0/0xb0 [] kthread+0xd2/0xf0 [] ? kthread_create_on_node+0x180/0x180 [] ret_from_fork+0x7c/0xb0 [] ? kthread_create_on_node+0x180/0x180 This problem also appears in 3.12 and could be a candidate for backport. Signed-off-by: Konrad Rzeszutek Wilk Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 2a991e468f78..a55e68f2cfc8 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -400,7 +400,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); */ void cpuidle_unregister_device(struct cpuidle_device *dev) { - if (dev->registered == 0) + if (!dev || dev->registered == 0) return; cpuidle_pause_and_lock(); -- cgit v1.2.3 From 5a0973f33b4e6a10227b3d285ff2b0777730d298 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Oct 2013 18:36:57 +0200 Subject: atmel_lcdfb: fix module autoload Add missing module device table which is needed for module autoloading. Signed-off-by: Johan Hovold Acked-by: Nicolas Ferre Signed-off-by: Tomi Valkeinen --- drivers/video/atmel_lcdfb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 8521051cf946..cd961622f9c1 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -131,6 +131,7 @@ static const struct platform_device_id atmel_lcdfb_devtypes[] = { /* terminator */ } }; +MODULE_DEVICE_TABLE(platform, atmel_lcdfb_devtypes); static struct atmel_lcdfb_config * atmel_lcdfb_get_config(struct platform_device *pdev) -- cgit v1.2.3 From 46ac29568e63c9da9c15804648d3ed8c25e2dc44 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 2 Dec 2013 11:11:18 +0300 Subject: video: vt8500: fix error handling in probe() We shouldn't kfree(fbi) because that was allocated with devm_kzalloc(). There were several error paths which returned directly instead of releasing resources. Signed-off-by: Dan Carpenter Signed-off-by: Tomi Valkeinen --- drivers/video/vt8500lcdfb.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c index b30e5a439d1f..a8f2b280f796 100644 --- a/drivers/video/vt8500lcdfb.c +++ b/drivers/video/vt8500lcdfb.c @@ -293,8 +293,7 @@ static int vt8500lcd_probe(struct platform_device *pdev) + sizeof(u32) * 16, GFP_KERNEL); if (!fbi) { dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); - ret = -ENOMEM; - goto failed; + return -ENOMEM; } strcpy(fbi->fb.fix.id, "VT8500 LCD"); @@ -327,15 +326,13 @@ static int vt8500lcd_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "no I/O memory resource defined\n"); - ret = -ENODEV; - goto failed_fbi; + return -ENODEV; } res = request_mem_region(res->start, resource_size(res), "vt8500lcd"); if (res == NULL) { dev_err(&pdev->dev, "failed to request I/O memory\n"); - ret = -EBUSY; - goto failed_fbi; + return -EBUSY; } fbi->regbase = ioremap(res->start, resource_size(res)); @@ -346,17 +343,19 @@ static int vt8500lcd_probe(struct platform_device *pdev) } disp_timing = of_get_display_timings(pdev->dev.of_node); - if (!disp_timing) - return -EINVAL; + if (!disp_timing) { + ret = -EINVAL; + goto failed_free_io; + } ret = of_get_fb_videomode(pdev->dev.of_node, &of_mode, OF_USE_NATIVE_MODE); if (ret) - return ret; + goto failed_free_io; ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp); if (ret) - return ret; + goto failed_free_io; /* try allocating the framebuffer */ fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8); @@ -364,7 +363,8 @@ static int vt8500lcd_probe(struct platform_device *pdev) GFP_KERNEL); if (!fb_mem_virt) { pr_err("%s: Failed to allocate framebuffer\n", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto failed_free_io; } fbi->fb.fix.smem_start = fb_mem_phys; @@ -447,9 +447,6 @@ failed_free_io: iounmap(fbi->regbase); failed_free_res: release_mem_region(res->start, resource_size(res)); -failed_fbi: - kfree(fbi); -failed: return ret; } -- cgit v1.2.3 From 8a37ea50e7acf8db6821ba094ca41384e7d8c70c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 5 Dec 2013 02:01:55 +0100 Subject: PNP: fix restoring devices after hibernation On returning from hibernation 'restore' callback is called, not 'resume'. Fix it. Fixes: eaf140b60ec9 (PNP: convert PNP driver bus legacy pm_ops to dev_pm_ops) Signed-off-by: Dmitry Torokhov Cc: 3.12+ # 3.12+ Signed-off-by: Rafael J. Wysocki --- drivers/pnp/driver.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 6936e0acedcd..f748cc8cbb03 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -197,6 +197,11 @@ static int pnp_bus_freeze(struct device *dev) return __pnp_bus_suspend(dev, PMSG_FREEZE); } +static int pnp_bus_poweroff(struct device *dev) +{ + return __pnp_bus_suspend(dev, PMSG_HIBERNATE); +} + static int pnp_bus_resume(struct device *dev) { struct pnp_dev *pnp_dev = to_pnp_dev(dev); @@ -234,9 +239,14 @@ static int pnp_bus_resume(struct device *dev) } static const struct dev_pm_ops pnp_bus_dev_pm_ops = { + /* Suspend callbacks */ .suspend = pnp_bus_suspend, - .freeze = pnp_bus_freeze, .resume = pnp_bus_resume, + /* Hibernate callbacks */ + .freeze = pnp_bus_freeze, + .thaw = pnp_bus_resume, + .poweroff = pnp_bus_poweroff, + .restore = pnp_bus_resume, }; struct bus_type pnp_bus_type = { -- cgit v1.2.3 From 95677a9a3847de4f37e0f463aeb94aa8d5cccc50 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 4 Dec 2013 11:12:59 -0800 Subject: PowerCap: Fix mode for energy counter As per the documentation of powercap sysfs, energy_uj field is read only, if it can't be reset. Currently it always allows write but will fail, if there is no reset callback. Changing mode field, to read only if there is no reset callback. Signed-off-by: Srinivas Pandruvada Reported-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki --- drivers/powercap/powercap_sys.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index 8d0fe431dbdd..84419af16f77 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -377,9 +377,14 @@ static void create_power_zone_common_attributes( if (power_zone->ops->get_max_energy_range_uj) power_zone->zone_dev_attrs[count++] = &dev_attr_max_energy_range_uj.attr; - if (power_zone->ops->get_energy_uj) + if (power_zone->ops->get_energy_uj) { + if (power_zone->ops->reset_energy_uj) + dev_attr_energy_uj.attr.mode = S_IWUSR | S_IRUGO; + else + dev_attr_energy_uj.attr.mode = S_IRUGO; power_zone->zone_dev_attrs[count++] = &dev_attr_energy_uj.attr; + } if (power_zone->ops->get_power_uw) power_zone->zone_dev_attrs[count++] = &dev_attr_power_uw.attr; -- cgit v1.2.3 From 0ad7c00057dc1640647c1dc81ccbd009de17a767 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 26 Nov 2013 10:04:22 -0700 Subject: dma: add channel request API that supports deferred probe dma_request_slave_channel() simply returns NULL whenever DMA channel lookup fails. Lookup could fail for two distinct reasons: a) No DMA specification exists for the channel name. This includes situations where no DMA specifications exist at all, or other general lookup problems. b) A DMA specification does exist, yet the driver for that channel is not yet registered. Case (b) should trigger deferred probe in client drivers. However, since they have no way to differentiate the two situations, it cannot. Implement new function dma_request_slave_channel_reason(), which performs identically to dma_request_slave_channel(), except that it returns an error-pointer rather than NULL, which allows callers to detect when deferred probe should occur. Eventually, all drivers should be converted to this new API, the old API removed, and the new API renamed to the more desirable name. This patch doesn't convert the existing API and all drivers in one go, since some drivers call dma_request_slave_channel() then dma_request_channel() if that fails. That would require either modifying dma_request_channel() in the same way, or adding extra error-handling code to all affected drivers, and there are close to 100 drivers using the other API, rather than just the 15-20 or so that use dma_request_slave_channel(), which might be tenable in a single patch. acpi_dma_request_slave_chan_by_name() doesn't currently implement deferred probe. It should, but this will be addressed later. Acked-by: Dan Williams Signed-off-by: Stephen Warren Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 35 +++++++++++++++++++++++++++++++---- drivers/dma/of-dma.c | 15 +++++++++------ include/linux/dmaengine.h | 8 ++++++++ 3 files changed, 48 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ea806bdc12ef..e17e9b22d85e 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -540,6 +540,8 @@ EXPORT_SYMBOL_GPL(dma_get_slave_channel); * @mask: capabilities that the channel must satisfy * @fn: optional callback to disposition available channels * @fn_param: opaque parameter to pass to dma_filter_fn + * + * Returns pointer to appropriate DMA channel on success or NULL. */ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param) @@ -591,18 +593,43 @@ EXPORT_SYMBOL_GPL(__dma_request_channel); * dma_request_slave_channel - try to allocate an exclusive slave channel * @dev: pointer to client device structure * @name: slave channel name + * + * Returns pointer to appropriate DMA channel on success or an error pointer. */ -struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) +struct dma_chan *dma_request_slave_channel_reason(struct device *dev, + const char *name) { + struct dma_chan *chan; + /* If device-tree is present get slave info from here */ if (dev->of_node) return of_dma_request_slave_channel(dev->of_node, name); /* If device was enumerated by ACPI get slave info from here */ - if (ACPI_HANDLE(dev)) - return acpi_dma_request_slave_chan_by_name(dev, name); + if (ACPI_HANDLE(dev)) { + chan = acpi_dma_request_slave_chan_by_name(dev, name); + if (chan) + return chan; + } - return NULL; + return ERR_PTR(-ENODEV); +} +EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason); + +/** + * dma_request_slave_channel - try to allocate an exclusive slave channel + * @dev: pointer to client device structure + * @name: slave channel name + * + * Returns pointer to appropriate DMA channel on success or NULL. + */ +struct dma_chan *dma_request_slave_channel(struct device *dev, + const char *name) +{ + struct dma_chan *ch = dma_request_slave_channel_reason(dev, name); + if (IS_ERR(ch)) + return NULL; + return ch; } EXPORT_SYMBOL_GPL(dma_request_slave_channel); diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index 0b88dd3d05f4..e8fe9dc455f4 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -143,7 +143,7 @@ static int of_dma_match_channel(struct device_node *np, const char *name, * @np: device node to get DMA request from * @name: name of desired channel * - * Returns pointer to appropriate dma channel on success or NULL on error. + * Returns pointer to appropriate DMA channel on success or an error pointer. */ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, const char *name) @@ -152,17 +152,18 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, struct of_dma *ofdma; struct dma_chan *chan; int count, i; + int ret_no_channel = -ENODEV; if (!np || !name) { pr_err("%s: not enough information provided\n", __func__); - return NULL; + return ERR_PTR(-ENODEV); } count = of_property_count_strings(np, "dma-names"); if (count < 0) { pr_err("%s: dma-names property of node '%s' missing or empty\n", __func__, np->full_name); - return NULL; + return ERR_PTR(-ENODEV); } for (i = 0; i < count; i++) { @@ -172,10 +173,12 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, mutex_lock(&of_dma_lock); ofdma = of_dma_find_controller(&dma_spec); - if (ofdma) + if (ofdma) { chan = ofdma->of_dma_xlate(&dma_spec, ofdma); - else + } else { + ret_no_channel = -EPROBE_DEFER; chan = NULL; + } mutex_unlock(&of_dma_lock); @@ -185,7 +188,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, return chan; } - return NULL; + return ERR_PTR(ret_no_channel); } /** diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 41cf0c399288..ed92b30a02fd 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -22,6 +22,7 @@ #define LINUX_DMAENGINE_H #include +#include #include #include #include @@ -1040,6 +1041,8 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); void dma_issue_pending_all(void); struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); +struct dma_chan *dma_request_slave_channel_reason(struct device *dev, + const char *name); struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name); void dma_release_channel(struct dma_chan *chan); #else @@ -1063,6 +1066,11 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, { return NULL; } +static inline struct dma_chan *dma_request_slave_channel_reason( + struct device *dev, const char *name) +{ + return ERR_PTR(-ENODEV); +} static inline struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) { -- cgit v1.2.3 From 8010dad55a0ab0e829f3733854e5235eef4e2734 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 26 Nov 2013 12:40:51 -0700 Subject: dma: add dma_get_any_slave_channel(), for use in of_xlate() mmp_pdma.c implements a custom of_xlate() function that is 95% identical to what Tegra will need. Create a function to implement the common part, so everyone doesn't just cut/paste the implementation. Cc: Dan Williams Cc: Vinod Koul Cc: Lars-Peter Clausen Cc: dmaengine@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Stephen Warren Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 28 ++++++++++++++++++++++++++++ drivers/dma/mmp_pdma.c | 30 +++++++----------------------- include/linux/dmaengine.h | 1 + 3 files changed, 36 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ea806bdc12ef..4f08ee8c17b4 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -535,6 +535,34 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan) } EXPORT_SYMBOL_GPL(dma_get_slave_channel); +struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) +{ + dma_cap_mask_t mask; + struct dma_chan *chan; + int err; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + /* lock against __dma_request_channel */ + mutex_lock(&dma_list_mutex); + + chan = private_candidate(&mask, device, NULL, NULL); + if (chan) { + err = dma_chan_get(chan); + if (err) { + pr_debug("%s: failed to get %s: (%d)\n", + __func__, dma_chan_name(chan), err); + chan = NULL; + } + } + + mutex_unlock(&dma_list_mutex); + + return chan; +} +EXPORT_SYMBOL_GPL(dma_get_any_slave_channel); + /** * __dma_request_channel - try to allocate an exclusive channel * @mask: capabilities that the channel must satisfy diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index dcb1e05149a7..2998f1bffac1 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -893,33 +893,17 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { struct mmp_pdma_device *d = ofdma->of_dma_data; - struct dma_chan *chan, *candidate; + struct dma_chan *chan; + struct mmp_pdma_chan *c; -retry: - candidate = NULL; - - /* walk the list of channels registered with the current instance and - * find one that is currently unused */ - list_for_each_entry(chan, &d->device.channels, device_node) - if (chan->client_count == 0) { - candidate = chan; - break; - } - - if (!candidate) + chan = dma_get_any_slave_channel(&d->device); + if (!chan) return NULL; - /* dma_get_slave_channel will return NULL if we lost a race between - * the lookup and the reservation */ - chan = dma_get_slave_channel(candidate); - - if (chan) { - struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan); - c->drcmr = dma_spec->args[0]; - return chan; - } + c = to_mmp_pdma_chan(chan); + c->drcmr = dma_spec->args[0]; - goto retry; + return chan; } static int mmp_pdma_probe(struct platform_device *op) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 41cf0c399288..09ef23ee8bce 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1079,6 +1079,7 @@ int dma_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_get_slave_channel(struct dma_chan *chan); +struct dma_chan *dma_get_any_slave_channel(struct dma_device *device); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) #define dma_request_slave_channel_compat(mask, x, y, dev, name) \ -- cgit v1.2.3 From 6d5b988e7dc56bb97c39bdcbc006fadcd6ca371b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 5 Nov 2013 17:33:17 -0700 Subject: clk: tegra: implement a reset driver The Tegra CAR module implements both a clock and reset controller. So far, the driver exposes the clock feature via the common clock API and the reset feature using a custom API. This patch adds an implementation of the common reset framework API (include/linux/reset*.h). The legacy reset implementation will be removed once all drivers have been converted. Signed-off-by: Stephen Warren Reviewed-by: Thierry Reding Acked-By: Peter De Schrijver --- drivers/clk/tegra/clk-tegra114.c | 3 ++- drivers/clk/tegra/clk-tegra124.c | 2 +- drivers/clk/tegra/clk-tegra20.c | 3 ++- drivers/clk/tegra/clk-tegra30.c | 3 ++- drivers/clk/tegra/clk.c | 50 +++++++++++++++++++++++++++++++++++++++- drivers/clk/tegra/clk.h | 2 +- 6 files changed, 57 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 29b912582e3d..90d9d25f2228 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1460,7 +1460,8 @@ static void __init tegra114_clock_init(struct device_node *np) return; } - clks = tegra_clk_init(TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_PERIPH_BANKS); + clks = tegra_clk_init(clk_base, TEGRA114_CLK_CLK_MAX, + TEGRA114_CLK_PERIPH_BANKS); if (!clks) return; diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 0ef4485e9b0a..aff86b5bc745 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -1398,7 +1398,7 @@ static void __init tegra124_clock_init(struct device_node *np) return; } - clks = tegra_clk_init(TEGRA124_CLK_CLK_MAX, 6); + clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6); if (!clks) return; diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index b3b7204acfe7..5a6a60d9443a 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -1109,7 +1109,8 @@ static void __init tegra20_clock_init(struct device_node *np) BUG(); } - clks = tegra_clk_init(TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_PERIPH_BANKS); + clks = tegra_clk_init(clk_base, TEGRA20_CLK_CLK_MAX, + TEGRA20_CLK_PERIPH_BANKS); if (!clks) return; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index dcb6843b3a89..2e47383418c8 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1427,7 +1427,8 @@ static void __init tegra30_clock_init(struct device_node *np) BUG(); } - clks = tegra_clk_init(TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_PERIPH_BANKS); + clks = tegra_clk_init(clk_base, TEGRA30_CLK_CLK_MAX, + TEGRA30_CLK_PERIPH_BANKS); if (!clks) return; diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index a12a5f5107ec..c0a7d7723510 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include "clk.h" @@ -121,6 +123,35 @@ static struct tegra_clk_periph_regs periph_regs[] = { }, }; +static void __iomem *clk_base; + +static int tegra_clk_rst_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + /* + * If peripheral is on the APB bus then we must read the APB bus to + * flush the write operation in apb bus. This will avoid peripheral + * access after disabling clock. Since the reset driver has no + * knowledge of which reset IDs represent which devices, simply do + * this all the time. + */ + tegra_read_chipid(); + + writel_relaxed(BIT(id % 32), + clk_base + periph_regs[id / 32].rst_set_reg); + + return 0; +} + +static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + writel_relaxed(BIT(id % 32), + clk_base + periph_regs[id / 32].rst_clr_reg); + + return 0; +} + struct tegra_clk_periph_regs *get_reg_bank(int clkid) { int reg_bank = clkid / 32; @@ -133,8 +164,10 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid) } } -struct clk ** __init tegra_clk_init(int num, int banks) +struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) { + clk_base = regs; + if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) return NULL; @@ -203,6 +236,17 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, } } +static struct reset_control_ops rst_ops = { + .assert = tegra_clk_rst_assert, + .deassert = tegra_clk_rst_deassert, +}; + +static struct reset_controller_dev rst_ctlr = { + .ops = &rst_ops, + .owner = THIS_MODULE, + .of_reset_n_cells = 1, +}; + void __init tegra_add_of_provider(struct device_node *np) { int i; @@ -220,6 +264,10 @@ void __init tegra_add_of_provider(struct device_node *np) clk_data.clks = clks; clk_data.clk_num = clk_num; of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + + rst_ctlr.of_node = np; + rst_ctlr.nr_resets = clk_num * 32; + reset_controller_register(&rst_ctlr); } void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 40fb011233c0..07c62f997371 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -597,7 +597,7 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, struct clk *clks[], int clk_max); struct tegra_clk_periph_regs *get_reg_bank(int clkid); -struct clk **tegra_clk_init(int num, int periph_banks); +struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks); struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); -- cgit v1.2.3 From 3127a6b2a2342ecd7d7579ccbf39b50908b9df02 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 15:56:58 -0700 Subject: pci: tegra: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. The old Tegra-specific API used a struct clock to represent the module to reset. Some of the clocks retrieved during probe() were only used for reset purposes, and indeed aren't even true clocks. So, there's no need to get() them any more. Signed-off-by: Stephen Warren Acked-by: Bjorn Helgaas Reviewed-by: Thierry Reding Acked-by: Thierry Reding --- drivers/pci/host/pci-tegra.c | 50 +++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 0afbbbc55c81..6681c3182c85 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -25,7 +25,6 @@ */ #include -#include #include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -259,10 +259,13 @@ struct tegra_pcie { struct clk *pex_clk; struct clk *afi_clk; - struct clk *pcie_xclk; struct clk *pll_e; struct clk *cml_clk; + struct reset_control *pex_rst; + struct reset_control *afi_rst; + struct reset_control *pcie_xrst; + struct tegra_msi msi; struct list_head ports; @@ -858,7 +861,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) pads_writel(pcie, value, PADS_CTL); /* take the PCIe interface module out of reset */ - tegra_periph_reset_deassert(pcie->pcie_xclk); + reset_control_deassert(pcie->pcie_xrst); /* finally enable PCIe */ value = afi_readl(pcie, AFI_CONFIGURATION); @@ -891,9 +894,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie) /* TODO: disable and unprepare clocks? */ - tegra_periph_reset_assert(pcie->pcie_xclk); - tegra_periph_reset_assert(pcie->afi_clk); - tegra_periph_reset_assert(pcie->pex_clk); + reset_control_assert(pcie->pcie_xrst); + reset_control_assert(pcie->afi_rst); + reset_control_assert(pcie->pex_rst); tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); @@ -921,9 +924,9 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) const struct tegra_pcie_soc_data *soc = pcie->soc_data; int err; - tegra_periph_reset_assert(pcie->pcie_xclk); - tegra_periph_reset_assert(pcie->afi_clk); - tegra_periph_reset_assert(pcie->pex_clk); + reset_control_assert(pcie->pcie_xrst); + reset_control_assert(pcie->afi_rst); + reset_control_assert(pcie->pex_rst); tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); @@ -958,7 +961,7 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) return err; } - tegra_periph_reset_deassert(pcie->afi_clk); + reset_control_deassert(pcie->afi_rst); err = clk_prepare_enable(pcie->afi_clk); if (err < 0) { @@ -996,10 +999,6 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) if (IS_ERR(pcie->afi_clk)) return PTR_ERR(pcie->afi_clk); - pcie->pcie_xclk = devm_clk_get(pcie->dev, "pcie_xclk"); - if (IS_ERR(pcie->pcie_xclk)) - return PTR_ERR(pcie->pcie_xclk); - pcie->pll_e = devm_clk_get(pcie->dev, "pll_e"); if (IS_ERR(pcie->pll_e)) return PTR_ERR(pcie->pll_e); @@ -1013,6 +1012,23 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) return 0; } +static int tegra_pcie_resets_get(struct tegra_pcie *pcie) +{ + pcie->pex_rst = devm_reset_control_get(pcie->dev, "pex"); + if (IS_ERR(pcie->pex_rst)) + return PTR_ERR(pcie->pex_rst); + + pcie->afi_rst = devm_reset_control_get(pcie->dev, "afi"); + if (IS_ERR(pcie->afi_rst)) + return PTR_ERR(pcie->afi_rst); + + pcie->pcie_xrst = devm_reset_control_get(pcie->dev, "pcie_x"); + if (IS_ERR(pcie->pcie_xrst)) + return PTR_ERR(pcie->pcie_xrst); + + return 0; +} + static int tegra_pcie_get_resources(struct tegra_pcie *pcie) { struct platform_device *pdev = to_platform_device(pcie->dev); @@ -1025,6 +1041,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) return err; } + err = tegra_pcie_resets_get(pcie); + if (err) { + dev_err(&pdev->dev, "failed to get resets: %d\n", err); + return err; + } + err = tegra_pcie_power_on(pcie); if (err) { dev_err(&pdev->dev, "failed to power up: %d\n", err); -- cgit v1.2.3 From ca48080a039f667c9a1e2d6236ea18dde2d36e7e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:20:54 -0700 Subject: drm/tegra: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-By: Terje Bergstrom --- drivers/gpu/drm/tegra/Kconfig | 1 + drivers/gpu/drm/tegra/dc.c | 10 ++++++++-- drivers/gpu/drm/tegra/drm.h | 3 +++ drivers/gpu/drm/tegra/gr3d.c | 16 ++++++++++++++++ drivers/gpu/drm/tegra/hdmi.c | 15 +++++++++++---- 5 files changed, 39 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index 8961ba6a34b8..8db9b3bce001 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -2,6 +2,7 @@ config DRM_TEGRA bool "NVIDIA Tegra DRM" depends on ARCH_TEGRA || ARCH_MULTIPLATFORM depends on DRM + depends on RESET_CONTROLLER select TEGRA_HOST1X select DRM_KMS_HELPER select DRM_KMS_FB_HELPER diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index ae1cb31ead7e..cd7f1e499616 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -8,8 +8,8 @@ */ #include -#include #include +#include #include "dc.h" #include "drm.h" @@ -712,7 +712,7 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc) unsigned long value; /* hardware initialization */ - tegra_periph_reset_deassert(dc->clk); + reset_control_deassert(dc->rst); usleep_range(10000, 20000); if (dc->pipe) @@ -1187,6 +1187,12 @@ static int tegra_dc_probe(struct platform_device *pdev) return PTR_ERR(dc->clk); } + dc->rst = devm_reset_control_get(&pdev->dev, "dc"); + if (IS_ERR(dc->rst)) { + dev_err(&pdev->dev, "failed to get reset\n"); + return PTR_ERR(dc->rst); + } + err = clk_prepare_enable(dc->clk); if (err < 0) return err; diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index fdfe259ed7f8..f717c18b28c2 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -19,6 +19,8 @@ #include #include +struct reset_control; + struct tegra_fb { struct drm_framebuffer base; struct tegra_bo **planes; @@ -93,6 +95,7 @@ struct tegra_dc { int pipe; struct clk *clk; + struct reset_control *rst; void __iomem *regs; int irq; diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 4cec8f526af7..f629e38b00e4 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "drm.h" @@ -22,6 +23,8 @@ struct gr3d { struct host1x_channel *channel; struct clk *clk_secondary; struct clk *clk; + struct reset_control *rst_secondary; + struct reset_control *rst; DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); }; @@ -255,12 +258,25 @@ static int gr3d_probe(struct platform_device *pdev) return PTR_ERR(gr3d->clk); } + gr3d->rst = devm_reset_control_get(&pdev->dev, "3d"); + if (IS_ERR(gr3d->rst)) { + dev_err(&pdev->dev, "cannot get reset\n"); + return PTR_ERR(gr3d->rst); + } + if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) { gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2"); if (IS_ERR(gr3d->clk)) { dev_err(&pdev->dev, "cannot get secondary clock\n"); return PTR_ERR(gr3d->clk); } + + gr3d->rst_secondary = devm_reset_control_get(&pdev->dev, + "3d2"); + if (IS_ERR(gr3d->rst_secondary)) { + dev_err(&pdev->dev, "cannot get secondary reset\n"); + return PTR_ERR(gr3d->rst_secondary); + } } err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk); diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 0cd9bc2056e8..7f6253ea5cb5 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -8,10 +8,10 @@ */ #include -#include #include #include #include +#include #include "hdmi.h" #include "drm.h" @@ -49,6 +49,7 @@ struct tegra_hdmi { struct clk *clk_parent; struct clk *clk; + struct reset_control *rst; const struct tegra_hdmi_config *config; @@ -731,9 +732,9 @@ static int tegra_output_hdmi_enable(struct tegra_output *output) return err; } - tegra_periph_reset_assert(hdmi->clk); + reset_control_assert(hdmi->rst); usleep_range(1000, 2000); - tegra_periph_reset_deassert(hdmi->clk); + reset_control_deassert(hdmi->rst); tegra_dc_writel(dc, VSYNC_H_POSITION(1), DC_DISP_DISP_TIMING_OPTIONS); @@ -912,7 +913,7 @@ static int tegra_output_hdmi_disable(struct tegra_output *output) { struct tegra_hdmi *hdmi = to_hdmi(output); - tegra_periph_reset_assert(hdmi->clk); + reset_control_assert(hdmi->rst); clk_disable(hdmi->clk); regulator_disable(hdmi->pll); @@ -1338,6 +1339,12 @@ static int tegra_hdmi_probe(struct platform_device *pdev) return PTR_ERR(hdmi->clk); } + hdmi->rst = devm_reset_control_get(&pdev->dev, "hdmi"); + if (IS_ERR(hdmi->rst)) { + dev_err(&pdev->dev, "failed to get reset\n"); + return PTR_ERR(hdmi->rst); + } + err = clk_prepare(hdmi->clk); if (err < 0) return err; -- cgit v1.2.3 From 80b28791ff0416a472e5a555a4b6f5f39df2fc24 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 15:45:46 -0700 Subject: ARM: tegra: pass reset to tegra_powergate_sequence_power_up() Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Bjorn Helgaas Acked-By: Terje Bergstrom Reviewed-by: Thierry Reding Acked-by: Thierry Reding --- arch/arm/mach-tegra/powergate.c | 8 +++++--- drivers/gpu/drm/tegra/gr3d.c | 6 ++++-- drivers/pci/host/pci-tegra.c | 3 ++- include/linux/tegra-powergate.h | 7 +++++-- 4 files changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index 85d28e756bb7..f6f5b54ff95e 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -144,11 +145,12 @@ int tegra_powergate_remove_clamping(int id) } /* Must be called with clk disabled, and returns with clk enabled */ -int tegra_powergate_sequence_power_up(int id, struct clk *clk) +int tegra_powergate_sequence_power_up(int id, struct clk *clk, + struct reset_control *rst) { int ret; - tegra_periph_reset_assert(clk); + reset_control_assert(rst); ret = tegra_powergate_power_on(id); if (ret) @@ -165,7 +167,7 @@ int tegra_powergate_sequence_power_up(int id, struct clk *clk) goto err_clamp; udelay(10); - tegra_periph_reset_deassert(clk); + reset_control_deassert(rst); return 0; diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index f629e38b00e4..0cbb24b1ae04 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -279,7 +279,8 @@ static int gr3d_probe(struct platform_device *pdev) } } - err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk); + err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk, + gr3d->rst); if (err < 0) { dev_err(&pdev->dev, "failed to power up 3D unit\n"); return err; @@ -287,7 +288,8 @@ static int gr3d_probe(struct platform_device *pdev) if (gr3d->clk_secondary) { err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1, - gr3d->clk_secondary); + gr3d->clk_secondary, + gr3d->rst_secondary); if (err < 0) { dev_err(&pdev->dev, "failed to power up secondary 3D unit\n"); diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 6681c3182c85..0175041ab728 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -955,7 +955,8 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) } err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, - pcie->pex_clk); + pcie->pex_clk, + pcie->pex_rst); if (err) { dev_err(pcie->dev, "powerup sequence failed: %d\n", err); return err; diff --git a/include/linux/tegra-powergate.h b/include/linux/tegra-powergate.h index fd4498329c7c..afe442d2629a 100644 --- a/include/linux/tegra-powergate.h +++ b/include/linux/tegra-powergate.h @@ -19,6 +19,7 @@ #define _MACH_TEGRA_POWERGATE_H_ struct clk; +struct reset_control; #define TEGRA_POWERGATE_CPU 0 #define TEGRA_POWERGATE_3D 1 @@ -52,7 +53,8 @@ int tegra_powergate_power_off(int id); int tegra_powergate_remove_clamping(int id); /* Must be called with clk disabled, and returns with clk enabled */ -int tegra_powergate_sequence_power_up(int id, struct clk *clk); +int tegra_powergate_sequence_power_up(int id, struct clk *clk, + struct reset_control *rst); #else static inline int tegra_powergate_is_powered(int id) { @@ -74,7 +76,8 @@ static inline int tegra_powergate_remove_clamping(int id) return -ENOSYS; } -static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk) +static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk, + struct reset_control *rst); { return -ENOSYS; } -- cgit v1.2.3 From 9aa433d2a77220fc261cb8248bb93bdd8e3944ef Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:35:34 -0700 Subject: dma: tegra: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Reviewed-by: Thierry Reding Acked-by: Dan Williams Acked-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 73654e33f13b..afa5844c9346 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -32,8 +32,8 @@ #include #include #include +#include #include -#include #include "dmaengine.h" @@ -208,6 +208,7 @@ struct tegra_dma { struct dma_device dma_dev; struct device *dev; struct clk *dma_clk; + struct reset_control *rst; spinlock_t global_lock; void __iomem *base_addr; const struct tegra_dma_chip_data *chip_data; @@ -1282,6 +1283,12 @@ static int tegra_dma_probe(struct platform_device *pdev) return PTR_ERR(tdma->dma_clk); } + tdma->rst = devm_reset_control_get(&pdev->dev, "dma"); + if (IS_ERR(tdma->rst)) { + dev_err(&pdev->dev, "Error: Missing reset\n"); + return PTR_ERR(tdma->rst); + } + spin_lock_init(&tdma->global_lock); pm_runtime_enable(&pdev->dev); @@ -1302,9 +1309,9 @@ static int tegra_dma_probe(struct platform_device *pdev) } /* Reset DMA controller */ - tegra_periph_reset_assert(tdma->dma_clk); + reset_control_assert(tdma->rst); udelay(2); - tegra_periph_reset_deassert(tdma->dma_clk); + reset_control_deassert(tdma->rst); /* Enable global DMA registers */ tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE); -- cgit v1.2.3 From 996556c92a706058cf5ce6b3ef8dacc4032a3e0d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 11 Nov 2013 13:09:35 -0700 Subject: dma: tegra: register as an OF DMA controller Call of_dma_controller_register() so that DMA clients can look up the Tegra DMA controller using standard APIs. This requires the of_xlate() function to save off the DMA slave ID, and for tegra_dma_slave_config() not to over-write this information; once DMA client drivers are converted to dma_request_slave_channel() and DT-based lookups, they won't set this field of struct dma_slave_config anymore. Signed-off-by: Stephen Warren Acked-by: Arnd Bergmann Reviewed-by: Thierry Reding --- drivers/dma/tegra20-apb-dma.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index afa5844c9346..d11bb3620f27 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1,7 +1,7 @@ /* * DMA driver for Nvidia's Tegra20 APB DMA controller. * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2012-2013, 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, @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -199,6 +200,7 @@ struct tegra_dma_channel { void *callback_param; /* Channel-slave specific configuration */ + unsigned int slave_id; struct dma_slave_config dma_sconfig; struct tegra_dma_channel_regs channel_reg; }; @@ -340,6 +342,8 @@ static int tegra_dma_slave_config(struct dma_chan *dc, } memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); + if (!tdc->slave_id) + tdc->slave_id = sconfig->slave_id; tdc->config_init = true; return 0; } @@ -942,7 +946,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; - csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; + csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; if (flags & DMA_PREP_INTERRUPT) csr |= TEGRA_APBDMA_CSR_IE_EOC; @@ -1086,7 +1090,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( csr |= TEGRA_APBDMA_CSR_FLOW; if (flags & DMA_PREP_INTERRUPT) csr |= TEGRA_APBDMA_CSR_IE_EOC; - csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; + csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; @@ -1206,6 +1210,25 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) kfree(sg_req); } clk_disable_unprepare(tdma->dma_clk); + + tdc->slave_id = 0; +} + +static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct tegra_dma *tdma = ofdma->of_dma_data; + struct dma_chan *chan; + struct tegra_dma_channel *tdc; + + chan = dma_get_any_slave_channel(&tdma->dma_dev); + if (!chan) + return NULL; + + tdc = to_tegra_dma_chan(chan); + tdc->slave_id = dma_spec->args[0]; + + return chan; } /* Tegra20 specific DMA controller information */ @@ -1383,10 +1406,20 @@ static int tegra_dma_probe(struct platform_device *pdev) goto err_irq; } + ret = of_dma_controller_register(pdev->dev.of_node, + tegra_dma_of_xlate, tdma); + if (ret < 0) { + dev_err(&pdev->dev, + "Tegra20 APB DMA OF registration failed %d\n", ret); + goto err_unregister_dma_dev; + } + dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n", cdata->nr_channels); return 0; +err_unregister_dma_dev: + dma_async_device_unregister(&tdma->dma_dev); err_irq: while (--i >= 0) { struct tegra_dma_channel *tdc = &tdma->channels[i]; -- cgit v1.2.3 From dda9d6a8262cb1fa63eb815dc0de2a984389c71b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:42:05 -0700 Subject: i2c: tegra: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Wolfram Sang Reviewed-by: Thierry Reding --- drivers/i2c/busses/i2c-tegra.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index e661edee4d0c..9704537aee3c 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include @@ -160,6 +160,7 @@ struct tegra_i2c_dev { struct i2c_adapter adapter; struct clk *div_clk; struct clk *fast_clk; + struct reset_control *rst; void __iomem *base; int cont_id; int irq; @@ -415,9 +416,9 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) return err; } - tegra_periph_reset_assert(i2c_dev->div_clk); + reset_control_assert(i2c_dev->rst); udelay(2); - tegra_periph_reset_deassert(i2c_dev->div_clk); + reset_control_deassert(i2c_dev->rst); if (i2c_dev->is_dvc) tegra_dvc_init(i2c_dev); @@ -743,6 +744,12 @@ static int tegra_i2c_probe(struct platform_device *pdev) i2c_dev->cont_id = pdev->id; i2c_dev->dev = &pdev->dev; + i2c_dev->rst = devm_reset_control_get(&pdev->dev, "i2c"); + if (IS_ERR(i2c_dev->rst)) { + dev_err(&pdev->dev, "missing controller reset"); + return PTR_ERR(i2c_dev->rst); + } + ret = of_property_read_u32(i2c_dev->dev->of_node, "clock-frequency", &i2c_dev->bus_clk_rate); if (ret) -- cgit v1.2.3 From c0df5bf5369ec5d12d781491c95e3207ec5ee2b7 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:46:24 -0700 Subject: staging: nvec: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Marc Dietrich Acked-by: Greg Kroah-Hartman Reviewed-by: Thierry Reding --- drivers/staging/nvec/nvec.c | 11 ++++++++--- drivers/staging/nvec/nvec.h | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 49ea76b3435d..986870593b0c 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "nvec.h" @@ -734,9 +733,9 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) clk_prepare_enable(nvec->i2c_clk); - tegra_periph_reset_assert(nvec->i2c_clk); + reset_control_assert(nvec->rst); udelay(2); - tegra_periph_reset_deassert(nvec->i2c_clk); + reset_control_deassert(nvec->rst); val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN | (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); @@ -837,6 +836,12 @@ static int tegra_nvec_probe(struct platform_device *pdev) return -ENODEV; } + nvec->rst = devm_reset_control_get(&pdev->dev, "i2c"); + if (IS_ERR(nvec->rst)) { + dev_err(nvec->dev, "failed to get controller reset\n"); + return PTR_ERR(nvec->rst); + } + nvec->base = base; nvec->irq = res->start; nvec->i2c_clk = i2c_clk; diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index e880518935fb..e271375053fa 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -109,7 +110,8 @@ struct nvec_msg { * @irq: The IRQ of the I2C device * @i2c_addr: The address of the I2C slave * @base: The base of the memory mapped region of the I2C device - * @clk: The clock of the I2C device + * @i2c_clk: The clock of the I2C device + * @rst: The reset of the I2C device * @notifier_list: Notifiers to be called on received messages, see * nvec_register_notifier() * @rx_data: Received messages that have to be processed @@ -139,6 +141,7 @@ struct nvec_chip { int i2c_addr; void __iomem *base; struct clk *i2c_clk; + struct reset_control *rst; struct atomic_notifier_head notifier_list; struct list_head rx_data, tx_data; struct notifier_block nvec_status_notifier; -- cgit v1.2.3 From ff2251e3de37b002e2e91e4917119f5776e210e3 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:31:24 -0700 Subject: spi: tegra: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Mark Brown Reviewed-by: Thierry Reding --- drivers/spi/Kconfig | 3 +++ drivers/spi/spi-tegra114.c | 18 +++++++++++++----- drivers/spi/spi-tegra20-sflash.c | 18 +++++++++++++----- drivers/spi/spi-tegra20-slink.c | 18 +++++++++++++----- 4 files changed, 42 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index eb1f1ef5fa2e..9fc66e83c1a7 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -448,6 +448,7 @@ config SPI_MXS config SPI_TEGRA114 tristate "NVIDIA Tegra114 SPI Controller" depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST + depends on RESET_CONTROLLER help SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller is different than the older SoCs SPI controller and also register interface @@ -456,6 +457,7 @@ config SPI_TEGRA114 config SPI_TEGRA20_SFLASH tristate "Nvidia Tegra20 Serial flash Controller" depends on ARCH_TEGRA || COMPILE_TEST + depends on RESET_CONTROLLER help SPI driver for Nvidia Tegra20 Serial flash Controller interface. The main usecase of this controller is to use spi flash as boot @@ -464,6 +466,7 @@ config SPI_TEGRA20_SFLASH config SPI_TEGRA20_SLINK tristate "Nvidia Tegra20/Tegra30 SLINK Controller" depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST + depends on RESET_CONTROLLER help SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index aaecfb3ebf58..f62e6e5e90e3 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include #define SPI_COMMAND1 0x000 @@ -174,6 +174,7 @@ struct tegra_spi_data { spinlock_t lock; struct clk *clk; + struct reset_control *rst; void __iomem *base; phys_addr_t phys; unsigned irq; @@ -918,9 +919,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi) tspi->status_reg); dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n", tspi->command1_reg, tspi->dma_control_reg); - tegra_periph_reset_assert(tspi->clk); + reset_control_assert(tspi->rst); udelay(2); - tegra_periph_reset_deassert(tspi->clk); + reset_control_deassert(tspi->rst); complete(&tspi->xfer_completion); goto exit; } @@ -990,9 +991,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi) tspi->status_reg); dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n", tspi->command1_reg, tspi->dma_control_reg); - tegra_periph_reset_assert(tspi->clk); + reset_control_assert(tspi->rst); udelay(2); - tegra_periph_reset_deassert(tspi->clk); + reset_control_deassert(tspi->rst); complete(&tspi->xfer_completion); spin_unlock_irqrestore(&tspi->lock, flags); return IRQ_HANDLED; @@ -1127,6 +1128,13 @@ static int tegra_spi_probe(struct platform_device *pdev) goto exit_free_irq; } + tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); + if (IS_ERR(tspi->rst)) { + dev_err(&pdev->dev, "can not get reset\n"); + ret = PTR_ERR(tspi->rst); + goto exit_free_irq; + } + tspi->max_buf_size = SPI_FIFO_DEPTH << 2; tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 4dc8e8129459..e6f382b33818 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -32,8 +32,8 @@ #include #include #include +#include #include -#include #define SPI_COMMAND 0x000 #define SPI_GO BIT(30) @@ -118,6 +118,7 @@ struct tegra_sflash_data { spinlock_t lock; struct clk *clk; + struct reset_control *rst; void __iomem *base; unsigned irq; u32 spi_max_frequency; @@ -389,9 +390,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_sflash_data *tsd) dev_err(tsd->dev, "CpuXfer 0x%08x:0x%08x\n", tsd->command_reg, tsd->dma_control_reg); - tegra_periph_reset_assert(tsd->clk); + reset_control_assert(tsd->rst); udelay(2); - tegra_periph_reset_deassert(tsd->clk); + reset_control_deassert(tsd->rst); complete(&tsd->xfer_completion); goto exit; } @@ -505,6 +506,13 @@ static int tegra_sflash_probe(struct platform_device *pdev) goto exit_free_irq; } + tsd->rst = devm_reset_control_get(&pdev->dev, "spi"); + if (IS_ERR(tsd->rst)) { + dev_err(&pdev->dev, "can not get reset\n"); + ret = PTR_ERR(tsd->rst); + goto exit_free_irq; + } + init_completion(&tsd->xfer_completion); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { @@ -520,9 +528,9 @@ static int tegra_sflash_probe(struct platform_device *pdev) } /* Reset controller */ - tegra_periph_reset_assert(tsd->clk); + reset_control_assert(tsd->rst); udelay(2); - tegra_periph_reset_deassert(tsd->clk); + reset_control_deassert(tsd->rst); tsd->def_command_reg = SPI_M_S | SPI_CS_SW; tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index e66715ba37ed..1305b8f933ba 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -33,8 +33,8 @@ #include #include #include +#include #include -#include #define SLINK_COMMAND 0x000 #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) @@ -167,6 +167,7 @@ struct tegra_slink_data { spinlock_t lock; struct clk *clk; + struct reset_control *rst; void __iomem *base; phys_addr_t phys; unsigned irq; @@ -884,9 +885,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, tspi->command2_reg, tspi->dma_control_reg); - tegra_periph_reset_assert(tspi->clk); + reset_control_assert(tspi->rst); udelay(2); - tegra_periph_reset_deassert(tspi->clk); + reset_control_deassert(tspi->rst); complete(&tspi->xfer_completion); goto exit; } @@ -957,9 +958,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi) dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, tspi->command2_reg, tspi->dma_control_reg); - tegra_periph_reset_assert(tspi->clk); + reset_control_assert(tspi->rst); udelay(2); - tegra_periph_reset_deassert(tspi->clk); + reset_control_assert(tspi->rst); complete(&tspi->xfer_completion); spin_unlock_irqrestore(&tspi->lock, flags); return IRQ_HANDLED; @@ -1118,6 +1119,13 @@ static int tegra_slink_probe(struct platform_device *pdev) goto exit_free_irq; } + tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); + if (IS_ERR(tspi->rst)) { + dev_err(&pdev->dev, "can not get reset\n"); + ret = PTR_ERR(tspi->rst); + goto exit_free_irq; + } + tspi->max_buf_size = SLINK_FIFO_DEPTH << 2; tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; -- cgit v1.2.3 From a915d150f68d8fd8ad72de6d9d4d7be26813b214 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 11 Nov 2013 13:13:47 -0700 Subject: spi: tegra: convert to standard DMA DT bindings By using dma_request_slave_channel_or_err(), the DMA slave ID can be looked up from standard DT properties, and squirrelled away during channel allocation. Hence, there's no need to use a custom DT property to store the slave ID. Signed-off-by: Stephen Warren Acked-by: Mark Brown --- drivers/spi/spi-tegra114.c | 48 +++++++++++++++-------------------------- drivers/spi/spi-tegra20-slink.c | 48 +++++++++++++++-------------------------- 2 files changed, 34 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index f62e6e5e90e3..c8604981a058 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -178,7 +178,6 @@ struct tegra_spi_data { void __iomem *base; phys_addr_t phys; unsigned irq; - int dma_req_sel; u32 spi_max_frequency; u32 cur_speed; @@ -601,15 +600,15 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi, dma_addr_t dma_phys; int ret; struct dma_slave_config dma_sconfig; - dma_cap_mask_t mask; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_chan = dma_request_channel(mask, NULL, NULL); - if (!dma_chan) { - dev_err(tspi->dev, - "Dma channel is not available, will try later\n"); - return -EPROBE_DEFER; + dma_chan = dma_request_slave_channel_reason(tspi->dev, + dma_to_memory ? "rx" : "tx"); + if (IS_ERR(dma_chan)) { + ret = PTR_ERR(dma_chan); + if (ret != -EPROBE_DEFER) + dev_err(tspi->dev, + "Dma channel is not available: %d\n", ret); + return ret; } dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, @@ -620,7 +619,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi, return -ENOMEM; } - dma_sconfig.slave_id = tspi->dma_req_sel; if (dma_to_memory) { dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO; dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -1055,11 +1053,6 @@ static void tegra_spi_parse_dt(struct platform_device *pdev, struct tegra_spi_data *tspi) { struct device_node *np = pdev->dev.of_node; - u32 of_dma[2]; - - if (of_property_read_u32_array(np, "nvidia,dma-request-selector", - of_dma, 2) >= 0) - tspi->dma_req_sel = of_dma[1]; if (of_property_read_u32(np, "spi-max-frequency", &tspi->spi_max_frequency)) @@ -1138,22 +1131,15 @@ static int tegra_spi_probe(struct platform_device *pdev) tspi->max_buf_size = SPI_FIFO_DEPTH << 2; tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; - if (tspi->dma_req_sel) { - ret = tegra_spi_init_dma_param(tspi, true); - if (ret < 0) { - dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); - goto exit_free_irq; - } - - ret = tegra_spi_init_dma_param(tspi, false); - if (ret < 0) { - dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret); - goto exit_rx_dma_free; - } - tspi->max_buf_size = tspi->dma_buf_size; - init_completion(&tspi->tx_dma_complete); - init_completion(&tspi->rx_dma_complete); - } + ret = tegra_spi_init_dma_param(tspi, true); + if (ret < 0) + goto exit_free_irq; + ret = tegra_spi_init_dma_param(tspi, false); + if (ret < 0) + goto exit_rx_dma_free; + tspi->max_buf_size = tspi->dma_buf_size; + init_completion(&tspi->tx_dma_complete); + init_completion(&tspi->rx_dma_complete); init_completion(&tspi->xfer_completion); diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 1305b8f933ba..dd6f26c05947 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -171,7 +171,6 @@ struct tegra_slink_data { void __iomem *base; phys_addr_t phys; unsigned irq; - int dma_req_sel; u32 spi_max_frequency; u32 cur_speed; @@ -630,15 +629,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, dma_addr_t dma_phys; int ret; struct dma_slave_config dma_sconfig; - dma_cap_mask_t mask; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_chan = dma_request_channel(mask, NULL, NULL); - if (!dma_chan) { - dev_err(tspi->dev, - "Dma channel is not available, will try later\n"); - return -EPROBE_DEFER; + dma_chan = dma_request_slave_channel(tspi->dev, + dma_to_memory ? "rx" : "tx"); + if (IS_ERR(dma_chan)) { + ret = PTR_ERR(dma_chan); + if (ret != -EPROBE_DEFER) + dev_err(tspi->dev, + "Dma channel is not available: %d\n", ret); + return ret; } dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, @@ -649,7 +648,6 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, return -ENOMEM; } - dma_sconfig.slave_id = tspi->dma_req_sel; if (dma_to_memory) { dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -1021,11 +1019,6 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data) static void tegra_slink_parse_dt(struct tegra_slink_data *tspi) { struct device_node *np = tspi->dev->of_node; - u32 of_dma[2]; - - if (of_property_read_u32_array(np, "nvidia,dma-request-selector", - of_dma, 2) >= 0) - tspi->dma_req_sel = of_dma[1]; if (of_property_read_u32(np, "spi-max-frequency", &tspi->spi_max_frequency)) @@ -1129,22 +1122,15 @@ static int tegra_slink_probe(struct platform_device *pdev) tspi->max_buf_size = SLINK_FIFO_DEPTH << 2; tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; - if (tspi->dma_req_sel) { - ret = tegra_slink_init_dma_param(tspi, true); - if (ret < 0) { - dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); - goto exit_free_irq; - } - - ret = tegra_slink_init_dma_param(tspi, false); - if (ret < 0) { - dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret); - goto exit_rx_dma_free; - } - tspi->max_buf_size = tspi->dma_buf_size; - init_completion(&tspi->tx_dma_complete); - init_completion(&tspi->rx_dma_complete); - } + ret = tegra_slink_init_dma_param(tspi, true); + if (ret < 0) + goto exit_free_irq; + ret = tegra_slink_init_dma_param(tspi, false); + if (ret < 0) + goto exit_rx_dma_free; + tspi->max_buf_size = tspi->dma_buf_size; + init_completion(&tspi->tx_dma_complete); + init_completion(&tspi->rx_dma_complete); init_completion(&tspi->xfer_completion); -- cgit v1.2.3 From d3d654ef230d8b8370e1b2820589521282c868d8 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:50:44 -0700 Subject: serial: tegra: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Greg Kroah-Hartman Reviewed-by: Thierry Reding --- drivers/tty/serial/serial-tegra.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index dfe79ccc4fb3..4455481a3517 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -44,8 +45,6 @@ #include #include -#include - #define TEGRA_UART_TYPE "TEGRA_UART" #define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) #define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3) @@ -103,6 +102,7 @@ struct tegra_uart_port { const struct tegra_uart_chip_data *cdata; struct clk *uart_clk; + struct reset_control *rst; unsigned int current_baud; /* Register shadow */ @@ -832,9 +832,9 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup) clk_prepare_enable(tup->uart_clk); /* Reset the UART controller to clear all previous status.*/ - tegra_periph_reset_assert(tup->uart_clk); + reset_control_assert(tup->rst); udelay(10); - tegra_periph_reset_deassert(tup->uart_clk); + reset_control_deassert(tup->rst); tup->rx_in_progress = 0; tup->tx_in_progress = 0; @@ -1320,6 +1320,12 @@ static int tegra_uart_probe(struct platform_device *pdev) return PTR_ERR(tup->uart_clk); } + tup->rst = devm_reset_control_get(&pdev->dev, "serial"); + if (IS_ERR(tup->rst)) { + dev_err(&pdev->dev, "Couldn't get the reset\n"); + return PTR_ERR(tup->rst); + } + u->iotype = UPIO_MEM32; u->irq = platform_get_irq(pdev, 0); u->regshift = 2; -- cgit v1.2.3 From c2b329f56196cce5ebde42f0b6ffc3c12db4c826 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 11 Nov 2013 14:16:38 -0700 Subject: serial: tegra: convert to standard DMA DT bindings By using dma_request_slave_channel_or_err(), the DMA slave ID can be looked up from standard DT properties, and squirrelled away during channel allocation. Hence, there's no need to use a custom DT property to store the slave ID. Acked-by: Greg Kroah-Hartman Signed-off-by: Stephen Warren Reviewed-by: Thierry Reding --- drivers/tty/serial/serial-tegra.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 4455481a3517..d5c2a287b7e7 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -120,7 +120,6 @@ struct tegra_uart_port { bool rx_timeout; int rx_in_progress; int symb_bit; - int dma_req_sel; struct dma_chan *rx_dma_chan; struct dma_chan *tx_dma_chan; @@ -910,15 +909,14 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, dma_addr_t dma_phys; int ret; struct dma_slave_config dma_sconfig; - dma_cap_mask_t mask; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_chan = dma_request_channel(mask, NULL, NULL); - if (!dma_chan) { + dma_chan = dma_request_slave_channel_reason(tup->uport.dev, + dma_to_memory ? "rx" : "tx"); + if (IS_ERR(dma_chan)) { + ret = PTR_ERR(dma_chan); dev_err(tup->uport.dev, - "Dma channel is not available, will try later\n"); - return -EPROBE_DEFER; + "DMA channel alloc failed: %d\n", ret); + return ret; } if (dma_to_memory) { @@ -938,7 +936,6 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, dma_buf = tup->uport.state->xmit.buf; } - dma_sconfig.slave_id = tup->dma_req_sel; if (dma_to_memory) { dma_sconfig.src_addr = tup->uport.mapbase; dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; @@ -1222,17 +1219,8 @@ static int tegra_uart_parse_dt(struct platform_device *pdev, struct tegra_uart_port *tup) { struct device_node *np = pdev->dev.of_node; - u32 of_dma[2]; int port; - if (of_property_read_u32_array(np, "nvidia,dma-request-selector", - of_dma, 2) >= 0) { - tup->dma_req_sel = of_dma[1]; - } else { - dev_err(&pdev->dev, "missing dma requestor in device tree\n"); - return -EINVAL; - } - port = of_alias_get_id(np, "serial"); if (port < 0) { dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port); -- cgit v1.2.3 From fe6b0dfaba689ad5481037bdfbf31531b3e4c074 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:48:16 -0700 Subject: Input: tegra-kbc - use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Dmitry Torokhov Reviewed-by: Thierry Reding --- drivers/input/keyboard/tegra-kbc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 8508879f6faf..9757a58bc897 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #define KBC_MAX_KPENT 8 @@ -116,6 +116,7 @@ struct tegra_kbc { u32 wakeup_key; struct timer_list timer; struct clk *clk; + struct reset_control *rst; const struct tegra_kbc_hw_support *hw_support; int max_keys; int num_rows_and_columns; @@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) clk_prepare_enable(kbc->clk); /* Reset the KBC controller to clear all previous status.*/ - tegra_periph_reset_assert(kbc->clk); + reset_control_assert(kbc->rst); udelay(100); - tegra_periph_reset_deassert(kbc->clk); + reset_control_assert(kbc->rst); udelay(100); tegra_kbc_config_pins(kbc); @@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev) return PTR_ERR(kbc->clk); } + kbc->rst = devm_reset_control_get(&pdev->dev, "kbc"); + if (IS_ERR(kbc->rst)) { + dev_err(&pdev->dev, "failed to get keyboard reset\n"); + return PTR_ERR(kbc->rst); + } + /* * The time delay between two consecutive reads of the FIFO is * the sum of the repeat time and the time taken for scanning -- cgit v1.2.3 From 75606f5d32fabef51c1337eac274492c0470d774 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:53:58 -0700 Subject: USB: EHCI: tegra: use reset framework Tegra's clock driver now provides an implementation of the common reset API (include/linux/reset.h). Use this instead of the old Tegra- specific API; that will soon be removed. Signed-off-by: Stephen Warren Acked-by: Alan Stern Acked-by: Greg Kroah-Hartman Reviewed-by: Thierry Reding --- drivers/usb/host/ehci-tegra.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index b9fd0396011e..6f7e23dd1417 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +62,7 @@ static int (*orig_hub_control)(struct usb_hcd *hcd, struct tegra_ehci_hcd { struct tegra_usb_phy *phy; struct clk *clk; + struct reset_control *rst; int port_resuming; bool needs_double_reset; enum tegra_usb_phy_port_speed port_speed; @@ -385,13 +386,20 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto cleanup_hcd_create; } + tegra->rst = devm_reset_control_get(&pdev->dev, "usb"); + if (IS_ERR(tegra->rst)) { + dev_err(&pdev->dev, "Can't get ehci reset\n"); + err = PTR_ERR(tegra->rst); + goto cleanup_hcd_create; + } + err = clk_prepare_enable(tegra->clk); if (err) goto cleanup_hcd_create; - tegra_periph_reset_assert(tegra->clk); + reset_control_assert(tegra->rst); udelay(1); - tegra_periph_reset_deassert(tegra->clk); + reset_control_deassert(tegra->rst); u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); if (IS_ERR(u_phy)) { -- cgit v1.2.3 From 2ae77527bb1a510070d039aaa22d1ae9a5807b6f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Nov 2013 16:58:16 -0700 Subject: clk: tegra: remove legacy reset APIs Now that no code uses the custom Tegra module reset API, we can remove its implementation. Signed-off-by: Stephen Warren Reviewed-by: Thierry Reding Acked-By: Peter De Schrijver --- drivers/clk/tegra/clk-periph-gate.c | 22 -------------------- drivers/clk/tegra/clk-periph.c | 40 ------------------------------------- drivers/clk/tegra/clk.h | 1 - include/linux/clk/tegra.h | 7 ------- 4 files changed, 70 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index f38f33e3c65d..507015314827 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -36,8 +36,6 @@ static DEFINE_SPINLOCK(periph_ref_lock); #define read_rst(gate) \ readl_relaxed(gate->clk_base + (gate->regs->rst_reg)) -#define write_rst_set(val, gate) \ - writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg)) #define write_rst_clr(val, gate) \ writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg)) @@ -123,26 +121,6 @@ static void clk_periph_disable(struct clk_hw *hw) spin_unlock_irqrestore(&periph_ref_lock, flags); } -void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert) -{ - if (gate->flags & TEGRA_PERIPH_NO_RESET) - return; - - if (assert) { - /* - * If peripheral is in the APB bus then read the APB bus to - * flush the write operation in apb bus. This will avoid the - * peripheral access after disabling clock - */ - if (gate->flags & TEGRA_PERIPH_ON_APB) - tegra_read_chipid(); - - write_rst_set(periph_clk_to_bit(gate), gate); - } else { - write_rst_clr(periph_clk_to_bit(gate), gate); - } -} - const struct clk_ops tegra_clk_periph_gate_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index d62b396863c1..c534043c0481 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -111,46 +111,6 @@ static void clk_periph_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } -void tegra_periph_reset_deassert(struct clk *c) -{ - struct clk_hw *hw = __clk_get_hw(c); - struct tegra_clk_periph *periph = to_clk_periph(hw); - struct tegra_clk_periph_gate *gate; - - if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { - gate = to_clk_periph_gate(hw); - if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { - WARN_ON(1); - return; - } - } else { - gate = &periph->gate; - } - - tegra_periph_reset(gate, 0); -} -EXPORT_SYMBOL(tegra_periph_reset_deassert); - -void tegra_periph_reset_assert(struct clk *c) -{ - struct clk_hw *hw = __clk_get_hw(c); - struct tegra_clk_periph *periph = to_clk_periph(hw); - struct tegra_clk_periph_gate *gate; - - if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { - gate = to_clk_periph_gate(hw); - if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { - WARN_ON(1); - return; - } - } else { - gate = &periph->gate; - } - - tegra_periph_reset(gate, 1); -} -EXPORT_SYMBOL(tegra_periph_reset_assert); - const struct clk_ops tegra_clk_periph_ops = { .get_parent = clk_periph_get_parent, .set_parent = clk_periph_set_parent, diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 07c62f997371..16ec8d6bb87f 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -393,7 +393,6 @@ struct tegra_clk_periph_gate { #define TEGRA_PERIPH_NO_DIV BIT(4) #define TEGRA_PERIPH_NO_GATE BIT(5) -void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); extern const struct clk_ops tegra_clk_periph_gate_ops; struct clk *tegra_clk_register_periph_gate(const char *name, const char *parent_name, u8 gate_flags, void __iomem *clk_base, diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index 23a0ceee831f..3ca9fca827a2 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -120,13 +120,6 @@ static inline void tegra_cpu_clock_resume(void) } #endif -#ifdef CONFIG_ARCH_TEGRA -void tegra_periph_reset_deassert(struct clk *c); -void tegra_periph_reset_assert(struct clk *c); -#else -static inline void tegra_periph_reset_deassert(struct clk *c) {} -static inline void tegra_periph_reset_assert(struct clk *c) {} -#endif void tegra_clocks_apply_init_table(void); #endif /* __LINUX_CLK_TEGRA_H_ */ -- cgit v1.2.3 From a85f06badc3cff4069f2f5112cea63cd39d99920 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 7 Nov 2013 10:58:21 -0700 Subject: clk: tegra: remove bogus PCIE_XCLK The "pcie_xclk" clock is not actually a clock at all, but rather a reset domain. Now that the custom Tegra module reset API has been removed, we can remove the definition of any "clocks" that existed solely to support it. Signed-off-by: Stephen Warren Reviewed-by: Thierry Reding Acked-By: Peter De Schrijver --- drivers/clk/tegra/clk-tegra20.c | 6 ------ drivers/clk/tegra/clk-tegra30.c | 7 ------- include/dt-bindings/clock/tegra20-car.h | 2 +- include/dt-bindings/clock/tegra30-car.h | 2 +- 4 files changed, 2 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 5a6a60d9443a..dbace152b2fa 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -468,7 +468,6 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP }, { .con_id = "pex", .dt_id = TEGRA20_CLK_PEX }, { .con_id = "afi", .dt_id = TEGRA20_CLK_AFI }, - { .con_id = "pcie_xclk", .dt_id = TEGRA20_CLK_PCIE_XCLK }, { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 }, { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 }, { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K }, @@ -834,11 +833,6 @@ static void __init tegra20_periph_clk_init(void) periph_clk_enb_refcnt); clks[TEGRA20_CLK_PEX] = clk; - /* pcie_xclk */ - clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base, - 0, 74, periph_clk_enb_refcnt); - clks[TEGRA20_CLK_PCIE_XCLK] = clk; - /* cdev1 */ clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, 26000000); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 2e47383418c8..8b10c38b6e3c 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -649,7 +649,6 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_ISP }, { .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE }, { .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI }, - { .con_id = "pciex", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIEX }, { .con_id = "fuse", .dt_id = TEGRA30_CLK_FUSE }, { .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN }, { .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF }, @@ -1150,11 +1149,6 @@ static void __init tegra30_periph_clk_init(void) periph_clk_enb_refcnt); clks[TEGRA30_CLK_AFI] = clk; - /* pciex */ - clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0, - 74, periph_clk_enb_refcnt); - clks[TEGRA30_CLK_PCIEX] = clk; - /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, ARRAY_SIZE(mux_pllmcp_clkm), @@ -1395,7 +1389,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "nvavp", "bsea"), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML1, "tegra_sata_cml", NULL), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML0, "tegra_pcie", "cml"), - TEGRA_CLK_DUPLICATE(TEGRA30_CLK_PCIEX, "tegra_pcie", "pciex"), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VCP, "nvavp", "vcp"), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */ }; diff --git a/include/dt-bindings/clock/tegra20-car.h b/include/dt-bindings/clock/tegra20-car.h index a1ae9a8fdd6c..9406207cfac8 100644 --- a/include/dt-bindings/clock/tegra20-car.h +++ b/include/dt-bindings/clock/tegra20-car.h @@ -92,7 +92,7 @@ #define TEGRA20_CLK_OWR 71 #define TEGRA20_CLK_AFI 72 #define TEGRA20_CLK_CSITE 73 -#define TEGRA20_CLK_PCIE_XCLK 74 +/* 74 */ #define TEGRA20_CLK_AVPUCQ 75 #define TEGRA20_CLK_LA 76 /* 77 */ diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h index 22445820a929..889e49ba0aa3 100644 --- a/include/dt-bindings/clock/tegra30-car.h +++ b/include/dt-bindings/clock/tegra30-car.h @@ -92,7 +92,7 @@ #define TEGRA30_CLK_OWR 71 #define TEGRA30_CLK_AFI 72 #define TEGRA30_CLK_CSITE 73 -#define TEGRA30_CLK_PCIEX 74 +/* 74 */ #define TEGRA30_CLK_AVPUCQ 75 #define TEGRA30_CLK_LA 76 /* 77 */ -- cgit v1.2.3 From 8a0a1af30cbf56b41220a02e34835022c4d72f41 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 16 Dec 2013 17:02:10 +0300 Subject: spi: tegra: checking for ERR_PTR instead of NULL dma_request_slave_channel() returns NULL on error and not ERR_PTRs. I've fixed this by using dma_request_slave_channel_reason() which does return ERR_PTRs. Fixes: a915d150f68d ('spi: tegra: convert to standard DMA DT bindings') Signed-off-by: Dan Carpenter Signed-off-by: Stephen Warren --- drivers/spi/spi-tegra20-slink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index dd6f26c05947..a728bb82090f 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -630,8 +630,8 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, int ret; struct dma_slave_config dma_sconfig; - dma_chan = dma_request_slave_channel(tspi->dev, - dma_to_memory ? "rx" : "tx"); + dma_chan = dma_request_slave_channel_reason(tspi->dev, + dma_to_memory ? "rx" : "tx"); if (IS_ERR(dma_chan)) { ret = PTR_ERR(dma_chan); if (ret != -EPROBE_DEFER) -- cgit v1.2.3