diff options
author | Olof Johansson <olof@lixom.net> | 2013-12-26 11:03:29 -0800 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-12-26 11:03:29 -0800 |
commit | 770039fef4887d22b12525b62cc4ade1ca724173 (patch) | |
tree | 7408ae2a4dbe6a3b36af36976a04a968d951d6af /drivers | |
parent | 954e198eac14f6c34157bbf053149f3c2917cbbd (diff) | |
parent | 8a0a1af30cbf56b41220a02e34835022c4d72f41 (diff) |
Merge branch 'tegra/dma-reset-rework' into next/dt
Bringing in the tegra dma/reset framework cleanup as a base for the DT changes.
* tegra/dma-reset-rework: (320 commits)
spi: tegra: checking for ERR_PTR instead of NULL
ASoC: tegra: update module reset list for Tegra124
clk: tegra: remove bogus PCIE_XCLK
clk: tegra: remove legacy reset APIs
ARM: tegra: remove legacy DMA entries from DT
ARM: tegra: remove legacy clock entries from DT
USB: EHCI: tegra: use reset framework
Input: tegra-kbc - use reset framework
serial: tegra: convert to standard DMA DT bindings
serial: tegra: use reset framework
spi: tegra: convert to standard DMA DT bindings
spi: tegra: use reset framework
staging: nvec: use reset framework
i2c: tegra: use reset framework
ASoC: tegra: convert to standard DMA DT bindings
ASoC: tegra: allocate AHUB FIFO during probe() not startup()
ASoC: tegra: call pm_runtime APIs around register accesses
ASoC: tegra: use reset framework
dma: tegra: register as an OF DMA controller
dma: tegra: use reset framework
...
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers')
138 files changed, 5919 insertions, 3729 deletions
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/base/power/main.c b/drivers/base/power/main.c index 1b41fca3d65a..e3219dfd736c 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -29,6 +29,7 @@ #include <linux/async.h> #include <linux/suspend.h> #include <trace/events/power.h> +#include <linux/cpufreq.h> #include <linux/cpuidle.h> #include <linux/timer.h> @@ -540,6 +541,7 @@ static void dpm_resume_noirq(pm_message_t state) dpm_show_time(starttime, state, "noirq"); resume_device_irqs(); cpuidle_resume(); + cpufreq_resume(); } /** @@ -955,6 +957,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/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 432db1b59b00..c4a4c9006288 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); @@ -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); } diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index f49fac2d193a..f7dfb72884a4 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -6,7 +6,12 @@ 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-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 +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h new file mode 100644 index 000000000000..cf0c323f2c36 --- /dev/null +++ b/drivers/clk/tegra/clk-id.h @@ -0,0 +1,235 @@ +/* + * 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_adx1, + tegra_clk_afi, + tegra_clk_amx, + tegra_clk_amx1, + 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_clk72Mhz, + 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_cml0, + tegra_clk_cml1, + 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_dpaux, + 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_entropy, + 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_gpu, + 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_hdmi_audio, + tegra_clk_host1x, + tegra_clk_host1x_8, + tegra_clk_i2c1, + tegra_clk_i2c2, + tegra_clk_i2c3, + tegra_clk_i2c4, + tegra_clk_i2c5, + tegra_clk_i2c6, + 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_isp_8, + tegra_clk_ispb, + 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_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, + 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_p_out5, + 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_sor0, + tegra_clk_sor0_lvds, + 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_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, + 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 */ diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index bafee9895a24..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, @@ -151,12 +129,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..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, @@ -170,27 +130,50 @@ 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, - 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); + + 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; + 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; + periph->gate.enable_refcnt = periph_clk_enb_refcnt; clk = clk_register(NULL, &periph->hw); if (IS_ERR(clk)) @@ -209,7 +192,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, @@ -217,6 +200,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-pll.c b/drivers/clk/tegra/clk-pll.c index 197074a57754..2dd432266ef6 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) @@ -121,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) @@ -134,7 +180,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)) @@ -154,10 +200,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); @@ -171,13 +217,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; @@ -204,7 +250,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; @@ -223,12 +269,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); @@ -241,12 +287,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); @@ -326,7 +372,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; @@ -389,12 +435,11 @@ 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; } + cfg->output_rate >>= p_div; + if (pll->params->pdiv_tohw) { ret = _p_div_to_hw(hw, 1 << p_div); if (ret < 0) @@ -414,7 +459,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); @@ -450,7 +495,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); @@ -479,11 +524,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; @@ -505,7 +550,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) { @@ -524,11 +569,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; @@ -536,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; } @@ -559,18 +606,16 @@ 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) && - _calc_rate(hw, &cfg, rate, *prate)) { - WARN_ON(1); + _calc_rate(hw, &cfg, rate, *prate)) return -EINVAL; - } return cfg.output_rate; } @@ -586,17 +631,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); @@ -664,7 +711,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); @@ -680,7 +727,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)); @@ -744,7 +791,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) @@ -755,6 +802,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); @@ -1173,7 +1262,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) @@ -1217,6 +1306,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: @@ -1248,9 +1349,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; @@ -1261,10 +1361,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) @@ -1293,17 +1390,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); @@ -1317,17 +1412,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); @@ -1339,7 +1432,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, @@ -1386,21 +1479,46 @@ 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; - struct clk *clk; + struct clk *clk, *parent; + unsigned long parent_rate; + int err; + u32 val, val_iddq; + + parent = __clk_lookup(parent_name); + if (!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); - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + 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_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); @@ -1414,19 +1532,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 = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + 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, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1461,23 +1579,32 @@ 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; - struct clk *clk; + struct clk *clk, *parent; + unsigned long parent_rate; if (!pll_params->pdiv_tohw) return ERR_PTR(-EINVAL); - 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); + parent = __clk_lookup(parent_name); + if (!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_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); @@ -1491,10 +1618,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; @@ -1507,20 +1632,21 @@ 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); } - pll_flags |= TEGRA_PLL_BYPASS; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + pll_params->flags |= TEGRA_PLL_BYPASS; + pll = _tegra_init_pll(clk_base, pmc, pll_params, 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. @@ -1567,17 +1693,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); @@ -1587,11 +1711,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); } @@ -1603,3 +1729,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 (!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-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 <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#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-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 <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#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-periph.c b/drivers/clk/tegra/clk-tegra-periph.c new file mode 100644 index 000000000000..5c35885f4a7c --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -0,0 +1,674 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#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_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 +#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_I2C6 0x65c +#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_UARTE 0x1c4 +#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_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) + +#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,\ + 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,\ + 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,\ + 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,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _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, 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, 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, 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, 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, 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, NULL) + +#define NODIV(_name, _parents, _offset, \ + _mux_shift, _mux_mask, _clk_num, \ + _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, _lock) + +#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, NULL), \ + .flags = _flags \ + } + +#define PLLP_BASE 0xa0 +#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", \ + #_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 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), + 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("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), + 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), + 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), + 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), + 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), + 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), + 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), + 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), + 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 { + 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), + PLL_OUT(5, PLLP_OUTC, 24, 0, 16, pll_p_out5), +}; + +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-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 <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#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-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 <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#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 9467da7dee49..90d9d25f2228 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -23,30 +23,15 @@ #include <linux/delay.h> #include <linux/export.h> #include <linux/clk/tegra.h> +#include <dt-bindings/clock/tegra114-car.h> #include "clk.h" +#include "clk-id.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 @@ -73,25 +58,7 @@ #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 @@ -139,25 +106,6 @@ #define PLLE_AUX 0x48c #define PLLC_OUT 0x84 #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 -#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 @@ -166,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) @@ -196,91 +141,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 */ @@ -298,19 +160,13 @@ 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; 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_doubler_lock); -static DEFINE_SPINLOCK(clk_out_lock); -static DEFINE_SPINLOCK(sysrate_lock); static struct div_nmp pllxc_nmp = { .divm_shift = 0, @@ -370,6 +226,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 = { @@ -417,6 +275,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 = { @@ -437,6 +297,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 = { @@ -483,6 +345,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 = { @@ -516,6 +380,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[] = { @@ -543,6 +410,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[] = { @@ -579,6 +448,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 = { @@ -594,6 +466,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[] = { @@ -634,6 +509,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[] = { @@ -667,12 +545,15 @@ 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[] = { /* 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}, }; @@ -699,6 +580,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 = { @@ -725,53 +609,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, -}; - -/* 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, + .flags = TEGRA_PLL_USE_LOCK, }; /* possible OSC frequencies in Hz */ @@ -787,120 +625,6 @@ 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) \ - 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) - -#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) - -#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) - -#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,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _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) - -#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) - -#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) - -#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_mask, _clk_num, _regs, \ - _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, \ - _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) \ - 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) - -#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, \ - 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; @@ -934,122 +658,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", }; @@ -1064,8 +677,253 @@ static const struct clk_div_table pll_re_div_table[] = { { .val = 0, .div = 0 }, }; -static struct clk *clks[clk_max]; -static struct clk_onecell_data clk_data; +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 }, + { .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 }, + { .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 }, +}; + +static struct clk **clks; static unsigned long osc_freq; static unsigned long pll_ref_freq; @@ -1086,16 +944,14 @@ 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[clk_m] = clk; + clks[TEGRA114_CLK_CLK_M] = clk; /* pll_ref */ val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; 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[pll_ref] = clk; + clks[TEGRA114_CLK_PLL_REF] = clk; pll_ref_freq = osc_freq / pll_ref_div; @@ -1109,20 +965,17 @@ 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[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; } @@ -1208,63 +1061,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) { @@ -1272,104 +1068,34 @@ 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[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[pll_c_out1] = clk; - } + clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, + pmc, 0, &pll_c_params, 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); + 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); - clk_register_clkdev(clk, "pll_c2", NULL); - clks[pll_c2] = clk; + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, + &pll_c2_params, NULL); + 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); - clk_register_clkdev(clk, "pll_c3", NULL); - clks[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); - 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 | 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); - 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; + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, + &pll_c3_params, NULL); + clks[TEGRA114_CLK_PLL_C3] = 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, - pll_m_freq_table, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clks[TEGRA114_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -1378,41 +1104,20 @@ 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[pll_m_out1] = clk; + clks[TEGRA114_CLK_PLL_M_OUT1] = clk; /* PLLM_UD */ clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", 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[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; - /* 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, - 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); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + &pll_u_params, &pll_u_lock); + clks[TEGRA114_CLK_PLL_U] = clk; tegra114_utmi_param_configure(clk_base); @@ -1420,731 +1125,97 @@ 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[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, - 0, &pll_d_params, - 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; + &pll_d_params, &pll_d_lock); + 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, - 0, &pll_d2_params, - 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; + &pll_d2_params, &pll_d2_lock); + 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; - - /* 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; - - /* 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[TEGRA114_CLK_PLL_D2_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); - clk_register_clkdev(clk, "pll_re_vco", NULL); - clks[pll_re_vco] = clk; + 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); + 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; -} - -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 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); - 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); - clks[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; - - /* 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[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; - - /* 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[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; - - /* 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[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; - - /* 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[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; - - /* 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[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; - - /* 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_v_regs, - 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_v_regs, - 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_v_regs, - 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_v_regs, - 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_v_regs, - 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_v_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "spdif_2x", NULL); - clks[spdif_2x] = clk; -} - -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[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); - clks[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; - - /* 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[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; - - /* 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); - clk_register_clkdev(clk, "blink", NULL); - clks[blink] = clk; - + clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_ref", + clk_base, 0, &pll_e_params, NULL); + 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) +static __init void tegra114_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base) { struct clk *clk; + u32 val; - /* 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); - clk_register_clkdev(clk, "cclk_g", NULL); - clks[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); - clk_register_clkdev(clk, "cclk_lp", NULL); - clks[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); - 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_IGNORE_UNUSED, 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_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, - 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "pclk", NULL); - clks[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), -}; - -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), -}; + /* 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); -static __init void tegra114_periph_clk_init(void __iomem *clk_base) -{ - struct tegra_periph_init_data *data; - struct clk *clk; - int i; - u32 val; + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, + 1, 1); + clks[TEGRA114_CLK_XUSB_HS_SRC] = clk; - /* apbdma */ - clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, - 0, 34, &periph_h_regs, - periph_clk_enb_refcnt); - clks[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); - clk_register_clkdev(clk, NULL, "rtc-tegra"); - clks[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_h_regs, - periph_clk_enb_refcnt); - clks[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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* 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; - - /* dsia */ + /* 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[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_MUX] = 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[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_MUX] = 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[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; - - /* 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; - - /* 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; - - /* 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_h_regs, - periph_clk_enb_refcnt); - clks[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 */ @@ -2207,28 +1278,37 @@ 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_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}, + {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}, }; 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); } @@ -2359,7 +1439,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) { @@ -2381,29 +1460,24 @@ static void __init tegra114_clock_init(struct device_node *np) return; } + clks = tegra_clk_init(clk_base, TEGRA114_CLK_CLK_MAX, + TEGRA114_CLK_PERIPH_BANKS); + if (!clks) + return; + if (tegra114_osc_clk_init(clk_base) < 0) return; 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); - 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); + 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); + 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)); tegra_clk_apply_init_table = tegra114_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c new file mode 100644 index 000000000000..aff86b5bc745 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra124.c @@ -0,0 +1,1424 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> +#include <dt-bindings/clock/tegra124-car.h> + +#include "clk.h" +#include "clk-id.h" + +#define CLK_SOURCE_CSITE 0x1d4 +#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) + +/* 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; + +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 }, + { .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 }, +}; + +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; + +} + +/* 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. */ +} + +#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 = { + { .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(clk_base, 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; + + tegra_cpu_car_ops = &tegra124_cpu_car_ops; +} +CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 056f649d0d89..dbace152b2fa 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -22,30 +22,10 @@ #include <linux/of_address.h> #include <linux/clk/tegra.h> #include <linux/delay.h> +#include <dt-bindings/clock/tegra20-car.h> #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 +#include "clk-id.h" #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (3<<30) @@ -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 @@ -114,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 @@ -151,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 @@ -188,64 +137,32 @@ 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; -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) \ - TEGRA_INIT_DATA(_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, NULL, NULL, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _regs, _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, _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) - -#define TEGRA_INIT_DATA_DIV16(_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, 16, 0, TEGRA_DIVIDER_ROUND_UP, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ +#define TEGRA_INIT_DATA_DIV16(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + 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, \ - _mux_shift, _mux_width, _clk_num, _regs, \ +#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, \ - _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + 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[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 }, @@ -383,6 +300,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 = { @@ -397,6 +316,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 = { @@ -411,6 +332,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 = { @@ -425,6 +349,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 = { @@ -439,6 +365,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[] = { @@ -460,6 +388,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 = { @@ -474,6 +404,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 = { @@ -488,34 +420,160 @@ 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, }; -/* 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_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 = "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 }, + { .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 = "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_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 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) @@ -577,10 +635,8 @@ 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); - clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; + &pll_c_params, NULL); + clks[TEGRA20_CLK_PLL_C] = clk; /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", @@ -589,71 +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, - 216000000, &pll_p_params, TEGRA_PLL_FIXED | - TEGRA_PLL_HAS_CPCON, pll_p_freq_table, 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, 0, - &pll_m_params, TEGRA_PLL_HAS_CPCON, - pll_m_freq_table, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clks[TEGRA20_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -662,42 +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, - 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, - pll_x_freq_table, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; + &pll_x_params, NULL); + clks[TEGRA20_CLK_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); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + &pll_u_params, NULL); + clks[TEGRA20_CLK_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); - clk_register_clkdev(clk, "pll_d", NULL); - clks[pll_d] = clk; + &pll_d_params, NULL); + 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, - 0, &pll_a_params, TEGRA_PLL_HAS_CPCON, - pll_a_freq_table, NULL); - clk_register_clkdev(clk, "pll_a", NULL); - clks[pll_a] = clk; + &pll_a_params, NULL); + clks[TEGRA20_CLK_PLL_A] = clk; /* PLLA_OUT0 */ clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", @@ -706,15 +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, 100000000, &pll_e_params, - 0, pll_e_freq_table, NULL); - clk_register_clkdev(clk, "pll_e", NULL); - clks[pll_e] = clk; + 0, &pll_e_params, NULL); + clks[TEGRA20_CLK_PLL_E] = clk; } static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", @@ -732,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", @@ -784,18 +746,16 @@ 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", 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; + clks[TEGRA20_CLK_AUDIO_2X] = clk; } @@ -803,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, &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", 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, &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", 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) @@ -876,69 +804,13 @@ 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_register_clkdev(clk, NULL, "tegra20-ac97"); - clks[ac97] = clk; + clk_base, 0, 3, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_AC97] = clk; /* apbdma */ clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, - 0, 34, &periph_h_regs, - 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_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); - 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_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_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_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_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_register_clkdev(clk, "bsev", "tegra-aes"); - clks[bsev] = clk; + 0, 34, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_APBDMA] = clk; /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, @@ -947,130 +819,52 @@ 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); - 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); - 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); - 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); - clk_register_clkdev(clk, NULL, "tegra-ehci.2"); - clks[usb3] = clk; + 57, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_EMC] = 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); - 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); - 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_u_regs, 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); - 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); - clk_register_clkdev(clk, "pcie_xclk", NULL); - clks[pcie_xclk] = clk; + clks[TEGRA20_CLK_PEX] = 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_u_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "cdev1", NULL); - clks[cdev1] = clk; + clk_base, 0, 94, periph_clk_enb_refcnt); + 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_u_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "cdev2", NULL); - clks[cdev2] = clk; + clk_base, 0, 93, periph_clk_enb_refcnt); + 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->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); 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->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) @@ -1084,15 +878,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 */ @@ -1226,49 +1018,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); } /* @@ -1277,11 +1069,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 = { @@ -1291,7 +1083,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); @@ -1312,30 +1103,24 @@ static void __init tegra20_clock_init(struct device_node *np) BUG(); } + clks = tegra_clk_init(clk_base, 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, TEGRA20_CLK_CLK_MAX); - 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_register_devclks(devclks, ARRAY_SIZE(devclks)); 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 dbe7c8003c5c..8b10c38b6e3c 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -23,42 +23,9 @@ #include <linux/of_address.h> #include <linux/clk/tegra.h> #include <linux/tegra-powergate.h> - +#include <dt-bindings/clock/tegra30-car.h> #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 +#include "clk-id.h" #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) @@ -92,6 +59,8 @@ #define SYSTEM_CLK_RATE 0x030 +#define TEGRA30_CLK_PERIPH_BANKS 5 + #define PLLC_BASE 0x80 #define PLLC_MISC 0x8c #define PLLM_BASE 0x90 @@ -132,88 +101,21 @@ #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) @@ -266,89 +168,41 @@ 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; -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, \ - _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) - -#define TEGRA_INIT_DATA_DIV16(_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, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ - _regs, _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) \ - 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) - -#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) -#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) +#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + 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_MUX8(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + 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, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + 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_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, _clk_num, _regs, \ +#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, \ - _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + 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[clk_max]; -static struct clk_onecell_data clk_data; +static struct clk **clks; /* * Structure defining the fields for USB UTMI clocks Parameters. @@ -564,6 +418,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 = { @@ -593,6 +449,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 = { @@ -607,6 +466,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 = { @@ -621,6 +483,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 = { @@ -635,6 +499,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 = { @@ -649,6 +517,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 = { @@ -664,6 +535,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 = { @@ -678,6 +551,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 = { @@ -692,116 +568,299 @@ 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, }; -/* 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 unsigned long tegra30_input_freq[] = { + [0] = 13000000, + [1] = 16800000, + [4] = 19200000, + [5] = 38400000, + [8] = 12000000, + [9] = 48000000, + [12] = 260000000, }; -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_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 = "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 }, + { .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_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 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_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 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); - 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 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 void tegra30_utmi_param_configure(void) { u32 reg; @@ -863,11 +922,8 @@ 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); - clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; + &pll_c_params, NULL); + clks[TEGRA30_CLK_PLL_C] = clk; /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", @@ -876,73 +932,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, - 408000000, &pll_p_params, - TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_USE_LOCK, pll_p_freq_table, 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, 0, - &pll_m_params, TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, - pll_m_freq_table, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clks[TEGRA30_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -951,78 +947,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, - 0, &pll_x_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, - pll_x_freq_table, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; + &pll_x_params, NULL); + 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, - 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON, - pll_u_freq_table, - NULL); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + &pll_u_params, NULL); + 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, - 0, &pll_d_params, 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; + &pll_d_params, &pll_d_lock); + 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, - 0, &pll_d2_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, - pll_d_freq_table, NULL); - clk_register_clkdev(clk, "pll_d2", NULL); - clks[pll_d2] = clk; + &pll_d2_params, NULL); + 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, 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; - - /* 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, @@ -1030,258 +992,8 @@ 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_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_v_regs, - 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_v_regs, - 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_v_regs, - 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_v_regs, - 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_v_regs, - 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_v_regs, - 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; - + CLK_GET_RATE_NOCACHE, &pll_e_params, NULL); + clks[TEGRA30_CLK_PLL_E] = clk; } static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", @@ -1332,8 +1044,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 @@ -1369,8 +1080,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, @@ -1378,142 +1088,44 @@ 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 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("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("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), + 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[] = { - 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("dsib", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, 0, TEGRA30_CLK_DSIB), }; static void __init tegra30_periph_clk_init(void) @@ -1522,170 +1134,20 @@ 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_h_regs, 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_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); - 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_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_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_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_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_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); - 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); - 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); - 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); - 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); - 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); - clk_register_clkdev(clk, "isp", "tegra_camera"); - clks[isp] = clk; + 0, 48, periph_clk_enb_refcnt); + clks[TEGRA30_CLK_DSIA] = clk; /* pcie */ clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, - 70, &periph_u_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pcie", "tegra-pcie"); - clks[pcie] = clk; + 70, periph_clk_enb_refcnt); + clks[TEGRA30_CLK_PCIE] = clk; /* afi */ clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, - &periph_u_regs, 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); - 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_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_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_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_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_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_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_register_clkdev(clk, NULL, "dtv"); - clks[dtv] = clk; + clks[TEGRA30_CLK_AFI] = clk; /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, @@ -1694,84 +1156,37 @@ 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); - clk_register_clkdev(clk, "emc", NULL); - clks[emc] = clk; + 57, periph_clk_enb_refcnt); + 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->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); 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->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 */ @@ -1913,48 +1328,49 @@ 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_GR3D2, 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); } /* @@ -1963,19 +1379,18 @@ 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_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 = { @@ -1986,7 +1401,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) { @@ -2006,29 +1420,27 @@ static void __init tegra30_clock_init(struct device_node *np) BUG(); } - tegra30_osc_clk_init(); - tegra30_fixed_clk_init(); + clks = tegra_clk_init(clk_base, TEGRA30_CLK_CLK_MAX, + TEGRA30_CLK_PERIPH_BANKS); + if (!clks) + return; + + 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(); - - 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_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); - 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_register_devclks(devclks, ARRAY_SIZE(devclks)); 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 86581ac1fd69..c0a7d7723510 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -18,13 +18,175 @@ #include <linux/clk-provider.h> #include <linux/of.h> #include <linux/clk/tegra.h> +#include <linux/reset-controller.h> +#include <linux/tegra-soc.h> #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 +#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; 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] = { + .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, + }, + [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, + }, +}; + +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; + + if (reg_bank < periph_banks) + return &periph_regs[reg_bank]; + else { + WARN_ON(1); + return NULL; + } +} + +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; + + periph_clk_enb_refcnt = kzalloc(32 * banks * + sizeof(*periph_clk_enb_refcnt), GFP_KERNEL); + if (!periph_clk_enb_refcnt) + return NULL; + + periph_banks = banks; + + 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, struct clk *clks[], int clk_max) { @@ -74,6 +236,58 @@ 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; + + 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); + + 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) +{ + 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) +{ + 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 07cfacd91686..16ec8d6bb87f 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); @@ -188,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; }; /** @@ -233,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; }; @@ -258,56 +260,49 @@ 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); +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 * @@ -395,13 +390,13 @@ 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) +#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, - 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,26 +438,26 @@ 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, \ - _gate_flags, _table) \ + _div_flags, _clk_num,\ + _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, \ .clk_num = _clk_num, \ - .enable_refcnt = _enb_refcnt, \ - .regs = _regs, \ }, \ .mux_ops = &clk_mux_ops, \ .div_ops = &tegra_clk_frac_div_ops, \ @@ -472,7 +467,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; @@ -483,20 +481,19 @@ 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, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ - _flags) \ + _div_width, _div_frac_width, _div_flags, \ + _clk_num, _gate_flags, _clk_id, _table, \ + _flags, _lock) \ { \ .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, \ _div_width, _div_frac_width, \ _div_flags, _clk_num, \ - _enb_refcnt, _regs, \ - _gate_flags, _table), \ + _gate_flags, _table, _lock), \ .offset = _offset, \ .con_id = _con_id, \ .dev_id = _dev_id, \ @@ -505,13 +502,13 @@ 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, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ + _div_width, _div_frac_width, _div_flags, \ + _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, \ - _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ - NULL, 0) + _clk_num, _gate_flags, _clk_id,\ + NULL, 0, NULL) /** * struct clk_super_mux - super clock @@ -581,12 +578,49 @@ struct tegra_clk_duplicate { }, \ } +struct tegra_clk { + int dt_id; + 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); 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(void __iomem *clk_base, 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 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 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 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); void tegra114_clock_tune_cpu_trimmers_init(void); 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 diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 4aac9ee0d0c0..3cf12834681e 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -313,8 +313,20 @@ 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 = 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 err3; + + return 0; + err3: + clk_unprepare(p->clk); + err2: + clk_put(p->clk); err1: iounmap(p->mapbase); err0: diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 78b8dae49628..63557cda0a7d 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -472,12 +472,26 @@ 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; - 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 err3; + + return 0; + + err3: + clk_unprepare(p->clk); + err2: + clk_put(p->clk); err1: iounmap(p->mapbase); err0: diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 02d534da22dd..81e9d4412db8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -26,6 +26,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/slab.h> +#include <linux/suspend.h> #include <linux/syscore_ops.h> #include <linux/tick.h> #include <trace/events/power.h> @@ -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) { @@ -2076,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); 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(); 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); 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 <linux/of_irq.h> +#include <linux/of_address.h> #include "compat.h" #include "regs.h" diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 905de4427e7c..b44f4ddc565c 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; } @@ -1108,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; @@ -1122,10 +1127,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. @@ -1141,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; } /* @@ -1173,9 +1176,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); } @@ -1197,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); @@ -1206,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) @@ -1216,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); @@ -1239,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); @@ -1285,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); @@ -1441,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); @@ -1449,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) @@ -1459,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); @@ -1476,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); @@ -1628,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) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ea806bdc12ef..24095ff8a93b 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -535,11 +535,41 @@ 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 * @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 +621,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/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/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/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 73654e33f13b..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,11 +29,12 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/of_dma.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/slab.h> -#include <linux/clk/tegra.h> #include "dmaengine.h" @@ -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; }; @@ -208,6 +210,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; @@ -339,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; } @@ -941,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; @@ -1085,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; @@ -1205,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 */ @@ -1282,6 +1306,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 +1332,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); @@ -1376,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]; 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 <krh@bitplanet.net>"); diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index 5002d50e3781..743fd426f21b 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; } @@ -39,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; @@ -57,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; @@ -67,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; @@ -79,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; @@ -91,19 +95,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 +222,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 +303,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; } @@ -199,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; @@ -214,10 +343,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/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) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ac53a9593662..85f772c0b26a 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; @@ -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,13 +2431,23 @@ 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)) { - dev_warn(dev, "lookup for GPIO %s failed\n", con_id); + dev_dbg(dev, "lookup for GPIO %s failed\n", con_id); return desc; } 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 <linux/clk.h> -#include <linux/clk/tegra.h> #include <linux/debugfs.h> +#include <linux/reset.h> #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 <drm/drm_fb_helper.h> #include <drm/drm_fixed.h> +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..0cbb24b1ae04 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -11,6 +11,7 @@ #include <linux/host1x.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/reset.h> #include <linux/tegra-powergate.h> #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,15 +258,29 @@ 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); + 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; @@ -271,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/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 <linux/clk.h> -#include <linux/clk/tegra.h> #include <linux/debugfs.h> #include <linux/hdmi.h> #include <linux/regulator/consumer.h> +#include <linux/reset.h> #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; 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 <linux/slab.h> #include <linux/of_device.h> #include <linux/module.h> -#include <linux/clk/tegra.h> +#include <linux/reset.h> #include <asm/unaligned.h> @@ -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) 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 }, 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 <linux/clk.h> #include <linux/slab.h> #include <linux/input/matrix_keypad.h> -#include <linux/clk/tegra.h> +#include <linux/reset.h> #include <linux/err.h> #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 diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 9031171c141b..341c6016812d 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -957,12 +957,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); 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); diff --git a/drivers/md/md.c b/drivers/md/md.c index e60cebf3f519..21f4d7ff0da2 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/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"); 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)) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index e3fc07cf2f62..77061eebb034 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; } /* @@ -754,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; @@ -872,7 +882,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; 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); 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); 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); } } 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_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, diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index abde97471636..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); } @@ -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; } @@ -4599,6 +4597,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 +4633,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) diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 58c147271a36..f9313b36c887 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 @@ -312,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 e38622825fa7..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) @@ -544,21 +551,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 +1310,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); @@ -1440,6 +1433,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); @@ -2325,11 +2322,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); } /** @@ -2345,9 +2339,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)) && @@ -2368,7 +2359,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) @@ -2422,10 +2412,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; @@ -2516,7 +2502,7 @@ link_up: adapter->tx_timeout_count++; schedule_work(&adapter->reset_task); /* exit immediately since reset is imminent */ - goto unlock; + return; } } @@ -2544,9 +2530,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 { @@ -3495,10 +3478,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); } /** @@ -4963,6 +4944,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); } 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: diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 0c55079ebee3..cc06854296a3 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; @@ -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: 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); 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) { 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); } 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); } 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); } 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 <asm/mach-types.h> @@ -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) /* 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); diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index dc76670c2f2a..9093004f9b63 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; @@ -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; } 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); @@ -246,6 +248,18 @@ static struct phy_driver vsc82xx_driver[] = { .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", .phy_id_mask = 0x000ffff0, @@ -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 }, 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; } diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 7bab4de658a9..916241d16c67 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -299,35 +299,76 @@ 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_small(void *buf, unsigned int len) { - struct skb_vnet_hdr *hdr = skb_vnet_hdr(head_skb); + 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, + unsigned int len) +{ + 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 +382,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 +391,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) @@ -362,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)) { @@ -377,33 +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) { - 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); - return; - } - if (receive_mergeable(rq, skb)) { - dev_kfree_skb(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; - } - } + if (vi->mergeable_rx_bufs) + skb = receive_mergeable(dev, rq, buf, len); + 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); @@ -1084,7 +1124,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); } 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 <linux/udp.h> #include <net/tcp.h> +#include <net/ip6_checksum.h> #include <xen/xen.h> #include <xen/events.h> diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 0afbbbc55c81..0175041ab728 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -25,7 +25,6 @@ */ #include <linux/clk.h> -#include <linux/clk/tegra.h> #include <linux/delay.h> #include <linux/export.h> #include <linux/interrupt.h> @@ -39,6 +38,7 @@ #include <linux/of_platform.h> #include <linux/pci.h> #include <linux/platform_device.h> +#include <linux/reset.h> #include <linux/sizes.h> #include <linux/slab.h> #include <linux/tegra-cpuidle.h> @@ -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); @@ -952,13 +955,14 @@ 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; } - 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 +1000,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 +1013,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 +1042,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); 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: 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 */ diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index e939c28cbf1f..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; @@ -1453,8 +1454,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); 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; } 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; } 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 = { 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; 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/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); } 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..20a5e6ecf945 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, }; @@ -1288,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 */ @@ -4925,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); 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/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); 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/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/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 34f5f5ffef05..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) { @@ -1169,6 +1183,7 @@ module_exit(pm8001_exit); MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>"); MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>"); MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>"); +MODULE_AUTHOR("Nikith Ganigarakoppal <Nikith.Ganigarakoppal@pmcs.com>"); MODULE_DESCRIPTION( "PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 " "SAS/SATA controller driver"); 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); 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 { 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 diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index bd6f743d87a7..be8ce54f99b2 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. @@ -4315,6 +4325,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/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-bcm2835.c b/drivers/spi/spi-bcm2835.c index 3ed666fe840a..9025edd7dc45 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); 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 */ diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 9602bbd8d7ea..87676587d783 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -557,7 +557,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); diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 73afb56c08cc..3adebfa22e3d 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; diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index cb0e1f1137ad..7765b1999537 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 }, { }, }; @@ -1291,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) { 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; } diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index aaecfb3ebf58..c8604981a058 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -17,7 +17,6 @@ */ #include <linux/clk.h> -#include <linux/clk/tegra.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/dmaengine.h> @@ -34,6 +33,7 @@ #include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/reset.h> #include <linux/spi/spi.h> #define SPI_COMMAND1 0x000 @@ -174,10 +174,10 @@ struct tegra_spi_data { spinlock_t lock; struct clk *clk; + struct reset_control *rst; void __iomem *base; phys_addr_t phys; unsigned irq; - int dma_req_sel; u32 spi_max_frequency; u32 cur_speed; @@ -600,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, @@ -619,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; @@ -918,9 +917,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 +989,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; @@ -1054,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)) @@ -1127,25 +1121,25 @@ 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; - 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-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 <linux/pm_runtime.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/reset.h> #include <linux/spi/spi.h> -#include <linux/clk/tegra.h> #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..a728bb82090f 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -33,8 +33,8 @@ #include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/reset.h> #include <linux/spi/spi.h> -#include <linux/clk/tegra.h> #define SLINK_COMMAND 0x000 #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) @@ -167,10 +167,10 @@ struct tegra_slink_data { spinlock_t lock; struct clk *clk; + struct reset_control *rst; void __iomem *base; phys_addr_t phys; unsigned irq; - int dma_req_sel; u32 spi_max_frequency; u32 cur_speed; @@ -629,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_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, @@ -648,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; @@ -884,9 +883,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 +956,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; @@ -1020,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)) @@ -1118,25 +1112,25 @@ 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; - 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); diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 0b71270fbf67..4396bd448540 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; } @@ -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); @@ -517,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; } 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); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 18cc625d887f..349ebba4b199 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1415,7 +1415,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 { 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 <linux/slab.h> #include <linux/spinlock.h> #include <linux/workqueue.h> -#include <linux/clk/tegra.h> #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 <linux/list.h> #include <linux/mutex.h> #include <linux/notifier.h> +#include <linux/reset.h> #include <linux/spinlock.h> #include <linux/workqueue.h> @@ -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; diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index dfe79ccc4fb3..d5c2a287b7e7 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -34,6 +34,7 @@ #include <linux/of_device.h> #include <linux/pagemap.h> #include <linux/platform_device.h> +#include <linux/reset.h> #include <linux/serial.h> #include <linux/serial_8250.h> #include <linux/serial_core.h> @@ -44,8 +45,6 @@ #include <linux/tty.h> #include <linux/tty_flip.h> -#include <linux/clk/tegra.h> - #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 */ @@ -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; @@ -832,9 +831,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; @@ -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); @@ -1320,6 +1308,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; 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; 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 <linux/clk.h> -#include <linux/clk/tegra.h> #include <linux/dma-mapping.h> #include <linux/err.h> #include <linux/gpio.h> @@ -29,6 +28,7 @@ #include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/slab.h> #include <linux/usb/ehci_def.h> #include <linux/usb/tegra_usb_phy.h> @@ -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)) { 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) 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; } 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; 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, 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; } 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(); 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 |