diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 408c87bc7..ae01b29d7 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard/ obj-$(CONFIG_MACH_MX6Q_ARM2) += freescale-mx6-arm2/ obj-$(CONFIG_MACH_NESO) += guf-neso/ obj-$(CONFIG_MACH_NOMADIK_8815NHK) += nhk8815/ +obj-$(CONFIG_MACH_NVIDIA_BEAVER) += nvidia-beaver/ obj-$(CONFIG_MACH_NXDB500) += netx/ obj-$(CONFIG_MACH_OMAP343xSDP) += omap343xdsp/ obj-$(CONFIG_MACH_OMAP3EVM) += omap3evm/ diff --git a/arch/arm/boards/nvidia-beaver/Makefile b/arch/arm/boards/nvidia-beaver/Makefile new file mode 100644 index 000000000..d2d217319 --- /dev/null +++ b/arch/arm/boards/nvidia-beaver/Makefile @@ -0,0 +1,4 @@ +CFLAGS_pbl-entry.o := \ + -mcpu=arm7tdmi -march=armv4t \ + -fno-tree-switch-conversion -fno-jump-tables +lwl-y += entry.o diff --git a/arch/arm/boards/nvidia-beaver/entry.c b/arch/arm/boards/nvidia-beaver/entry.c new file mode 100644 index 000000000..25452a6a7 --- /dev/null +++ b/arch/arm/boards/nvidia-beaver/entry.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Lucas Stach + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +extern char __dtb_tegra30_beaver_start[]; + +ENTRY_FUNCTION(start_nvidia_beaver, r0, r1, r2) +{ + uint32_t fdt; + + tegra_cpu_lowlevel_setup(); + + tegra_dvc_init(); + tegra30_tps65911_cpu_rail_enable(); + + fdt = (uint32_t)__dtb_tegra30_beaver_start - get_runtime_offset(); + + tegra_avp_reset_vector(fdt); +} diff --git a/arch/arm/boards/toradex-colibri-t20/Makefile b/arch/arm/boards/toradex-colibri-t20/Makefile index 5be3dd0e7..d2d217319 100644 --- a/arch/arm/boards/toradex-colibri-t20/Makefile +++ b/arch/arm/boards/toradex-colibri-t20/Makefile @@ -1,2 +1,4 @@ -CFLAGS_pbl-entry.o := -mcpu=arm7tdmi -march=armv4t +CFLAGS_pbl-entry.o := \ + -mcpu=arm7tdmi -march=armv4t \ + -fno-tree-switch-conversion -fno-jump-tables lwl-y += entry.o diff --git a/arch/arm/boards/toshiba-ac100/Makefile b/arch/arm/boards/toshiba-ac100/Makefile index 4ef18c0ce..2b6c09e27 100644 --- a/arch/arm/boards/toshiba-ac100/Makefile +++ b/arch/arm/boards/toshiba-ac100/Makefile @@ -1,3 +1,5 @@ -CFLAGS_pbl-entry.o := -mcpu=arm7tdmi -march=armv4t +CFLAGS_pbl-entry.o := \ + -mcpu=arm7tdmi -march=armv4t \ + -fno-tree-switch-conversion -fno-jump-tables lwl-y += entry.o obj-y += board.o diff --git a/arch/arm/configs/tegra_v7_defconfig b/arch/arm/configs/tegra_v7_defconfig index f76b5017a..83d2851d8 100644 --- a/arch/arm/configs/tegra_v7_defconfig +++ b/arch/arm/configs/tegra_v7_defconfig @@ -1,6 +1,7 @@ CONFIG_ARCH_TEGRA=y CONFIG_MACH_TORADEX_COLIBRI_T20=y CONFIG_MACH_TOSHIBA_AC100=y +CONFIG_MACH_NVIDIA_BEAVER=y CONFIG_AEABI=y CONFIG_CMD_ARM_MMUINFO=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y @@ -8,22 +9,30 @@ CONFIG_ARM_UNWIND=y CONFIG_MMU=y CONFIG_STACK_SIZE=0x10000 CONFIG_MALLOC_SIZE=0x4000000 +CONFIG_KALLSYMS=y CONFIG_LONGHELP=y CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y +CONFIG_BLSPEC=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_CMD_EDIT=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LOADENV=y CONFIG_CMD_EXPORT=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_IOMEM=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOOTM_OFTREE=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_RESET=y CONFIG_CMD_OFTREE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_GPIO=y CONFIG_CMD_CLK=y +CONFIG_CMD_DETECT=y CONFIG_DRIVER_SERIAL_NS16550=y CONFIG_MCI=y +CONFIG_MCI_MMC_BOOT_PARTITIONS=y CONFIG_MCI_TEGRA=y diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index c2e9826a5..b8b7e7bc3 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -36,7 +36,8 @@ dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5_sockit.dtb \ socfpga_cyclone5_socrates.dtb dtb-$(CONFIG_ARCH_TEGRA) += \ tegra20-colibri-iris.dtb \ - tegra20-paz00.dtb + tegra20-paz00.dtb \ + tegra30-beaver.dtb BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME)) obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o @@ -48,6 +49,7 @@ pbl-$(CONFIG_MACH_FREESCALE_MX51_PDK) += imx51-babbage.dtb.o pbl-$(CONFIG_MACH_FREESCALE_MX53_LOCO) += imx53-qsb.dtb.o imx53-qsrb.dtb.o pbl-$(CONFIG_MACH_FREESCALE_MX53_VMX53) += imx53-voipac-bsb.dtb.o pbl-$(CONFIG_MACH_DFI_FS700_M60) += imx6q-dfi-fs700-m60-6q.dtb.o imx6dl-dfi-fs700-m60-6s.dtb.o +pbl-$(CONFIG_MACH_NVIDIA_BEAVER) += tegra30-beaver.dtb.o pbl-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore.dtb.o pbl-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o pbl-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o diff --git a/arch/arm/dts/tegra20-colibri-iris.dts b/arch/arm/dts/tegra20-colibri-iris.dts index ef5f2c11c..adfa91782 100644 --- a/arch/arm/dts/tegra20-colibri-iris.dts +++ b/arch/arm/dts/tegra20-colibri-iris.dts @@ -6,8 +6,8 @@ model = "Toradex Colibri T20 on Iris"; compatible = "toradex,iris", "toradex,colibri_t20", "nvidia,tegra20"; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; }; }; @@ -15,27 +15,39 @@ pinmux@70000014 { state_default: pinmux { hdint { - nvidia,tristate = <0>; + nvidia,tristate = ; }; i2cddc { - nvidia,tristate = <0>; + nvidia,tristate = ; }; sdio4 { - nvidia,tristate = <0>; + nvidia,tristate = ; }; uarta { - nvidia,tristate = <0>; + nvidia,tristate = ; }; uartd { - nvidia,tristate = <0>; + nvidia,tristate = ; }; }; }; + serial@70006000 { + status = "okay"; + }; + + serial@70006300 { + status = "okay"; + }; + + i2c_ddc: i2c@7000c400 { + status = "okay"; + }; + usb@c5000000 { status = "okay"; }; @@ -52,18 +64,6 @@ status = "okay"; }; - serial@70006000 { - status = "okay"; - }; - - serial@70006300 { - status = "okay"; - }; - - i2c_ddc: i2c@7000c400 { - status = "okay"; - }; - sdhci@c8000600 { status = "okay"; bus-width = <4>; diff --git a/arch/arm/dts/tegra30-beaver.dts b/arch/arm/dts/tegra30-beaver.dts new file mode 100644 index 000000000..1110b8974 --- /dev/null +++ b/arch/arm/dts/tegra30-beaver.dts @@ -0,0 +1,917 @@ +/dts-v1/; + +#include "tegra30.dtsi" + +/ { + model = "NVIDIA Tegra30 Beaver evaluation board"; + compatible = "nvidia,beaver", "nvidia,tegra30"; + + aliases { + rtc0 = "/i2c@7000d000/tps65911@2d"; + rtc1 = "/rtc@7000e000"; + }; + + memory { + reg = <0x80000000 0x7ff00000>; + }; + + pcie-controller@00003000 { + status = "okay"; + pex-clk-supply = <&sys_3v3_pexs_reg>; + vdd-supply = <&ldo1_reg>; + avdd-supply = <&ldo2_reg>; + + pci@1,0 { + status = "okay"; + nvidia,num-lanes = <2>; + }; + + pci@2,0 { + nvidia,num-lanes = <2>; + }; + + pci@3,0 { + status = "okay"; + nvidia,num-lanes = <2>; + }; + }; + + host1x@50000000 { + hdmi@54280000 { + status = "okay"; + + vdd-supply = <&sys_3v3_reg>; + pll-supply = <&vio_reg>; + + nvidia,hpd-gpio = + <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>; + nvidia,ddc-i2c-bus = <&hdmiddc>; + }; + }; + + pinmux@70000868 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + sdmmc1_clk_pz0 { + nvidia,pins = "sdmmc1_clk_pz0"; + nvidia,function = "sdmmc1"; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc1_cmd_pz1 { + nvidia,pins = "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4"; + nvidia,function = "sdmmc1"; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc3_clk_pa6 { + nvidia,pins = "sdmmc3_clk_pa6"; + nvidia,function = "sdmmc3"; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc3_cmd_pa7 { + nvidia,pins = "sdmmc3_cmd_pa7", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4"; + nvidia,function = "sdmmc3"; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc3_gpio { + nvidia,pins = "sdmmc3_dat4_pd1", + "sdmmc3_dat5_pd0"; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc4_rst { + nvidia,pins = "sdmmc4_rst_n_pcc3"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,io-reset = ; + nvidia,enable-input = ; + }; + sdmmc4_clk_pcc4 { + nvidia,pins = "sdmmc4_clk_pcc4"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,io-reset = ; + nvidia,enable-input = ; + }; + sdmmc4_dat0_paa0 { + nvidia,pins = "sdmmc4_cmd_pt7", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,io-reset = ; + nvidia,enable-input = ; + }; + crt { + nvidia,pins = "crt_hsync_pv6", + "crt_vsync_pv7"; + nvidia,function = "crt"; + nvidia,tristate = ; + }; + dap { + nvidia,pins = "clk1_req_pee2", + "clk2_req_pcc5"; + nvidia,function = "dap"; + nvidia,tristate = ; + }; + dev3 { + nvidia,pins = "clk3_req_pee1"; + nvidia,function = "dev3"; + nvidia,tristate = ; + }; + dap1 { + nvidia,pins = "dap1_fs_pn0", "dap1_dout_pn2", + "dap1_din_pn1", "dap1_sclk_pn3"; + nvidia,function = "i2s0"; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap2_fs_pa2 { + nvidia,pins = "dap2_fs_pa2", + "dap2_sclk_pa3", + "dap2_din_pa4", + "dap2_dout_pa5"; + nvidia,function = "i2s1"; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap3 { + nvidia,pins = "dap3_fs_pp0", "dap3_dout_pp2", + "dap3_din_pp1", "dap3_sclk_pp3"; + nvidia,function = "i2s2"; + nvidia,tristate = ; + }; + dap4 { + nvidia,pins = "dap4_fs_pp4", "dap4_dout_pp6", + "dap4_din_pp5", "dap4_sclk_pp7"; + nvidia,function = "i2s3"; + nvidia,tristate = ; + }; + pex_in { + nvidia,pins = "pex_l0_prsnt_n_pdd0", + "pex_l0_clkreq_n_pdd2", + "pex_l2_prsnt_n_pdd7", + "pex_l2_clkreq_n_pcc7", + "pex_wake_n_pdd3"; + nvidia,function = "pcie"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + pex_out { + nvidia,pins = "pex_l0_rst_n_pdd1", + "pex_l1_rst_n_pdd5", + "pex_l2_rst_n_pcc6"; + nvidia,function = "pcie"; + nvidia,tristate = ; + }; + pex_l1_prsnt_n_pdd4 { + nvidia,pins = "pex_l1_prsnt_n_pdd4", + "pex_l1_clkreq_n_pdd6"; + nvidia,pull = ; + }; + sdio3 { + nvidia,pins = "drive_sdio3"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,pull-down-strength = <46>; + nvidia,pull-up-strength = <42>; + nvidia,slew-rate-rising = <1>; + nvidia,slew-rate-falling = <1>; + }; + gpv { + nvidia,pins = "drive_gpv"; + nvidia,pull-up-strength = <16>; + }; + uarta { + nvidia,pins = "ulpi_data0_po1", + "ulpi_data1_po2", + "ulpi_data2_po3", + "ulpi_data3_po4", + "ulpi_data4_po5", + "ulpi_data5_po6", + "ulpi_data6_po7", + "ulpi_data7_po0"; + nvidia,function = "uarta"; + nvidia,tristate = <0>; + }; + pu { + nvidia,pins = "pu0", "pu1", "pu2", "pu3", + "pu4", "pu5", "pu6"; + nvidia,function = "rsvd4"; + nvidia,tristate = ; + }; + uartb { + nvidia,pins = "uart2_txd_pc2", + "uart2_rxd_pc3", + "uart2_cts_n_pj5", + "uart2_rts_n_pj6"; + nvidia,function = "uartb"; + nvidia,tristate = ; + }; + uartc { + nvidia,pins = "uart3_txd_pw6", + "uart3_rxd_pw7", + "uart3_cts_n_pa1", + "uart3_rts_n_pc0"; + nvidia,function = "uartc"; + nvidia,tristate = ; + }; + uartd { + nvidia,pins = "ulpi_clk_py0", "ulpi_dir_py1", + "ulpi_nxt_py2", "ulpi_stp_py3"; + nvidia,function = "uartd"; + nvidia,tristate = ; + }; + i2c1 { + nvidia,pins = "gen1_i2c_scl_pc4", + "gen1_i2c_sda_pc5"; + nvidia,function = "i2c1"; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + i2c2 { + nvidia,pins = "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6"; + nvidia,function = "i2c2"; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + i2c3 { + nvidia,pins = "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2"; + nvidia,function = "i2c3"; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + i2c4 { + nvidia,pins = "ddc_scl_pv4", + "ddc_sda_pv5"; + nvidia,function = "i2c4"; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + i2cpwr { + nvidia,pins = "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7"; + nvidia,function = "i2cpwr"; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + spi1 { + nvidia,pins = "spi1_mosi_px4", + "spi1_sck_px5", + "spi1_cs0_n_px6", + "spi1_miso_px7"; + nvidia,function = "spi1"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + spi2_up { + nvidia,pins = "spi2_cs1_n_pw2"; + nvidia,tristate = ; + nvidia,pull = ; + }; + spi4 { + nvidia,pins = "gmi_a16_pj7", "gmi_a17_pb0", + "gmi_a18_pb1", "gmi_a19_pk7"; + nvidia,function = "spi4"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + spdif { + nvidia,pins = "spdif_out_pk5", "spdif_in_pk6"; + nvidia,function = "spdif"; + nvidia,tristate = ; + }; + hdmi_int { + nvidia,pins = "hdmi_int_pn7"; + nvidia,function = "hdmi"; + nvidia,tristate = ; + }; + hdmi_cec { + nvidia,pins = "hdmi_cec_pee3"; + nvidia,function = "cec"; + nvidia,tristate = ; + }; + ddr { + nvidia,pins = "vi_d10_pt2", "vi_vsync_pd6", + "vi_hsync_pd7"; + nvidia,function = "ddr"; + nvidia,tristate = ; + }; + ddr_up { + nvidia,pins = "vi_d11_pt3"; + nvidia,function = "ddr"; + nvidia,tristate = ; + nvidia,pull = ; + nvidia,enable-input = ; + }; + vi { + nvidia,pins = "vi_d4_pl2", "vi_mclk_pt1", + "vi_d6_pl4"; + nvidia,function = "vi"; + nvidia,tristate = ; + }; + owr { + nvidia,pins = "pv2", "pu0", "owr"; + nvidia,function = "owr"; + nvidia,tristate = ; + }; + lcd { + nvidia,pins = "lcd_pwr1_pc1", "lcd_pwr2_pc6", + "lcd_sdin_pz2", "lcd_sdout_pn5", + "lcd_wr_n_pz3", "lcd_cs0_n_pn4", + "lcd_dc0_pn6", "lcd_sck_pz4", + "lcd_pwr0_pb2", "lcd_pclk_pb3", + "lcd_de_pj1", "lcd_hsync_pj3", + "lcd_vsync_pj4", "lcd_d0_pe0", + "lcd_d1_pe1", "lcd_d2_pe2", + "lcd_d3_pe3", "lcd_d4_pe4", + "lcd_d5_pe5", "lcd_d6_pe6", + "lcd_d7_pe7", "lcd_d8_pf0", + "lcd_d9_pf1", "lcd_d10_pf2", + "lcd_d11_pf3", "lcd_d12_pf4", + "lcd_d13_pf5", "lcd_d14_pf6", + "lcd_d15_pf7", "lcd_d16_pm0", + "lcd_d17_pm1", "lcd_d18_pm2", + "lcd_d19_pm3", "lcd_d20_pm4", + "lcd_d21_pm5", "lcd_d22_pm6", + "lcd_d23_pm7", "lcd_cs1_n_pw0", + "lcd_m1_pw1", "lcd_dc1_pd2"; + nvidia,function = "displaya"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kbc { + nvidia,pins = "kb_row0_pr0", "kb_row1_pr1", + "kb_row2_pr2", "kb_row3_pr3", + "kb_row4_pr4", "kb_row5_pr5", + "kb_row6_pr6", "kb_row7_pr7", + "kb_row9_ps1", "kb_row8_ps0", + "kb_row10_ps2", "kb_row11_ps3", + "kb_row12_ps4", "kb_row13_ps5", + "kb_row14_ps6", "kb_row15_ps7", + "kb_col0_pq0", "kb_col1_pq1", + "kb_col2_pq2", "kb_col3_pq3", + "kb_col4_pq4", "kb_col5_pq5", + "kb_col6_pq6", "kb_col7_pq7"; + nvidia,function = "kbc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gpio_vi { + nvidia,pins = "vi_d1_pd5", "vi_d2_pl0", + "vi_d3_pl1", "vi_d5_pl3", + "vi_d7_pl5", "vi_d8_pl6", + "vi_d9_pl7"; + nvidia,function = "sdmmc2"; + nvidia,tristate = ; + nvidia,io-reset = ; + nvidia,enable-input = ; + }; + gpio_pbb0 { + nvidia,pins = "pbb0", "pbb7", "pcc1", "pcc2"; + nvidia,function = "i2s4"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gpio_pbb3 { + nvidia,pins = "pbb3"; + nvidia,function = "vgp3"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gpio_pbb4 { + nvidia,pins = "pbb4"; + nvidia,function = "vgp4"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gpio_pbb5 { + nvidia,pins = "pbb5"; + nvidia,function = "vgp5"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gpio_pbb6 { + nvidia,pins = "pbb6"; + nvidia,function = "vgp6"; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gpio_pu1 { + nvidia,pins = "pu1", "pu2"; + nvidia,function = "rsvd1"; + nvidia,tristate = ; + }; + gpio_pv0 { + nvidia,pins = "pv0", "gmi_cs2_n_pk3"; + nvidia,function = "rsvd1"; + nvidia,tristate = ; + nvidia,pull = ; + }; + gpio_pv3 { + nvidia,pins = "pv3"; + nvidia,function = "clk_12m_out"; + nvidia,tristate = ; + }; + gpio_gmi { + nvidia,pins = "spi2_sck_px2", "gmi_wp_n_pc7"; + nvidia,function = "gmi"; + nvidia,tristate = ; + }; + gpio_gmi_ad { + nvidia,pins = "gmi_ad10_ph2", "gmi_ad14_ph6"; + nvidia,function = "nand"; + nvidia,tristate = ; + }; + gpio_gmi_ad_up { + nvidia,pins = "gmi_ad12_ph4"; + nvidia,function = "nand"; + nvidia,tristate = ; + nvidia,pull = ; + }; + gpio_gmi_iordy_up { + nvidia,pins = "gmi_iordy_pi5"; + nvidia,function = "rsvd1"; + nvidia,tristate = ; + nvidia,pull = ; + }; + pwm0 { + nvidia,pins = "gmi_ad8_ph0", "pu3"; + nvidia,function = "pwm0"; + nvidia,tristate = ; + }; + pwm1 { + nvidia,pins = "pu4"; + nvidia,function = "pwm1"; + nvidia,tristate = ; + }; + pwm2 { + nvidia,pins = "pu5"; + nvidia,function = "pwm2"; + nvidia,tristate = ; + }; + pwm3 { + nvidia,pins = "pu6"; + nvidia,function = "pwm3"; + nvidia,tristate = ; + }; + extperiph1 { + nvidia,pins = "clk1_out_pw4"; + nvidia,function = "extperiph1"; + nvidia,tristate = ; + }; + extperiph2 { + nvidia,pins = "clk2_out_pw5"; + nvidia,function = "extperiph2"; + nvidia,tristate = ; + }; + extperiph3 { + nvidia,pins = "clk3_out_pee0"; + nvidia,function = "extperiph3"; + nvidia,tristate = ; + }; + jtag { + nvidia,pins = "jtag_rtck_pu7"; + nvidia,function = "rtck"; + nvidia,tristate = ; + }; + blink { + nvidia,pins = "clk_32k_out_pa0"; + nvidia,function = "blink"; + nvidia,tristate = ; + }; + sysclk { + nvidia,pins = "sys_clk_req_pz5"; + nvidia,function = "sysclk"; + nvidia,tristate = ; + }; + cam_mclk { + nvidia,pins = "cam_mclk_pcc0"; + nvidia,function = "vi_alt3"; + nvidia,tristate = ; + nvidia,pull = ; + }; + vi_pclk { + nvidia,pins = "vi_pclk_pt0"; + nvidia,function = "rsvd1"; + nvidia,tristate = ; + nvidia,io-reset = ; + }; + unused { + nvidia,pins = "gmi_adv_n_pk0", "gmi_clk_pk1", + "gmi_cs3_n_pk4", "gmi_ad0_pg0", + "gmi_ad1_pg1", "gmi_ad2_pg2", + "gmi_ad3_pg3", "gmi_ad4_pg4", + "gmi_ad5_pg5", "gmi_ad6_pg6", + "gmi_ad7_pg7", "gmi_ad9_ph1", + "gmi_ad11_ph3", "gmi_wr_n_pi0", + "gmi_oe_n_pi1", "gmi_dqs_pi2"; + nvidia,function = "nand"; + nvidia,tristate = ; + }; + unused_pu { + nvidia,pins = "gmi_wait_pi7", "gmi_cs7_n_pi6", + "gmi_ad13_ph5"; + nvidia,function = "nand"; + nvidia,pull = ; + nvidia,tristate = ; + }; + }; + }; + + serial@70006000 { + status = "okay"; + }; + + i2c@7000c000 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c@7000c400 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c@7000c500 { + status = "okay"; + clock-frequency = <100000>; + }; + + hdmiddc: i2c@7000c700 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c@7000d000 { + status = "okay"; + clock-frequency = <100000>; + + rt5640: rt5640@1c { + compatible = "realtek,rt5640"; + reg = <0x1c>; + interrupt-parent = <&gpio>; + interrupts = ; + realtek,ldo1-en-gpios = + <&gpio TEGRA_GPIO(X, 2) GPIO_ACTIVE_HIGH>; + }; + + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + vcc1-supply = <&vdd_5v_in_reg>; + vcc2-supply = <&vdd_5v_in_reg>; + vcc3-supply = <&vio_reg>; + vcc4-supply = <&vdd_5v_in_reg>; + vcc5-supply = <&vdd_5v_in_reg>; + vcc6-supply = <&vdd2_reg>; + vcc7-supply = <&vdd_5v_in_reg>; + vccio-supply = <&vdd_5v_in_reg>; + + regulators { + #address-cells = <1>; + #size-cells = <0>; + + vdd1_reg: vdd1 { + regulator-name = "vddio_ddr_1v2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + vdd2_reg: vdd2 { + regulator-name = "vdd_1v5_gen"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + vddctrl_reg: vddctrl { + regulator-name = "vdd_cpu,vdd_sys"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + vio_reg: vio { + regulator-name = "vdd_1v8_gen"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo1_reg: ldo1 { + regulator-name = "vdd_pexa,vdd_pexb"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + }; + + ldo2_reg: ldo2 { + regulator-name = "vdd_sata,avdd_plle"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + }; + + /* LDO3 is not connected to anything */ + + ldo4_reg: ldo4 { + regulator-name = "vdd_rtc"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ldo5_reg: ldo5 { + regulator-name = "vddio_sdmmc,avdd_vdac"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ldo6_reg: ldo6 { + regulator-name = "avdd_dsi_csi,pwrdet_mipi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo7_reg: ldo7 { + regulator-name = "vdd_pllm,x,u,a_p_c_s"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ldo8_reg: ldo8 { + regulator-name = "vdd_ddr_hs"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + }; + }; + + tps62361@60 { + compatible = "ti,tps62361"; + reg = <0x60>; + + regulator-name = "tps62361-vout"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + ti,vsel0-state-high; + ti,vsel1-state-high; + }; + }; + + spi@7000da00 { + status = "okay"; + spi-max-frequency = <25000000>; + spi-flash@1 { + compatible = "winbond,w25q32"; + reg = <1>; + spi-max-frequency = <20000000>; + }; + }; + + pmc@7000e400 { + status = "okay"; + nvidia,invert-interrupt; + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <200>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <0>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + }; + + ahub@70080000 { + i2s@70080400 { + status = "okay"; + }; + }; + + sdhci@78000000 { + status = "okay"; + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>; + bus-width = <4>; + }; + + sdhci@78000600 { + status = "okay"; + bus-width = <8>; + non-removable; + }; + + usb@7d004000 { + status = "okay"; + }; + + phy2: usb-phy@7d004000 { + vbus-supply = <&sys_3v3_reg>; + status = "okay"; + }; + + usb@7d008000 { + status = "okay"; + }; + + usb-phy@7d008000 { + vbus-supply = <&usb3_vbus_reg>; + status = "okay"; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + clk32k_in: clock@0 { + compatible = "fixed-clock"; + reg=<0>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + gpled1 { + label = "LED1"; /* CR5A1 (blue) */ + gpios = <&gpio TEGRA_GPIO(L, 1) GPIO_ACTIVE_HIGH>; + }; + gpled2 { + label = "LED2"; /* CR4A2 (green) */ + gpios = <&gpio TEGRA_GPIO(L, 0) GPIO_ACTIVE_HIGH>; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_5v_in_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_5v_in"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + chargepump_5v_reg: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "chargepump_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + enable-active-high; + gpio = <&pmic 0 GPIO_ACTIVE_HIGH>; + }; + + ddr_reg: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "vdd_ddr"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpio = <&pmic 7 GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_5v_in_reg>; + }; + + vdd_5v_sata_reg: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "vdd_5v_sata"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(D, 6) GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_5v_in_reg>; + }; + + usb1_vbus_reg: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "usb1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(DD, 6) GPIO_ACTIVE_HIGH>; + gpio-open-drain; + vin-supply = <&vdd_5v_in_reg>; + }; + + usb3_vbus_reg: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + regulator-name = "usb3_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>; + gpio-open-drain; + vin-supply = <&vdd_5v_in_reg>; + }; + + sys_3v3_reg: regulator@6 { + compatible = "regulator-fixed"; + reg = <6>; + regulator-name = "sys_3v3,vdd_3v3_alw"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpio = <&pmic 6 GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_5v_in_reg>; + }; + + sys_3v3_pexs_reg: regulator@7 { + compatible = "regulator-fixed"; + reg = <7>; + regulator-name = "sys_3v3_pexs"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(L, 7) GPIO_ACTIVE_HIGH>; + vin-supply = <&sys_3v3_reg>; + }; + }; + + sound { + compatible = "nvidia,tegra-audio-rt5640-beaver", + "nvidia,tegra-audio-rt5640"; + nvidia,model = "NVIDIA Tegra Beaver"; + + nvidia,audio-routing = + "Headphones", "HPOR", + "Headphones", "HPOL", + "Mic Jack", "MICBIAS1", + "IN2P", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&rt5640>; + + nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>; + + clocks = <&tegra_car TEGRA30_CLK_PLL_A>, + <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA30_CLK_EXTERN1>; + clock-names = "pll_a", "pll_a_out0", "mclk"; + }; +}; diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi new file mode 100644 index 000000000..19a84e933 --- /dev/null +++ b/arch/arm/dts/tegra30.dtsi @@ -0,0 +1,892 @@ +#include +#include +#include +#include + +#include "skeleton.dtsi" + +/ { + compatible = "nvidia,tegra30"; + interrupt-parent = <&intc>; + + aliases { + serial0 = &uarta; + serial1 = &uartb; + serial2 = &uartc; + serial3 = &uartd; + serial4 = &uarte; + }; + + pcie-controller@00003000 { + compatible = "nvidia,tegra30-pcie"; + device_type = "pci"; + reg = <0x00003000 0x00000800 /* PADS registers */ + 0x00003800 0x00000200 /* AFI registers */ + 0x10000000 0x10000000>; /* configuration space */ + reg-names = "pads", "afi", "cs"; + interrupts = ; /* MSI interrupt */ + interrupt-names = "intr", "msi"; + + bus-range = <0x00 0xff>; + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x82000000 0 0x00000000 0x00000000 0 0x00001000 /* port 0 configuration space */ + 0x82000000 0 0x00001000 0x00001000 0 0x00001000 /* port 1 configuration space */ + 0x82000000 0 0x00004000 0x00004000 0 0x00001000 /* port 2 configuration space */ + 0x81000000 0 0 0x02000000 0 0x00010000 /* downstream I/O */ + 0x82000000 0 0x20000000 0x20000000 0 0x08000000 /* non-prefetchable memory */ + 0xc2000000 0 0x28000000 0x28000000 0 0x18000000>; /* prefetchable memory */ + + clocks = <&tegra_car TEGRA30_CLK_PCIE>, + <&tegra_car TEGRA30_CLK_AFI>, + <&tegra_car TEGRA30_CLK_PLL_E>, + <&tegra_car TEGRA30_CLK_CML0>; + clock-names = "pex", "afi", "pll_e", "cml"; + resets = <&tegra_car 70>, + <&tegra_car 72>, + <&tegra_car 74>; + reset-names = "pex", "afi", "pcie_x"; + status = "disabled"; + + pci@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x00000000 0 0x1000>; + reg = <0x000800 0 0 0 0>; + status = "disabled"; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + nvidia,num-lanes = <2>; + }; + + pci@2,0 { + device_type = "pci"; + assigned-addresses = <0x82001000 0 0x00001000 0 0x1000>; + reg = <0x001000 0 0 0 0>; + status = "disabled"; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + nvidia,num-lanes = <2>; + }; + + pci@3,0 { + device_type = "pci"; + assigned-addresses = <0x82001800 0 0x00004000 0 0x1000>; + reg = <0x001800 0 0 0 0>; + status = "disabled"; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + nvidia,num-lanes = <2>; + }; + }; + + host1x@50000000 { + compatible = "nvidia,tegra30-host1x", "simple-bus"; + reg = <0x50000000 0x00024000>; + interrupts = , /* syncpt */ + ; /* general */ + clocks = <&tegra_car TEGRA30_CLK_HOST1X>; + resets = <&tegra_car 28>; + reset-names = "host1x"; + + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0x54000000 0x54000000 0x04000000>; + + mpe@54040000 { + compatible = "nvidia,tegra30-mpe"; + reg = <0x54040000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_MPE>; + resets = <&tegra_car 60>; + reset-names = "mpe"; + }; + + vi@54080000 { + compatible = "nvidia,tegra30-vi"; + reg = <0x54080000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_VI>; + resets = <&tegra_car 20>; + reset-names = "vi"; + }; + + epp@540c0000 { + compatible = "nvidia,tegra30-epp"; + reg = <0x540c0000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_EPP>; + resets = <&tegra_car 19>; + reset-names = "epp"; + }; + + isp@54100000 { + compatible = "nvidia,tegra30-isp"; + reg = <0x54100000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_ISP>; + resets = <&tegra_car 23>; + reset-names = "isp"; + }; + + gr2d@54140000 { + compatible = "nvidia,tegra30-gr2d"; + reg = <0x54140000 0x00040000>; + interrupts = ; + resets = <&tegra_car 21>; + reset-names = "2d"; + clocks = <&tegra_car TEGRA30_CLK_GR2D>; + }; + + gr3d@54180000 { + compatible = "nvidia,tegra30-gr3d"; + reg = <0x54180000 0x00040000>; + clocks = <&tegra_car TEGRA30_CLK_GR3D + &tegra_car TEGRA30_CLK_GR3D2>; + clock-names = "3d", "3d2"; + resets = <&tegra_car 24>, + <&tegra_car 98>; + reset-names = "3d", "3d2"; + }; + + dc@54200000 { + compatible = "nvidia,tegra30-dc", "nvidia,tegra20-dc"; + reg = <0x54200000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_DISP1>, + <&tegra_car TEGRA30_CLK_PLL_P>; + clock-names = "dc", "parent"; + resets = <&tegra_car 27>; + reset-names = "dc"; + + nvidia,head = <0>; + + rgb { + status = "disabled"; + }; + }; + + dc@54240000 { + compatible = "nvidia,tegra30-dc"; + reg = <0x54240000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_DISP2>, + <&tegra_car TEGRA30_CLK_PLL_P>; + clock-names = "dc", "parent"; + resets = <&tegra_car 26>; + reset-names = "dc"; + + nvidia,head = <1>; + + rgb { + status = "disabled"; + }; + }; + + hdmi@54280000 { + compatible = "nvidia,tegra30-hdmi"; + reg = <0x54280000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_HDMI>, + <&tegra_car TEGRA30_CLK_PLL_D2_OUT0>; + clock-names = "hdmi", "parent"; + resets = <&tegra_car 51>; + reset-names = "hdmi"; + status = "disabled"; + }; + + tvo@542c0000 { + compatible = "nvidia,tegra30-tvo"; + reg = <0x542c0000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_TVO>; + status = "disabled"; + }; + + dsi@54300000 { + compatible = "nvidia,tegra30-dsi"; + reg = <0x54300000 0x00040000>; + clocks = <&tegra_car TEGRA30_CLK_DSIA>; + resets = <&tegra_car 48>; + reset-names = "dsi"; + status = "disabled"; + }; + }; + + timer@50004600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x50040600 0x20>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_TWD>; + }; + + intc: interrupt-controller@50041000 { + compatible = "arm,cortex-a9-gic"; + reg = <0x50041000 0x1000 + 0x50040100 0x0100>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + cache-controller@50043000 { + compatible = "arm,pl310-cache"; + reg = <0x50043000 0x1000>; + arm,data-latency = <6 6 2>; + arm,tag-latency = <5 5 2>; + cache-unified; + cache-level = <2>; + }; + + timer@60005000 { + compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer"; + reg = <0x60005000 0x400>; + interrupts = , + , + , + , + , + ; + clocks = <&tegra_car TEGRA30_CLK_TIMER>; + }; + + tegra_car: clock@60006000 { + compatible = "nvidia,tegra30-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + apbdma: dma@6000a000 { + compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1400>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + clocks = <&tegra_car TEGRA30_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; + }; + + ahb: ahb@6000c004 { + compatible = "nvidia,tegra30-ahb"; + reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */ + }; + + gpio: gpio@6000d000 { + compatible = "nvidia,tegra30-gpio"; + reg = <0x6000d000 0x1000>; + interrupts = , + , + , + , + , + , + , + ; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + pinmux: pinmux@70000868 { + compatible = "nvidia,tegra30-pinmux"; + reg = <0x70000868 0xd4 /* Pad control registers */ + 0x70003000 0x3e4>; /* Mux registers */ + }; + + /* + * There are two serial driver i.e. 8250 based simple serial + * driver and APB DMA based serial driver for higher baudrate + * and performace. To enable the 8250 based driver, the compatible + * is "nvidia,tegra30-uart", "nvidia,tegra20-uart" and to enable + * the APB DMA based serial driver, the comptible is + * "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart". + */ + uarta: serial@70006000 { + compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; + reg = <0x70006000 0x40>; + reg-shift = <2>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uartb: serial@70006040 { + compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; + reg = <0x70006040 0x40>; + reg-shift = <2>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uartc: serial@70006200 { + compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; + reg = <0x70006200 0x100>; + reg-shift = <2>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uartd: serial@70006300 { + compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; + reg = <0x70006300 0x100>; + reg-shift = <2>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uarte: serial@70006400 { + compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; + reg = <0x70006400 0x100>; + reg-shift = <2>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_UARTE>; + resets = <&tegra_car 66>; + reset-names = "serial"; + dmas = <&apbdma 20>, <&apbdma 20>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + pwm: pwm@7000a000 { + compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm"; + reg = <0x7000a000 0x100>; + #pwm-cells = <2>; + clocks = <&tegra_car TEGRA30_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; + status = "disabled"; + }; + + rtc@7000e000 { + compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc"; + reg = <0x7000e000 0x100>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_RTC>; + }; + + i2c@7000c000 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c000 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_I2C1>, + <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; + clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000c400 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c400 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_I2C2>, + <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; + clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000c500 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c500 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_I2C3>, + <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; + clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000c700 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c700 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_I2C4>, + <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; + resets = <&tegra_car 103>; + reset-names = "i2c"; + clock-names = "div-clk", "fast-clk"; + dmas = <&apbdma 26>, <&apbdma 26>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000d000 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000d000 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_I2C5>, + <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; + clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000d400 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000d400 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_SBC1>; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000d600 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000d600 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_SBC2>; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000d800 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000d800 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_SBC3>; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000da00 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000da00 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_SBC4>; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000dc00 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000dc00 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_SBC5>; + resets = <&tegra_car 104>; + reset-names = "spi"; + dmas = <&apbdma 27>, <&apbdma 27>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000de00 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000de00 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA30_CLK_SBC6>; + resets = <&tegra_car 106>; + reset-names = "spi"; + dmas = <&apbdma 28>, <&apbdma 28>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + kbc@7000e200 { + compatible = "nvidia,tegra30-kbc", "nvidia,tegra20-kbc"; + reg = <0x7000e200 0x100>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_KBC>; + resets = <&tegra_car 36>; + reset-names = "kbc"; + status = "disabled"; + }; + + pmc@7000e400 { + compatible = "nvidia,tegra30-pmc"; + reg = <0x7000e400 0x400>; + clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>; + clock-names = "pclk", "clk32k_in"; + }; + + memory-controller@7000f000 { + compatible = "nvidia,tegra30-mc"; + reg = <0x7000f000 0x010 + 0x7000f03c 0x1b4 + 0x7000f200 0x028 + 0x7000f284 0x17c>; + interrupts = ; + }; + + iommu@7000f010 { + compatible = "nvidia,tegra30-smmu"; + reg = <0x7000f010 0x02c + 0x7000f1f0 0x010 + 0x7000f228 0x05c>; + nvidia,#asids = <4>; /* # of ASIDs */ + dma-window = <0 0x40000000>; /* IOVA start & length */ + nvidia,ahb = <&ahb>; + }; + + ahub@70080000 { + compatible = "nvidia,tegra30-ahub"; + reg = <0x70080000 0x200 + 0x70080200 0x100>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>, + <&tegra_car TEGRA30_CLK_APBIF>; + clock-names = "d_audio", "apbif"; + resets = <&tegra_car 106>, /* d_audio */ + <&tegra_car 107>, /* apbif */ + <&tegra_car 30>, /* i2s0 */ + <&tegra_car 11>, /* i2s1 */ + <&tegra_car 18>, /* i2s2 */ + <&tegra_car 101>, /* i2s3 */ + <&tegra_car 102>, /* i2s4 */ + <&tegra_car 108>, /* dam0 */ + <&tegra_car 109>, /* dam1 */ + <&tegra_car 110>, /* dam2 */ + <&tegra_car 10>; /* spdif */ + reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + "i2s3", "i2s4", "dam0", "dam1", "dam2", + "spdif"; + dmas = <&apbdma 1>, <&apbdma 1>, + <&apbdma 2>, <&apbdma 2>, + <&apbdma 3>, <&apbdma 3>, + <&apbdma 4>, <&apbdma 4>; + dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", + "rx3", "tx3"; + ranges; + #address-cells = <1>; + #size-cells = <1>; + + tegra_i2s0: i2s@70080300 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080300 0x100>; + nvidia,ahub-cif-ids = <4 4>; + clocks = <&tegra_car TEGRA30_CLK_I2S0>; + resets = <&tegra_car 30>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s1: i2s@70080400 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080400 0x100>; + nvidia,ahub-cif-ids = <5 5>; + clocks = <&tegra_car TEGRA30_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s2: i2s@70080500 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080500 0x100>; + nvidia,ahub-cif-ids = <6 6>; + clocks = <&tegra_car TEGRA30_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s3: i2s@70080600 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080600 0x100>; + nvidia,ahub-cif-ids = <7 7>; + clocks = <&tegra_car TEGRA30_CLK_I2S3>; + resets = <&tegra_car 101>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s4: i2s@70080700 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080700 0x100>; + nvidia,ahub-cif-ids = <8 8>; + clocks = <&tegra_car TEGRA30_CLK_I2S4>; + resets = <&tegra_car 102>; + reset-names = "i2s"; + status = "disabled"; + }; + }; + + sdhci@78000000 { + compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; + reg = <0x78000000 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; + status = "disabled"; + }; + + sdhci@78000200 { + compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; + reg = <0x78000200 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; + status = "disabled"; + }; + + sdhci@78000400 { + compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; + reg = <0x78000400 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; + status = "disabled"; + }; + + sdhci@78000600 { + compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; + reg = <0x78000600 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA30_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; + status = "disabled"; + }; + + usb@7d000000 { + compatible = "nvidia,tegra30-ehci", "usb-ehci"; + reg = <0x7d000000 0x4000>; + interrupts = ; + phy_type = "utmi"; + clocks = <&tegra_car TEGRA30_CLK_USBD>; + resets = <&tegra_car 22>; + reset-names = "usb"; + nvidia,needs-double-reset; + nvidia,phy = <&phy1>; + status = "disabled"; + }; + + phy1: usb-phy@7d000000 { + compatible = "nvidia,tegra30-usb-phy"; + reg = <0x7d000000 0x4000 0x7d000000 0x4000>; + phy_type = "utmi"; + clocks = <&tegra_car TEGRA30_CLK_USBD>, + <&tegra_car TEGRA30_CLK_PLL_U>, + <&tegra_car TEGRA30_CLK_USBD>; + clock-names = "reg", "pll_u", "utmi-pads"; + nvidia,hssync-start-delay = <9>; + nvidia,idle-wait-delay = <17>; + nvidia,elastic-limit = <16>; + nvidia,term-range-adj = <6>; + nvidia,xcvr-setup = <51>; + nvidia.xcvr-setup-use-fuses; + nvidia,xcvr-lsfslew = <1>; + nvidia,xcvr-lsrslew = <1>; + nvidia,xcvr-hsslew = <32>; + nvidia,hssquelch-level = <2>; + nvidia,hsdiscon-level = <5>; + status = "disabled"; + }; + + usb@7d004000 { + compatible = "nvidia,tegra30-ehci", "usb-ehci"; + reg = <0x7d004000 0x4000>; + interrupts = ; + phy_type = "utmi"; + clocks = <&tegra_car TEGRA30_CLK_USB2>; + resets = <&tegra_car 58>; + reset-names = "usb"; + nvidia,phy = <&phy2>; + status = "disabled"; + }; + + phy2: usb-phy@7d004000 { + compatible = "nvidia,tegra30-usb-phy"; + reg = <0x7d004000 0x4000 0x7d000000 0x4000>; + phy_type = "utmi"; + clocks = <&tegra_car TEGRA30_CLK_USB2>, + <&tegra_car TEGRA30_CLK_PLL_U>, + <&tegra_car TEGRA30_CLK_USBD>; + clock-names = "reg", "pll_u", "utmi-pads"; + nvidia,hssync-start-delay = <9>; + nvidia,idle-wait-delay = <17>; + nvidia,elastic-limit = <16>; + nvidia,term-range-adj = <6>; + nvidia,xcvr-setup = <51>; + nvidia.xcvr-setup-use-fuses; + nvidia,xcvr-lsfslew = <2>; + nvidia,xcvr-lsrslew = <2>; + nvidia,xcvr-hsslew = <32>; + nvidia,hssquelch-level = <2>; + nvidia,hsdiscon-level = <5>; + status = "disabled"; + }; + + usb@7d008000 { + compatible = "nvidia,tegra30-ehci", "usb-ehci"; + reg = <0x7d008000 0x4000>; + interrupts = ; + phy_type = "utmi"; + clocks = <&tegra_car TEGRA30_CLK_USB3>; + resets = <&tegra_car 59>; + reset-names = "usb"; + nvidia,phy = <&phy3>; + status = "disabled"; + }; + + phy3: usb-phy@7d008000 { + compatible = "nvidia,tegra30-usb-phy"; + reg = <0x7d008000 0x4000 0x7d000000 0x4000>; + phy_type = "utmi"; + clocks = <&tegra_car TEGRA30_CLK_USB3>, + <&tegra_car TEGRA30_CLK_PLL_U>, + <&tegra_car TEGRA30_CLK_USBD>; + clock-names = "reg", "pll_u", "utmi-pads"; + nvidia,hssync-start-delay = <0>; + nvidia,idle-wait-delay = <17>; + nvidia,elastic-limit = <16>; + nvidia,term-range-adj = <6>; + nvidia,xcvr-setup = <51>; + nvidia.xcvr-setup-use-fuses; + nvidia,xcvr-lsfslew = <2>; + nvidia,xcvr-lsrslew = <2>; + nvidia,xcvr-hsslew = <32>; + nvidia,hssquelch-level = <2>; + nvidia,hsdiscon-level = <5>; + status = "disabled"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <3>; + }; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = , + , + , + ; + }; +}; diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 34e1c37f5..1bbe6ce5e 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -46,6 +46,10 @@ config ARCH_TEGRA_2x_SOC bool select PINCTRL_TEGRA20 +config ARCH_TEGRA_3x_SOC + bool + select PINCTRL_TEGRA30 + menu "select Tegra boards to be built" config MACH_TORADEX_COLIBRI_T20 @@ -56,6 +60,10 @@ config MACH_TOSHIBA_AC100 bool "Toshiba AC100" select ARCH_TEGRA_2x_SOC +config MACH_NVIDIA_BEAVER + bool "NVIDIA Beaver" + select ARCH_TEGRA_3x_SOC + endmenu # --------------------------------------------------------- diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 791d5d45a..e68156a77 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,5 +1,13 @@ -CFLAGS_tegra_avp_init.o := -mcpu=arm7tdmi -march=armv4t -fno-jump-tables -CFLAGS_pbl-tegra_avp_init.o := -mcpu=arm7tdmi -march=armv4t -fno-jump-tables +CFLAGS_tegra_avp_init.o := \ + -mcpu=arm7tdmi -march=armv4t \ + -fno-tree-switch-conversion -fno-jump-tables +CFLAGS_pbl-tegra_avp_init.o := \ + -mcpu=arm7tdmi -march=armv4t \ + -fno-tree-switch-conversion -fno-jump-tables +CFLAGS_tegra_maincomplex_init.o := \ + -fno-tree-switch-conversion -fno-jump-tables +CFLAGS_pbl-tegra_maincomplex_init.o := \ + -fno-tree-switch-conversion -fno-jump-tables lwl-y += tegra_avp_init.o lwl-y += tegra_maincomplex_init.o obj-y += tegra20.o diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h index cc346a023..52b405d5f 100644 --- a/arch/arm/mach-tegra/include/mach/lowlevel.h +++ b/arch/arm/mach-tegra/include/mach/lowlevel.h @@ -39,6 +39,7 @@ #define T20_ODMDATA_RAMSIZE_SHIFT 28 #define T20_ODMDATA_RAMSIZE_MASK (3 << T20_ODMDATA_RAMSIZE_SHIFT) +#define T30_ODMDATA_RAMSIZE_MASK (0xf << T20_ODMDATA_RAMSIZE_SHIFT) #define T20_ODMDATA_UARTTYPE_SHIFT 18 #define T20_ODMDATA_UARTTYPE_MASK (3 << T20_ODMDATA_UARTTYPE_SHIFT) #define T20_ODMDATA_UARTID_SHIFT 15 @@ -124,6 +125,26 @@ uint32_t tegra20_get_ramsize(void) } } +static __always_inline +uint32_t tegra30_get_ramsize(void) +{ + switch ((tegra_get_odmdata() & T30_ODMDATA_RAMSIZE_MASK) >> + T20_ODMDATA_RAMSIZE_SHIFT) { + case 0: + case 1: + default: + return SZ_256M; + case 2: + return SZ_512M; + case 3: + return SZ_512M + SZ_256M; + case 4: + return SZ_1G; + case 8: + return SZ_2G - SZ_1M; + } +} + static long uart_id_to_base[] = { TEGRA_UARTA_BASE, TEGRA_UARTB_BASE, @@ -179,6 +200,19 @@ int tegra_get_osc_clock(void) } } +static __always_inline +int tegra_get_pllp_rate(void) +{ + switch (tegra_get_chiptype()) { + case TEGRA20: + return 216000000; + case TEGRA30: + return 408000000; + default: + return 0; + } +} + #define TIMER_CNTR_1US 0x00 #define TIMER_USEC_CFG 0x04 diff --git a/arch/arm/mach-tegra/tegra20.c b/arch/arm/mach-tegra/tegra20.c index bdd7960f4..0773972ae 100644 --- a/arch/arm/mach-tegra/tegra20.c +++ b/arch/arm/mach-tegra/tegra20.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Lucas Stach + * Copyright (C) 2013-2014 Lucas Stach * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -22,14 +22,17 @@ #include static struct NS16550_plat debug_uart = { - .clock = 216000000, /* pll_p rate */ .shift = 2, }; -static int tegra20_add_debug_console(void) +static int tegra_add_debug_console(void) { unsigned long base = 0; + if (!of_machine_is_compatible("nvidia,tegra20") && + !of_machine_is_compatible("nvidia,tegra30")) + return 0; + /* figure out which UART to use */ if (IS_ENABLED(CONFIG_TEGRA_UART_NONE)) return 0; @@ -49,17 +52,33 @@ static int tegra20_add_debug_console(void) if (!base) return -ENODEV; + debug_uart.clock = tegra_get_pllp_rate(); + add_ns16550_device(DEVICE_ID_DYNAMIC, base, 8 << debug_uart.shift, IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &debug_uart); return 0; } -console_initcall(tegra20_add_debug_console); +console_initcall(tegra_add_debug_console); static int tegra20_mem_init(void) { + if (!of_machine_is_compatible("nvidia,tegra20")) + return 0; + arm_add_mem_device("ram0", 0x0, tegra20_get_ramsize()); return 0; } mem_initcall(tegra20_mem_init); + +static int tegra30_mem_init(void) +{ + if (!of_machine_is_compatible("nvidia,tegra30")) + return 0; + + arm_add_mem_device("ram0", SZ_2G, tegra30_get_ramsize()); + + return 0; +} +mem_initcall(tegra30_mem_init); diff --git a/arch/arm/mach-tegra/tegra_avp_init.c b/arch/arm/mach-tegra/tegra_avp_init.c index 3314db457..1afea445a 100644 --- a/arch/arm/mach-tegra/tegra_avp_init.c +++ b/arch/arm/mach-tegra/tegra_avp_init.c @@ -164,8 +164,8 @@ static void start_cpu0_clocks(void) /* init MSELECT */ writel(CRC_RST_DEV_V_MSELECT, TEGRA_CLK_RESET_BASE + CRC_RST_DEV_V_SET); - writel((CRC_CLK_SOURCE_MSEL_SRC_PLLP << - CRC_CLK_SOURCE_MSEL_SRC_SHIFT) | 2, + writel((CRC_CLK_SOURCE_MSEL_SRC_CLKM << + CRC_CLK_SOURCE_MSEL_SRC_SHIFT), TEGRA_CLK_RESET_BASE + CRC_CLK_SOURCE_MSEL); writel(CRC_CLK_OUT_ENB_V_MSELECT, TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_V); diff --git a/arch/arm/mach-tegra/tegra_maincomplex_init.c b/arch/arm/mach-tegra/tegra_maincomplex_init.c index 5aad1dd65..776af64ae 100644 --- a/arch/arm/mach-tegra/tegra_maincomplex_init.c +++ b/arch/arm/mach-tegra/tegra_maincomplex_init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Lucas Stach + * Copyright (C) 2013-2014 Lucas Stach * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -41,6 +41,10 @@ void tegra_maincomplex_entry(void) rambase = 0x0; ramsize = tegra20_get_ramsize(); break; + case TEGRA30: + rambase = SZ_2G; + ramsize = tegra30_get_ramsize(); + break; default: /* If we don't know the chiptype, better bail out */ unreachable(); diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index e614722c2..7317f2254 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -4,4 +4,5 @@ obj-y += clk-periph.o obj-y += clk-pll.o obj-y += clk-pll-out.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o \ No newline at end of file +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o +obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index b7414dec0..be83955db 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Lucas Stach + * Copyright (C) 2013-2014 Lucas Stach * * Based on the Linux Tegra clock code * @@ -130,7 +130,7 @@ struct clk *_tegra_clk_register_periph(const char *name, bool has_div) { struct tegra_clk_periph *periph; - int ret; + int ret, gate_offs, rst_offs; periph = kzalloc(sizeof(*periph), GFP_KERNEL); if (!periph) { @@ -144,8 +144,13 @@ struct clk *_tegra_clk_register_periph(const char *name, if (!periph->mux) goto out_mux; - periph->gate = clk_gate_alloc(NULL, NULL, clk_base + 0x10 + - ((id >> 3) & 0xc), id & 0x1f, 0, 0); + if (id >= 96) + gate_offs = 0x360 + (((id - 96) >> 3) & 0xc); + else + gate_offs = 0x10 + ((id >> 3) & 0xc); + + periph->gate = clk_gate_alloc(NULL, NULL, clk_base + gate_offs, + id & 0x1f, 0, 0); if (!periph->gate) goto out_gate; @@ -162,7 +167,12 @@ struct clk *_tegra_clk_register_periph(const char *name, periph->hw.parent_names = parent_names; periph->hw.num_parents = num_parents; periph->flags = flags; - periph->rst_reg = clk_base + 0x4 + ((id >> 3) & 0xc); + + if (id >= 96) + rst_offs = 0x358 + (((id - 96) >> 3) & 0xc); + else + rst_offs = 0x4 + ((id >> 3) & 0xc); + periph->rst_reg = clk_base + rst_offs; periph->rst_shift = id & 0x1f; ret = clk_register(&periph->hw); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index cfb719f43..ea39f46b1 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -29,23 +30,7 @@ static void __iomem *car_base; -enum tegra20_clks { - cpu, ac97 = 3, rtc, timer, uarta, uartb, gpio, 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, - vfir = 96, 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_u, - pll_x, audio, pll_ref, twd, clk_max, -}; - -static struct clk *clks[clk_max]; +static struct clk *clks[TEGRA20_CLK_CLK_MAX]; static struct clk_onecell_data clk_data; static unsigned int get_pll_ref_div(void) @@ -58,11 +43,11 @@ static unsigned int get_pll_ref_div(void) static void tegra20_osc_clk_init(void) { - clks[clk_m] = clk_fixed("clk_m", tegra_get_osc_clock()); - clks[clk_32k] = clk_fixed("clk_32k", 32768); + clks[TEGRA20_CLK_CLK_M] = clk_fixed("clk_m", tegra_get_osc_clock()); + clks[TEGRA20_CLK_CLK_32K] = clk_fixed("clk_32k", 32768); - clks[pll_ref] = clk_fixed_factor("pll_ref", "clk_m", 1, - get_pll_ref_div(), 0); + clks[TEGRA20_CLK_PLL_REF] = clk_fixed_factor("pll_ref", "clk_m", 1, + get_pll_ref_div(), 0); } /* PLL frequency tables */ @@ -228,50 +213,52 @@ static struct tegra_clk_pll_params pll_u_params = { static void tegra20_pll_init(void) { /* PLLC */ - clks[pll_c] = tegra_clk_register_pll("pll_c", "pll_ref", car_base, - 0, 0, &pll_c_params, TEGRA_PLL_HAS_CPCON, + clks[TEGRA20_CLK_PLL_C] = tegra_clk_register_pll("pll_c", "pll_ref", + car_base, 0, 0, &pll_c_params, TEGRA_PLL_HAS_CPCON, pll_c_freq_table); - clks[pll_c_out1] = tegra_clk_register_pll_out("pll_c_out1", "pll_c", - car_base + CRC_PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP); + clks[TEGRA20_CLK_PLL_C_OUT1] = tegra_clk_register_pll_out("pll_c_out1", + "pll_c", car_base + CRC_PLLC_OUT, 0, + TEGRA_DIVIDER_ROUND_UP); /* PLLP */ - clks[pll_p] = tegra_clk_register_pll("pll_p", "pll_ref", car_base, - 0, 216000000, &pll_p_params, TEGRA_PLL_FIXED | + clks[TEGRA20_CLK_PLL_P] = tegra_clk_register_pll("pll_p", "pll_ref", + car_base, 0, 216000000, &pll_p_params, TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON, pll_p_freq_table); - clks[pll_p_out1] = tegra_clk_register_pll_out("pll_p_out1", "pll_p", - car_base + CRC_PLLP_OUTA, 0, + clks[TEGRA20_CLK_PLL_P_OUT1] = tegra_clk_register_pll_out("pll_p_out1", + "pll_p", car_base + CRC_PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); - clks[pll_p_out2] = tegra_clk_register_pll_out("pll_p_out2", "pll_p", - car_base + CRC_PLLP_OUTA, 16, + clks[TEGRA20_CLK_PLL_P_OUT2] = tegra_clk_register_pll_out("pll_p_out2", + "pll_p", car_base + CRC_PLLP_OUTA, 16, TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); - clks[pll_p_out3] = tegra_clk_register_pll_out("pll_p_out3", "pll_p", - car_base + CRC_PLLP_OUTB, 0, + clks[TEGRA20_CLK_PLL_P_OUT3] = tegra_clk_register_pll_out("pll_p_out3", + "pll_p", car_base + CRC_PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); - clks[pll_p_out4] = tegra_clk_register_pll_out("pll_p_out4", "pll_p", - car_base + CRC_PLLP_OUTB, 16, + clks[TEGRA20_CLK_PLL_P_OUT4] = tegra_clk_register_pll_out("pll_p_out4", + "pll_p", car_base + CRC_PLLP_OUTB, 16, TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); /* PLLM */ - clks[pll_m] = tegra_clk_register_pll("pll_m", "pll_ref", car_base, - 0, 0, &pll_m_params, TEGRA_PLL_HAS_CPCON, + clks[TEGRA20_CLK_PLL_M] = tegra_clk_register_pll("pll_m", "pll_ref", + car_base, 0, 0, &pll_m_params, TEGRA_PLL_HAS_CPCON, pll_m_freq_table); - clks[pll_m_out1] = tegra_clk_register_pll_out("pll_m_out1", "pll_m", - car_base + CRC_PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP); + clks[TEGRA20_CLK_PLL_M_OUT1] = tegra_clk_register_pll_out("pll_m_out1", + "pll_m", car_base + CRC_PLLM_OUT, 0, + TEGRA_DIVIDER_ROUND_UP); /* PLLX */ - clks[pll_x] = tegra_clk_register_pll("pll_x", "pll_ref", car_base, - 0, 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, + clks[TEGRA20_CLK_PLL_X] = tegra_clk_register_pll("pll_x", "pll_ref", + car_base, 0, 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, pll_x_freq_table); /* PLLU */ - clks[pll_u] = tegra_clk_register_pll("pll_u", "pll_ref", car_base, - 0, 0, &pll_u_params, TEGRA_PLLU | + clks[TEGRA20_CLK_PLL_U] = tegra_clk_register_pll("pll_u", "pll_ref", + car_base, 0, 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, pll_u_freq_table); } @@ -280,55 +267,60 @@ static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; static void tegra20_periph_init(void) { /* peripheral clocks without a divider */ - clks[uarta] = tegra_clk_register_periph_nodiv("uarta", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_UARTA, uarta, TEGRA_PERIPH_ON_APB); - clks[uartb] = tegra_clk_register_periph_nodiv("uartb", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_UARTB, uartb, TEGRA_PERIPH_ON_APB); - clks[uartc] = tegra_clk_register_periph_nodiv("uartc", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_UARTC, uartc, TEGRA_PERIPH_ON_APB); - clks[uartd] = tegra_clk_register_periph_nodiv("uartd", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_UARTD, uartd, TEGRA_PERIPH_ON_APB); - clks[uarte] = tegra_clk_register_periph_nodiv("uarte", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_UARTE, uarte, TEGRA_PERIPH_ON_APB); + clks[TEGRA20_CLK_UARTA] = tegra_clk_register_periph_nodiv("uarta", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTA, TEGRA20_CLK_UARTA, + TEGRA_PERIPH_ON_APB); + clks[TEGRA20_CLK_UARTB] = tegra_clk_register_periph_nodiv("uartb", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTB, 7, + TEGRA_PERIPH_ON_APB); + clks[TEGRA20_CLK_UARTC] = tegra_clk_register_periph_nodiv("uartc", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTC, TEGRA20_CLK_UARTC, + TEGRA_PERIPH_ON_APB); + clks[TEGRA20_CLK_UARTD] = tegra_clk_register_periph_nodiv("uartd", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTD, TEGRA20_CLK_UARTD, + TEGRA_PERIPH_ON_APB); + clks[TEGRA20_CLK_UARTE] = tegra_clk_register_periph_nodiv("uarte", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTE, TEGRA20_CLK_UARTE, + TEGRA_PERIPH_ON_APB); /* peripheral clocks with a divider */ - clks[sdmmc1] = tegra_clk_register_periph("sdmmc1", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_SDMMC1, sdmmc1, 1); - clks[sdmmc2] = tegra_clk_register_periph("sdmmc2", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_SDMMC2, sdmmc2, 1); - clks[sdmmc3] = tegra_clk_register_periph("sdmmc3", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_SDMMC3, sdmmc3, 1); - clks[sdmmc4] = tegra_clk_register_periph("sdmmc4", mux_pllpcm_clkm, - ARRAY_SIZE(mux_pllpcm_clkm), car_base, - CRC_CLK_SOURCE_SDMMC4, sdmmc4, 1); + clks[TEGRA20_CLK_SDMMC1] = tegra_clk_register_periph("sdmmc1", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC1, TEGRA20_CLK_SDMMC1, 1); + clks[TEGRA20_CLK_SDMMC2] = tegra_clk_register_periph("sdmmc2", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC2, TEGRA20_CLK_SDMMC2, 1); + clks[TEGRA20_CLK_SDMMC3] = tegra_clk_register_periph("sdmmc3", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC3, TEGRA20_CLK_SDMMC3, 1); + clks[TEGRA20_CLK_SDMMC4] = tegra_clk_register_periph("sdmmc4", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC4, TEGRA20_CLK_SDMMC4, 1); } static struct tegra_clk_init_table init_table[] = { - {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}, - {uarta, pll_p, 0, 1}, - {uartb, pll_p, 0, 1}, - {uartc, pll_p, 0, 1}, - {uartd, pll_p, 0, 1}, - {uarte, pll_p, 0, 1}, - {sdmmc1, pll_p, 48000000, 0}, - {sdmmc2, pll_p, 48000000, 0}, - {sdmmc3, pll_p, 48000000, 0}, - {sdmmc4, pll_p, 48000000, 0}, - {clk_max, clk_max, 0, 0}, /* sentinel */ + {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_UARTA, TEGRA20_CLK_PLL_P, 0, 1}, + {TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 1}, + {TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 1}, + {TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 1}, + {TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 1}, + {TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0}, + {TEGRA20_CLK_SDMMC2, 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_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0}, /* sentinel */ }; static int tegra20_car_probe(struct device_d *dev) @@ -341,7 +333,7 @@ static int tegra20_car_probe(struct device_d *dev) tegra20_pll_init(); tegra20_periph_init(); - tegra_init_from_table(init_table, clks, clk_max); + tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX); /* speed up system bus */ writel(CRC_SCLK_BURST_POLICY_SYS_STATE_RUN << diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c new file mode 100644 index 000000000..94bbeace4 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra30.c @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2014 Lucas Stach + * + * Based on the Linux Tegra clock code + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +static void __iomem *car_base; + +static struct clk *clks[TEGRA30_CLK_CLK_MAX]; +static struct clk_onecell_data clk_data; + +static unsigned int get_pll_ref_div(void) +{ + u32 osc_ctrl = readl(car_base + CRC_OSC_CTRL); + + return 1U << ((osc_ctrl & CRC_OSC_CTRL_PLL_REF_DIV_MASK) >> + CRC_OSC_CTRL_PLL_REF_DIV_SHIFT); +} + +static void tegra30_osc_clk_init(void) +{ + clks[TEGRA30_CLK_CLK_M] = clk_fixed("clk_m", tegra_get_osc_clock()); + clks[TEGRA30_CLK_CLK_32K] = clk_fixed("clk_32k", 32768); + + clks[TEGRA30_CLK_PLL_REF] = clk_fixed_factor("pll_ref", "clk_m", 1, + get_pll_ref_div(), 0); +} + +/* PLL frequency tables */ +static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { + { 12000000, 1040000000, 520, 6, 0, 8}, + { 26000000, 1040000000, 520, 13, 0, 8}, + + { 12000000, 832000000, 416, 6, 0, 8}, + { 26000000, 832000000, 416, 13, 0, 8}, + + { 12000000, 624000000, 624, 12, 0, 8}, + { 26000000, 624000000, 624, 26, 0, 8}, + + { 12000000, 600000000, 600, 12, 0, 8}, + { 26000000, 600000000, 600, 26, 0, 8}, + + { 12000000, 520000000, 520, 12, 0, 8}, + { 26000000, 520000000, 520, 26, 0, 8}, + + { 12000000, 416000000, 416, 12, 0, 8}, + { 26000000, 416000000, 416, 26, 0, 8}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { + { 12000000, 408000000, 408, 12, 1, 8}, + { 26000000, 408000000, 408, 26, 1, 8}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { + { 12000000, 666000000, 666, 12, 0, 8}, + { 26000000, 666000000, 666, 26, 0, 8}, + + { 12000000, 600000000, 600, 12, 0, 8}, + { 26000000, 600000000, 600, 26, 0, 8}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { + /* 1.7 GHz */ + { 12000000, 1700000000, 850, 6, 0, 8}, + { 26000000, 1700000000, 850, 13, 0, 8}, + + /* 1.6 GHz */ + { 12000000, 1600000000, 800, 6, 0, 8}, + { 26000000, 1600000000, 800, 13, 0, 8}, + + /* 1.5 GHz */ + { 12000000, 1500000000, 750, 6, 0, 8}, + { 26000000, 1500000000, 750, 13, 0, 8}, + + /* 1.4 GHz */ + { 12000000, 1400000000, 700, 6, 0, 8}, + { 26000000, 1400000000, 700, 13, 0, 8}, + + /* 1.3 GHz */ + { 12000000, 1300000000, 975, 9, 0, 8}, + { 26000000, 1300000000, 650, 13, 0, 8}, + + /* 1.2 GHz */ + { 12000000, 1200000000, 1000, 10, 0, 8}, + { 26000000, 1200000000, 600, 13, 0, 8}, + + /* 1.1 GHz */ + { 12000000, 1100000000, 825, 9, 0, 8}, + { 26000000, 1100000000, 550, 13, 0, 8}, + + /* 1 GHz */ + { 12000000, 1000000000, 1000, 12, 0, 8}, + { 26000000, 1000000000, 1000, 26, 0, 8}, + + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { + { 12000000, 480000000, 960, 12, 0, 12}, + { 26000000, 480000000, 960, 26, 0, 12}, + { 0, 0, 0, 0, 0, 0 }, +}; + +/* PLL parameters */ +static struct tegra_clk_pll_params pll_c_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .base_reg = CRC_PLLC_BASE, + .misc_reg = CRC_PLLC_MISC, + .lock_bit_idx = CRC_PLL_BASE_LOCK, + .lock_enable_bit_idx = CRC_PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, +}; + +static struct tegra_clk_pll_params pll_p_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .base_reg = CRC_PLLP_BASE, + .misc_reg = CRC_PLLP_MISC, + .lock_bit_idx = CRC_PLL_BASE_LOCK, + .lock_enable_bit_idx = CRC_PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, +}; + +static struct tegra_clk_pll_params pll_m_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1200000000, + .base_reg = CRC_PLLM_BASE, + .misc_reg = CRC_PLLM_MISC, + .lock_bit_idx = CRC_PLL_BASE_LOCK, + .lock_enable_bit_idx = CRC_PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, +}; + +static struct tegra_clk_pll_params pll_x_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1200000000, + .base_reg = CRC_PLLX_BASE, + .misc_reg = CRC_PLLX_MISC, + .lock_bit_idx = CRC_PLL_BASE_LOCK, + .lock_enable_bit_idx = CRC_PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, +}; + +static struct tegra_clk_pll_params pll_u_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 48000000, + .vco_max = 960000000, + .base_reg = CRC_PLLU_BASE, + .misc_reg = CRC_PLLU_MISC, + .lock_bit_idx = CRC_PLL_BASE_LOCK, + .lock_enable_bit_idx = CRC_PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, +}; + +static void tegra30_pll_init(void) +{ + /* PLLC */ + clks[TEGRA30_CLK_PLL_C] = tegra_clk_register_pll("pll_c", "pll_ref", + car_base, 0, 0, &pll_c_params, TEGRA_PLL_HAS_CPCON, + pll_c_freq_table); + + clks[TEGRA30_CLK_PLL_C_OUT1] = tegra_clk_register_pll_out("pll_c_out1", + "pll_c", car_base + CRC_PLLC_OUT, 0, + TEGRA_DIVIDER_ROUND_UP); + + /* PLLP */ + clks[TEGRA30_CLK_PLL_P] = tegra_clk_register_pll("pll_p", "pll_ref", + car_base, 0, 408000000, &pll_p_params, TEGRA_PLL_FIXED | + TEGRA_PLL_HAS_CPCON, pll_p_freq_table); + + clks[TEGRA30_CLK_PLL_P_OUT1] = tegra_clk_register_pll_out("pll_p_out1", + "pll_p", car_base + CRC_PLLP_OUTA, 0, + TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); + + clks[TEGRA30_CLK_PLL_P_OUT2] = tegra_clk_register_pll_out("pll_p_out2", + "pll_p", car_base + CRC_PLLP_OUTA, 16, + TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); + + clks[TEGRA30_CLK_PLL_P_OUT3] = tegra_clk_register_pll_out("pll_p_out3", + "pll_p", car_base + CRC_PLLP_OUTB, 0, + TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); + + clks[TEGRA30_CLK_PLL_P_OUT4] = tegra_clk_register_pll_out("pll_p_out4", + "pll_p", car_base + CRC_PLLP_OUTB, 16, + TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP); + + /* PLLM */ + clks[TEGRA30_CLK_PLL_M] = tegra_clk_register_pll("pll_m", "pll_ref", + car_base, 0, 0, &pll_m_params, TEGRA_PLL_HAS_CPCON, + pll_m_freq_table); + + clks[TEGRA30_CLK_PLL_M_OUT1] = tegra_clk_register_pll_out("pll_m_out1", + "pll_m", car_base + CRC_PLLM_OUT, 0, + TEGRA_DIVIDER_ROUND_UP); + + /* PLLX */ + clks[TEGRA30_CLK_PLL_X] = tegra_clk_register_pll("pll_x", "pll_ref", + car_base, 0, 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, + pll_x_freq_table); + + /* PLLU */ + clks[TEGRA30_CLK_PLL_U] = tegra_clk_register_pll("pll_u", "pll_ref", + car_base, 0, 0, &pll_u_params, TEGRA_PLLU | + TEGRA_PLL_HAS_CPCON, pll_u_freq_table); +} + +static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; + +static void tegra30_periph_init(void) +{ + /* peripheral clocks without a divider */ + clks[TEGRA30_CLK_UARTA] = tegra_clk_register_periph_nodiv("uarta", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTA, TEGRA30_CLK_UARTA, + TEGRA_PERIPH_ON_APB); + clks[TEGRA30_CLK_UARTB] = tegra_clk_register_periph_nodiv("uartb", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTB, 7, + TEGRA_PERIPH_ON_APB); + clks[TEGRA30_CLK_UARTC] = tegra_clk_register_periph_nodiv("uartc", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTC, TEGRA30_CLK_UARTC, + TEGRA_PERIPH_ON_APB); + clks[TEGRA30_CLK_UARTD] = tegra_clk_register_periph_nodiv("uartd", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTD, TEGRA30_CLK_UARTD, + TEGRA_PERIPH_ON_APB); + clks[TEGRA30_CLK_UARTE] = tegra_clk_register_periph_nodiv("uarte", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_UARTE, TEGRA30_CLK_UARTE, + TEGRA_PERIPH_ON_APB); + + /* peripheral clocks with a divider */ + clks[TEGRA30_CLK_MSELECT] = tegra_clk_register_periph("mselect", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_MSEL, TEGRA30_CLK_MSELECT, 1); + + clks[TEGRA30_CLK_SDMMC1] = tegra_clk_register_periph("sdmmc1", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC1, TEGRA30_CLK_SDMMC1, 1); + clks[TEGRA30_CLK_SDMMC2] = tegra_clk_register_periph("sdmmc2", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC2, TEGRA30_CLK_SDMMC2, 1); + clks[TEGRA30_CLK_SDMMC3] = tegra_clk_register_periph("sdmmc3", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC3, TEGRA30_CLK_SDMMC3, 1); + clks[TEGRA30_CLK_SDMMC4] = tegra_clk_register_periph("sdmmc4", + mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base, + CRC_CLK_SOURCE_SDMMC4, TEGRA30_CLK_SDMMC4, 1); +} + +static struct tegra_clk_init_table init_table[] = { + {TEGRA30_CLK_PLL_P, TEGRA30_CLK_CLK_MAX, 408000000, 1}, + {TEGRA30_CLK_PLL_P_OUT1, TEGRA30_CLK_CLK_MAX, 9600000, 1}, + {TEGRA30_CLK_PLL_P_OUT2, TEGRA30_CLK_CLK_MAX, 48000000, 1}, + {TEGRA30_CLK_PLL_P_OUT3, TEGRA30_CLK_CLK_MAX, 102000000, 1}, + {TEGRA30_CLK_PLL_P_OUT4, TEGRA30_CLK_CLK_MAX, 204000000, 1}, + {TEGRA30_CLK_MSELECT, TEGRA30_CLK_PLL_P, 204000000, 1}, + {TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 0, 1}, + {TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 0, 1}, + {TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 0, 1}, + {TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 0, 1}, + {TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 0, 1}, + {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_SDMMC4, TEGRA30_CLK_PLL_P, 48000000, 0}, + {TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* sentinel */ +}; + +static int tegra30_car_probe(struct device_d *dev) +{ + car_base = dev_request_mem_region(dev, 0); + if (!car_base) + return -EBUSY; + + tegra30_osc_clk_init(); + tegra30_pll_init(); + tegra30_periph_init(); + + tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX); + + /* speed up system bus */ + writel(CRC_SCLK_BURST_POLICY_SYS_STATE_RUN << + CRC_SCLK_BURST_POLICY_SYS_STATE_SHIFT | + CRC_SCLK_BURST_POLICY_SRC_PLLP_OUT4 << + CRC_SCLK_BURST_POLICY_RUN_SRC_SHIFT, + car_base + CRC_SCLK_BURST_POLICY); + + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, + &clk_data); + + return 0; +} + +static __maybe_unused struct of_device_id tegra30_car_dt_ids[] = { + { + .compatible = "nvidia,tegra30-car", + }, { + /* sentinel */ + } +}; + +static struct driver_d tegra30_car_driver = { + .probe = tegra30_car_probe, + .name = "tegra30-car", + .of_compatible = DRV_OF_COMPAT(tegra30_car_dt_ids), +}; + +static int tegra30_car_init(void) +{ + return platform_driver_register(&tegra30_car_driver); +} +postcore_initcall(tegra30_car_init); diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index e84c71a23..bab32ee32 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -38,11 +38,6 @@ #define GPIO_MSK_OE(x) (GPIO_REG(x) + config->upper_offset + 0x10) #define GPIO_MSK_OUT(x) (GPIO_REG(x) + config->upper_offset + 0X20) -struct tegra_gpio_bank { - int bank; - int irq; -}; - struct tegra_gpio_soc_config { u32 bank_stride; u32 upper_offset; @@ -180,19 +175,19 @@ static struct tegra_gpio_soc_config tegra20_gpio_config = { .bank_count = 7, }; -static struct platform_device_id tegra_gpio_ids[] = { - { - .name = "tegra20-gpio", - .driver_data = (unsigned long)&tegra20_gpio_config, - }, { - /* sentinel */ - }, +static struct tegra_gpio_soc_config tegra30_gpio_config = { + .bank_stride = 0x100, + .upper_offset = 0x80, + .bank_count = 8, }; static __maybe_unused struct of_device_id tegra_gpio_dt_ids[] = { { .compatible = "nvidia,tegra20-gpio", .data = (unsigned long)&tegra20_gpio_config + }, { + .compatible = "nvidia,tegra30-gpio", + .data = (unsigned long)&tegra30_gpio_config }, { /* sentinel */ }, @@ -200,7 +195,6 @@ static __maybe_unused struct of_device_id tegra_gpio_dt_ids[] = { static struct driver_d tegra_gpio_driver = { .name = "tegra-gpio", - .id_table = tegra_gpio_ids, .of_compatible = DRV_OF_COMPAT(tegra_gpio_dt_ids), .probe = tegra_gpio_probe, }; diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c index 64c455075..e4d82197b 100644 --- a/drivers/mci/tegra-sdmmc.c +++ b/drivers/mci/tegra-sdmmc.c @@ -339,7 +339,7 @@ static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev) val = readl(regs + TEGRA_SDMMC_INT_STAT_EN); val &= ~(0xffff); - val = (TEGRA_SDMMC_INT_STAT_EN_CMD_COMPLETE | + val |= (TEGRA_SDMMC_INT_STAT_EN_CMD_COMPLETE | TEGRA_SDMMC_INT_STAT_EN_XFER_COMPLETE | TEGRA_SDMMC_INT_STAT_EN_DMA_INTERRUPT | TEGRA_SDMMC_INT_STAT_EN_BUFFER_WRITE_READY | @@ -348,7 +348,7 @@ static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev) val = readl(regs + TEGRA_SDMMC_INT_SIG_EN); val &= ~(0xffff); - val = TEGRA_SDMMC_INT_SIG_EN_XFER_COMPLETE; + val |= TEGRA_SDMMC_INT_SIG_EN_XFER_COMPLETE; writel(val, regs + TEGRA_SDMMC_INT_SIG_EN); tegra_sdmmc_set_clock(host, 400000); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 906e33af8..b9b66f9c8 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -40,3 +40,9 @@ config PINCTRL_TEGRA20 bool help The pinmux controller found on the Tegra 20 line of SoCs. + +config PINCTRL_TEGRA30 + select PINCTRL + bool + help + The pinmux controller found on the Tegra 30 line of SoCs. diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 9a5d0ba97..3978c5692 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o +obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c new file mode 100644 index 000000000..032377fe8 --- /dev/null +++ b/drivers/pinctrl/pinctrl-tegra30.c @@ -0,0 +1,503 @@ +/* + * Copyright (C) 2014 Lucas Stach + * + * Partly based on code + * Copyright (C) 2011-2012, NVIDIA CORPORATION. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +struct pinctrl_tegra30 { + struct { + u32 __iomem *ctrl; + u32 __iomem *mux; + } regs; + struct pinctrl_device pinctrl; +}; + +struct tegra30_pingroup { + const char *name; + const char *funcs[4]; + u16 reg; +}; + +#define PG(pg_name, f0, f1, f2, f3, offset) \ + { \ + .name = #pg_name, \ + .funcs = { #f0, #f1, #f2, #f3, }, \ + .reg = offset \ + } + +static const struct tegra30_pingroup tegra30_groups[] = { + /* name, f0, f1, f2, f3, reg */ + PG(clk_32k_out_pa0, blink, rsvd2, rsvd3, rsvd4, 0x31c), + PG(uart3_cts_n_pa1, uartc, rsvd2, gmi, rsvd4, 0x17c), + PG(dap2_fs_pa2, i2s1, hda, rsvd3, gmi, 0x358), + PG(dap2_sclk_pa3, i2s1, hda, rsvd3, gmi, 0x364), + PG(dap2_din_pa4, i2s1, hda, rsvd3, gmi, 0x35c), + PG(dap2_dout_pa5, i2s1, hda, rsvd3, gmi, 0x360), + PG(sdmmc3_clk_pa6, uarta, pwm2, sdmmc3, spi3, 0x390), + PG(sdmmc3_cmd_pa7, uarta, pwm3, sdmmc3, spi2, 0x394), + PG(gmi_a17_pb0, uartd, spi4, gmi, dtv, 0x234), + PG(gmi_a18_pb1, uartd, spi4, gmi, dtv, 0x238), + PG(lcd_pwr0_pb2, displaya, displayb, spi5, hdcp, 0x090), + PG(lcd_pclk_pb3, displaya, displayb, rsvd3, rsvd4, 0x094), + PG(sdmmc3_dat3_pb4, rsvd1, pwm0, sdmmc3, spi3, 0x3a4), + PG(sdmmc3_dat2_pb5, rsvd1, pwm1, sdmmc3, spi3, 0x3a0), + PG(sdmmc3_dat1_pb6, rsvd1, rsvd2, sdmmc3, spi3, 0x39c), + PG(sdmmc3_dat0_pb7, rsvd1, rsvd2, sdmmc3, spi3, 0x398), + PG(uart3_rts_n_pc0, uartc, pwm0, gmi, rsvd4, 0x180), + PG(lcd_pwr1_pc1, displaya, displayb, rsvd3, rsvd4, 0x070), + PG(uart2_txd_pc2, uartb, spdif, uarta, spi4, 0x168), + PG(uart2_rxd_pc3, uartb, spdif, uarta, spi4, 0x164), + PG(gen1_i2c_scl_pc4, i2c1, rsvd2, rsvd3, rsvd4, 0x1a4), + PG(gen1_i2c_sda_pc5, i2c1, rsvd2, rsvd3, rsvd4, 0x1a0), + PG(lcd_pwr2_pc6, displaya, displayb, spi5, hdcp, 0x074), + PG(gmi_wp_n_pc7, rsvd1, nand, gmi, gmi_alt, 0x1c0), + PG(sdmmc3_dat5_pd0, pwm0, spi4, sdmmc3, spi2, 0x3ac), + PG(sdmmc3_dat4_pd1, pwm1, spi4, sdmmc3, spi2, 0x3a8), + PG(lcd_dc1_pd2, displaya, displayb, rsvd3, rsvd4, 0x10c), + PG(sdmmc3_dat6_pd3, spdif, spi4, sdmmc3, spi2, 0x3b0), + PG(sdmmc3_dat7_pd4, spdif, spi4, sdmmc3, spi2, 0x3b4), + PG(vi_d1_pd5, ddr, sdmmc2, vi, rsvd4, 0x128), + PG(vi_vsync_pd6, ddr, rsvd2, vi, rsvd4, 0x15c), + PG(vi_hsync_pd7, ddr, rsvd2, vi, rsvd4, 0x160), + PG(lcd_d0_pe0, displaya, displayb, rsvd3, rsvd4, 0x0a4), + PG(lcd_d1_pe1, displaya, displayb, rsvd3, rsvd4, 0x0a8), + PG(lcd_d2_pe2, displaya, displayb, rsvd3, rsvd4, 0x0ac), + PG(lcd_d3_pe3, displaya, displayb, rsvd3, rsvd4, 0x0b0), + PG(lcd_d4_pe4, displaya, displayb, rsvd3, rsvd4, 0x0b4), + PG(lcd_d5_pe5, displaya, displayb, rsvd3, rsvd4, 0x0b8), + PG(lcd_d6_pe6, displaya, displayb, rsvd3, rsvd4, 0x0bc), + PG(lcd_d7_pe7, displaya, displayb, rsvd3, rsvd4, 0x0c0), + PG(lcd_d8_pf0, displaya, displayb, rsvd3, rsvd4, 0x0c4), + PG(lcd_d9_pf1, displaya, displayb, rsvd3, rsvd4, 0x0c8), + PG(lcd_d10_pf2, displaya, displayb, rsvd3, rsvd4, 0x0cc), + PG(lcd_d11_pf3, displaya, displayb, rsvd3, rsvd4, 0x0d0), + PG(lcd_d12_pf4, displaya, displayb, rsvd3, rsvd4, 0x0d4), + PG(lcd_d13_pf5, displaya, displayb, rsvd3, rsvd4, 0x0d8), + PG(lcd_d14_pf6, displaya, displayb, rsvd3, rsvd4, 0x0dc), + PG(lcd_d15_pf7, displaya, displayb, rsvd3, rsvd4, 0x0e0), + PG(gmi_ad0_pg0, rsvd1, nand, gmi, rsvd4, 0x1f0), + PG(gmi_ad1_pg1, rsvd1, nand, gmi, rsvd4, 0x1f4), + PG(gmi_ad2_pg2, rsvd1, nand, gmi, rsvd4, 0x1f8), + PG(gmi_ad3_pg3, rsvd1, nand, gmi, rsvd4, 0x1fc), + PG(gmi_ad4_pg4, rsvd1, nand, gmi, rsvd4, 0x200), + PG(gmi_ad5_pg5, rsvd1, nand, gmi, rsvd4, 0x204), + PG(gmi_ad6_pg6, rsvd1, nand, gmi, rsvd4, 0x208), + PG(gmi_ad7_pg7, rsvd1, nand, gmi, rsvd4, 0x20c), + PG(gmi_ad8_ph0, pwm0, nand, gmi, rsvd4, 0x210), + PG(gmi_ad9_ph1, pwm1, nand, gmi, rsvd4, 0x214), + PG(gmi_ad10_ph2, pwm2, nand, gmi, rsvd4, 0x218), + PG(gmi_ad11_ph3, pwm3, nand, gmi, rsvd4, 0x21c), + PG(gmi_ad12_ph4, rsvd1, nand, gmi, rsvd4, 0x220), + PG(gmi_ad13_ph5, rsvd1, nand, gmi, rsvd4, 0x224), + PG(gmi_ad14_ph6, rsvd1, nand, gmi, rsvd4, 0x228), + PG(gmi_ad15_ph7, rsvd1, nand, gmi, rsvd4, 0x22c), + PG(gmi_wr_n_pi0, rsvd1, nand, gmi, rsvd4, 0x240), + PG(gmi_oe_n_pi1, rsvd1, nand, gmi, rsvd4, 0x244), + PG(gmi_dqs_pi2, rsvd1, nand, gmi, rsvd4, 0x248), + PG(gmi_cs6_n_pi3, nand, nand_alt, gmi, sata, 0x1e8), + PG(gmi_rst_n_pi4, nand, nand_alt, gmi, rsvd4, 0x24c), + PG(gmi_iordy_pi5, rsvd1, nand, gmi, rsvd4, 0x1c4), + PG(gmi_cs7_n_pi6, nand, nand_alt, gmi, gmi_alt, 0x1ec), + PG(gmi_wait_pi7, rsvd1, nand, gmi, rsvd4, 0x1c8), + PG(gmi_cs0_n_pj0, rsvd1, nand, gmi, dtv, 0x1d4), + PG(lcd_de_pj1, displaya, displayb, rsvd3, rsvd4, 0x098), + PG(gmi_cs1_n_pj2, rsvd1, nand, gmi, dtv, 0x1d8), + PG(lcd_hsync_pj3, displaya, displayb, rsvd3, rsvd4, 0x09c), + PG(lcd_vsync_pj4, displaya, displayb, rsvd3, rsvd4, 0x0a0), + PG(uart2_cts_n_pj5, uarta, uartb, gmi, spi4, 0x170), + PG(uart2_rts_n_pj6, uarta, uartb, gmi, spi4, 0x16c), + PG(gmi_a16_pj7, uartd, spi4, gmi, gmi_alt, 0x230), + PG(gmi_adv_n_pk0, rsvd1, nand, gmi, rsvd4, 0x1cc), + PG(gmi_clk_pk1, rsvd1, nand, gmi, rsvd4, 0x1d0), + PG(gmi_cs4_n_pk2, rsvd1, nand, gmi, rsvd4, 0x1e4), + PG(gmi_cs2_n_pk3, rsvd1, nand, gmi, rsvd4, 0x1dc), + PG(gmi_cs3_n_pk4, rsvd1, nand, gmi, gmi_alt, 0x1e0), + PG(spdif_out_pk5, spdif, rsvd2, i2c1, sdmmc2, 0x354), + PG(spdif_in_pk6, spdif, hda, i2c1, sdmmc2, 0x350), + PG(gmi_a19_pk7, uartd, spi4, gmi, rsvd4, 0x23c), + PG(vi_d2_pl0, ddr, sdmmc2, vi, rsvd4, 0x12c), + PG(vi_d3_pl1, ddr, sdmmc2, vi, rsvd4, 0x130), + PG(vi_d4_pl2, ddr, sdmmc2, vi, rsvd4, 0x134), + PG(vi_d5_pl3, ddr, sdmmc2, vi, rsvd4, 0x138), + PG(vi_d6_pl4, ddr, sdmmc2, vi, rsvd4, 0x13c), + PG(vi_d7_pl5, ddr, sdmmc2, vi, rsvd4, 0x140), + PG(vi_d8_pl6, ddr, sdmmc2, vi, rsvd4, 0x144), + PG(vi_d9_pl7, ddr, sdmmc2, vi, rsvd4, 0x148), + PG(lcd_d16_pm0, displaya, displayb, rsvd3, rsvd4, 0x0e4), + PG(lcd_d17_pm1, displaya, displayb, rsvd3, rsvd4, 0x0e8), + PG(lcd_d18_pm2, displaya, displayb, rsvd3, rsvd4, 0x0ec), + PG(lcd_d19_pm3, displaya, displayb, rsvd3, rsvd4, 0x0f0), + PG(lcd_d20_pm4, displaya, displayb, rsvd3, rsvd4, 0x0f4), + PG(lcd_d21_pm5, displaya, displayb, rsvd3, rsvd4, 0x0f8), + PG(lcd_d22_pm6, displaya, displayb, rsvd3, rsvd4, 0x0fc), + PG(lcd_d23_pm7, displaya, displayb, rsvd3, rsvd4, 0x100), + PG(dap1_fs_pn0, i2s0, hda, gmi, sdmmc2, 0x338), + PG(dap1_din_pn1, i2s0, hda, gmi, sdmmc2, 0x33c), + PG(dap1_dout_pn2, i2s0, hda, gmi, sdmmc2, 0x340), + PG(dap1_sclk_pn3, i2s0, hda, gmi, sdmmc2, 0x344), + PG(lcd_cs0_n_pn4, displaya, displayb, spi5, rsvd4, 0x084), + PG(lcd_sdout_pn5, displaya, displayb, spi5, hdcp, 0x07c), + PG(lcd_dc0_pn6, displaya, displayb, rsvd3, rsvd4, 0x088), + PG(hdmi_int_pn7, hdmi, rsvd2, rsvd3, rsvd4, 0x110), + PG(ulpi_data7_po0, spi2, hsi, uarta, ulpi, 0x01c), + PG(ulpi_data0_po1, spi3, hsi, uarta, ulpi, 0x000), + PG(ulpi_data1_po2, spi3, hsi, uarta, ulpi, 0x004), + PG(ulpi_data2_po3, spi3, hsi, uarta, ulpi, 0x008), + PG(ulpi_data3_po4, spi3, hsi, uarta, ulpi, 0x00c), + PG(ulpi_data4_po5, spi2, hsi, uarta, ulpi, 0x010), + PG(ulpi_data5_po6, spi2, hsi, uarta, ulpi, 0x014), + PG(ulpi_data6_po7, spi2, hsi, uarta, ulpi, 0x018), + PG(dap3_fs_pp0, i2s2, rsvd2, displaya, displayb, 0x030), + PG(dap3_din_pp1, i2s2, rsvd2, displaya, displayb, 0x034), + PG(dap3_dout_pp2, i2s2, rsvd2, displaya, displayb, 0x038), + PG(dap3_sclk_pp3, i2s2, rsvd2, displaya, displayb, 0x03c), + PG(dap4_fs_pp4, i2s3, rsvd2, gmi, rsvd4, 0x1a8), + PG(dap4_din_pp5, i2s3, rsvd2, gmi, rsvd4, 0x1ac), + PG(dap4_dout_pp6, i2s3, rsvd2, gmi, rsvd4, 0x1b0), + PG(dap4_sclk_pp7, i2s3, rsvd2, gmi, rsvd4, 0x1b4), + PG(kb_col0_pq0, kbc, nand, trace, test, 0x2fc), + PG(kb_col1_pq1, kbc, nand, trace, test, 0x300), + PG(kb_col2_pq2, kbc, nand, trace, rsvd4, 0x304), + PG(kb_col3_pq3, kbc, nand, trace, rsvd4, 0x308), + PG(kb_col4_pq4, kbc, nand, trace, rsvd4, 0x30c), + PG(kb_col5_pq5, kbc, nand, trace, rsvd4, 0x310), + PG(kb_col6_pq6, kbc, nand, trace, mio, 0x314), + PG(kb_col7_pq7, kbc, nand, trace, mio, 0x318), + PG(kb_row0_pr0, kbc, nand, rsvd3, rsvd4, 0x2bc), + PG(kb_row1_pr1, kbc, nand, rsvd3, rsvd4, 0x2c0), + PG(kb_row2_pr2, kbc, nand, rsvd3, rsvd4, 0x2c4), + PG(kb_row3_pr3, kbc, nand, rsvd3, invalid, 0x2c8), + PG(kb_row4_pr4, kbc, nand, trace, rsvd4, 0x2cc), + PG(kb_row5_pr5, kbc, nand, trace, owr, 0x2d0), + PG(kb_row6_pr6, kbc, nand, sdmmc2, mio, 0x2d4), + PG(kb_row7_pr7, kbc, nand, sdmmc2, mio, 0x2d8), + PG(kb_row8_ps0, kbc, nand, sdmmc2, mio, 0x2dc), + PG(kb_row9_ps1, kbc, nand, sdmmc2, mio, 0x2e0), + PG(kb_row10_ps2, kbc, nand, sdmmc2, mio, 0x2e4), + PG(kb_row11_ps3, kbc, nand, sdmmc2, mio, 0x2e8), + PG(kb_row12_ps4, kbc, nand, sdmmc2, mio, 0x2ec), + PG(kb_row13_ps5, kbc, nand, sdmmc2, mio, 0x2f0), + PG(kb_row14_ps6, kbc, nand, sdmmc2, mio, 0x2f4), + PG(kb_row15_ps7, kbc, nand, sdmmc2, mio, 0x2f8), + PG(vi_pclk_pt0, rsvd1, sdmmc2, vi, rsvd4, 0x154), + PG(vi_mclk_pt1, vi, vi_alt1, vi_alt2, vi_alt3, 0x158), + PG(vi_d10_pt2, ddr, rsvd2, vi, rsvd4, 0x14c), + PG(vi_d11_pt3, ddr, rsvd2, vi, rsvd4, 0x150), + PG(vi_d0_pt4, ddr, rsvd2, vi, rsvd4, 0x124), + PG(gen2_i2c_scl_pt5, i2c2, hdcp, gmi, rsvd4, 0x250), + PG(gen2_i2c_sda_pt6, i2c2, hdcp, gmi, rsvd4, 0x254), + PG(sdmmc4_cmd_pt7, i2c3, nand, gmi, sdmmc4, 0x25c), + PG(pu0, owr, uarta, gmi, rsvd4, 0x184), + PG(pu1, rsvd1, uarta, gmi, rsvd4, 0x188), + PG(pu2, rsvd1, uarta, gmi, rsvd4, 0x18c), + PG(pu3, pwm0, uarta, gmi, rsvd4, 0x190), + PG(pu4, pwm1, uarta, gmi, rsvd4, 0x194), + PG(pu5, pwm2, uarta, gmi, rsvd4, 0x198), + PG(pu6, pwm3, uarta, gmi, rsvd4, 0x19c), + PG(jtag_rtck_pu7, rtck, rsvd2, rsvd3, rsvd4, 0x2b0), + PG(pv0, rsvd1, rsvd2, rsvd3, rsvd4, 0x040), + PG(pv1, rsvd1, rsvd2, rsvd3, rsvd4, 0x044), + PG(pv2, owr, rsvd2, rsvd3, rsvd4, 0x060), + PG(pv3, clk_12m_out, rsvd2, rsvd3, rsvd4, 0x064), + PG(ddc_scl_pv4, i2c4, rsvd2, rsvd3, rsvd4, 0x114), + PG(ddc_sda_pv5, i2c4, rsvd2, rsvd3, rsvd4, 0x118), + PG(crt_hsync_pv6, crt, rsvd2, rsvd3, rsvd4, 0x11c), + PG(crt_vsync_pv7, crt, rsvd2, rsvd3, rsvd4, 0x120), + PG(lcd_cs1_n_pw0, displaya, displayb, spi5, rsvd4, 0x104), + PG(lcd_m1_pw1, displaya, displayb, rsvd3, rsvd4, 0x108), + PG(spi2_cs1_n_pw2, spi3, spi2, spi2_alt, i2c1, 0x388), + PG(spi2_cs2_n_pw3, spi3, spi2, spi2_alt, i2c1, 0x38c), + PG(clk1_out_pw4, extperiph1, rsvd2, rsvd3, rsvd4, 0x34c), + PG(clk2_out_pw5, extperiph2, rsvd2, rsvd3, rsvd4, 0x068), + PG(uart3_txd_pw6, uartc, rsvd2, gmi, rsvd4, 0x174), + PG(uart3_rxd_pw7, uartc, rsvd2, gmi, rsvd4, 0x178), + PG(spi2_mosi_px0, spi6, spi2, spi3, gmi, 0x368), + PG(spi2_miso_px1, spi6, spi2, spi3, gmi, 0x36c), + PG(spi2_sck_px2, spi6, spi2, spi3, gmi, 0x374), + PG(spi2_cs0_n_px3, spi6, spi2, spi3, gmi, 0x370), + PG(spi1_mosi_px4, spi2, spi1, spi2_alt, gmi, 0x378), + PG(spi1_sck_px5, spi2, spi1, spi2_alt, gmi, 0x37c), + PG(spi1_cs0_n_px6, spi2, spi1, spi2_alt, gmi, 0x380), + PG(spi1_miso_px7, spi3, spi1, spi2_alt, rsvd4, 0x384), + PG(ulpi_clk_py0, spi1, rsvd2, uartd, ulpi, 0x020), + PG(ulpi_dir_py1, spi1, rsvd2, uartd, ulpi, 0x024), + PG(ulpi_nxt_py2, spi1, rsvd2, uartd, ulpi, 0x028), + PG(ulpi_stp_py3, spi1, rsvd2, uartd, ulpi, 0x02c), + PG(sdmmc1_dat3_py4, sdmmc1, rsvd2, uarte, uarta, 0x050), + PG(sdmmc1_dat2_py5, sdmmc1, rsvd2, uarte, uarta, 0x054), + PG(sdmmc1_dat1_py6, sdmmc1, rsvd2, uarte, uarta, 0x058), + PG(sdmmc1_dat0_py7, sdmmc1, rsvd2, uarte, uarta, 0x05c), + PG(sdmmc1_clk_pz0, sdmmc1, rsvd2, rsvd3, uarta, 0x048), + PG(sdmmc1_cmd_pz1, sdmmc1, rsvd2, rsvd3, uarta, 0x04c), + PG(lcd_sdin_pz2, displaya, displayb, spi5, rsvd4, 0x078), + PG(lcd_wr_n_pz3, displaya, displayb, spi5, hdcp, 0x080), + PG(lcd_sck_pz4, displaya, displayb, spi5, hdcp, 0x08c), + PG(sys_clk_req_pz5, sysclk, rsvd2, rsvd3, rsvd4, 0x320), + PG(pwr_i2c_scl_pz6, i2cpwr, rsvd2, rsvd3, rsvd4, 0x2b4), + PG(pwr_i2c_sda_pz7, i2cpwr, rsvd2, rsvd3, rsvd4, 0x2b8), + PG(sdmmc4_dat0_paa0, uarte, spi3, gmi, sdmmc4, 0x260), + PG(sdmmc4_dat1_paa1, uarte, spi3, gmi, sdmmc4, 0x264), + PG(sdmmc4_dat2_paa2, uarte, spi3, gmi, sdmmc4, 0x268), + PG(sdmmc4_dat3_paa3, uarte, spi3, gmi, sdmmc4, 0x26c), + PG(sdmmc4_dat4_paa4, i2c3, i2s4, gmi, sdmmc4, 0x270), + PG(sdmmc4_dat5_paa5, vgp3, i2s4, gmi, sdmmc4, 0x274), + PG(sdmmc4_dat6_paa6, vgp4, i2s4, gmi, sdmmc4, 0x278), + PG(sdmmc4_dat7_paa7, vgp5, i2s4, gmi, sdmmc4, 0x27c), + PG(pbb0, i2s4, rsvd2, rsvd3, sdmmc4, 0x28c), + PG(cam_i2c_scl_pbb1, vgp1, i2c3, rsvd3, sdmmc4, 0x290), + PG(cam_i2c_sda_pbb2, vgp2, i2c3, rsvd3, sdmmc4, 0x294), + PG(pbb3, vgp3, displaya, displayb, sdmmc4, 0x298), + PG(pbb4, vgp4, displaya, displayb, sdmmc4, 0x29c), + PG(pbb5, vgp5, displaya, displayb, sdmmc4, 0x2a0), + PG(pbb6, vgp6, displaya, displayb, sdmmc4, 0x2a4), + PG(pbb7, i2s4, rsvd2, rsvd3, sdmmc4, 0x2a8), + PG(cam_mclk_pcc0, vi, vi_alt1, vi_alt3, sdmmc4, 0x284), + PG(pcc1, i2s4, rsvd2, rsvd3, sdmmc4, 0x288), + PG(pcc2, i2s4, rsvd2, rsvd3, rsvd4, 0x2ac), + PG(sdmmc4_rst_n_pcc3, vgp6, rsvd2, rsvd3, sdmmc4, 0x280), + PG(sdmmc4_clk_pcc4, invalid, nand, gmi, sdmmc4, 0x258), + PG(clk2_req_pcc5, dap, rsvd2, rsvd3, rsvd4, 0x06c), + PG(pex_l2_rst_n_pcc6, pcie, hda, rsvd3, rsvd4, 0x3d8), + PG(pex_l2_clkreq_n_pcc7, pcie, hda, rsvd3, rsvd4, 0x3dc), + PG(pex_l0_prsnt_n_pdd0, pcie, hda, rsvd3, rsvd4, 0x3b8), + PG(pex_l0_rst_n_pdd1, pcie, hda, rsvd3, rsvd4, 0x3bc), + PG(pex_l0_clkreq_n_pdd2, pcie, hda, rsvd3, rsvd4, 0x3c0), + PG(pex_wake_n_pdd3, pcie, hda, rsvd3, rsvd4, 0x3c4), + PG(pex_l1_prsnt_n_pdd4, pcie, hda, rsvd3, rsvd4, 0x3c8), + PG(pex_l1_rst_n_pdd5, pcie, hda, rsvd3, rsvd4, 0x3cc), + PG(pex_l1_clkreq_n_pdd6, pcie, hda, rsvd3, rsvd4, 0x3d0), + PG(pex_l2_prsnt_n_pdd7, pcie, hda, rsvd3, rsvd4, 0x3d4), + PG(clk3_out_pee0, extperiph3, rsvd2, rsvd3, rsvd4, 0x1b8), + PG(clk3_req_pee1, dev3, rsvd2, rsvd3, rsvd4, 0x1bc), + PG(clk1_req_pee2, dap, hda, rsvd3, rsvd4, 0x348), + PG(hdmi_cec_pee3, cec, rsvd2, rsvd3, rsvd4, 0x3e0), + PG(clk_32k_in, clk_32k_in, rsvd2, rsvd3, rsvd4, 0x330), + PG(core_pwr_req, core_pwr_req, rsvd2, rsvd3, rsvd4, 0x324), + PG(cpu_pwr_req, cpu_pwr_req, rsvd2, rsvd3, rsvd4, 0x328), + PG(owr, owr, cec, rsvd3, rsvd4, 0x334), + PG(pwr_int_n, pwr_int_n, rsvd2, rsvd3, rsvd4, 0x32c), +}; + +static void pinctrl_tegra30_set_func(struct pinctrl_tegra30 *ctrl, + u32 reg, int func) +{ + u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2); + u32 val; + + val = readl(regaddr); + val &= ~(0x3); + val |= func; + writel(val, regaddr); +} + +static void pinctrl_tegra30_set_pull(struct pinctrl_tegra30 *ctrl, + u32 reg, int pull) +{ + u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2); + u32 val; + + val = readl(regaddr); + val &= ~(0x3 << 2); + val |= pull << 2; + writel(val, regaddr); +} + +static void pinctrl_tegra30_set_input(struct pinctrl_tegra30 *ctrl, + u32 reg, int input) +{ + u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2); + u32 val; + + val = readl(regaddr); + val &= ~(1 << 5); + val |= input << 5; + writel(val, regaddr); +} + +static void pinctrl_tegra30_set_tristate(struct pinctrl_tegra30 *ctrl, + u32 reg, int tristate) +{ + u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2); + u32 val; + + val = readl(regaddr); + val &= ~(1 << 4); + val |= tristate << 4; + writel(val, regaddr); +} + +static void pinctrl_tegra30_set_opendrain(struct pinctrl_tegra30 *ctrl, + u32 reg, int opendrain) +{ + u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2); + u32 val; + + val = readl(regaddr); + val &= ~(1 << 6); + val |= opendrain << 6; + writel(val, regaddr); +} + +static void pinctrl_tegra30_set_ioreset(struct pinctrl_tegra30 *ctrl, + u32 reg, int ioreset) +{ + u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2); + u32 val; + + val = readl(regaddr); + val &= ~(1 << 8); + val |= ioreset << 8; + writel(val, regaddr); +} + +static int pinctrl_tegra30_set_state(struct pinctrl_device *pdev, + struct device_node *np) +{ + struct pinctrl_tegra30 *ctrl = + container_of(pdev, struct pinctrl_tegra30, pinctrl); + struct device_node *childnode; + int pull = -1, tri = -1, in = -1, od = -1, ior = -1, i, j, k; + const char *pins, *func = NULL; + const struct tegra30_pingroup *group; + + /* + * At first look if the node we are pointed at has children, + * which we may want to visit. + */ + list_for_each_entry(childnode, &np->children, parent_list) + pinctrl_tegra30_set_state(pdev, childnode); + + /* read relevant state from devicetree */ + of_property_read_string(np, "nvidia,function", &func); + of_property_read_u32_array(np, "nvidia,pull", &pull, 1); + of_property_read_u32_array(np, "nvidia,tristate", &tri, 1); + of_property_read_u32_array(np, "nvidia,enable-input", &in, 1); + of_property_read_u32_array(np, "nvidia,open-drain", &od, 1); + of_property_read_u32_array(np, "nvidia,io-reset", &ior, 1); + + /* iterate over all pingroups referenced in the dt node */ + for (i = 0; ; i++) { + if (of_property_read_string_index(np, "nvidia,pins", i, &pins)) + break; + + for (j = 0; j < ARRAY_SIZE(tegra30_groups); j++) { + if (!strcmp(pins, tegra30_groups[j].name)) { + group = &tegra30_groups[j]; + break; + } + } + /* if no matching pingroup is found bail out */ + if (j == ARRAY_SIZE(tegra30_groups)) { + dev_warn(ctrl->pinctrl.dev, + "invalid pingroup %s referenced in node %s\n", + pins, np->name); + continue; + } + + if (func) { + for (k = 0; k < 4; k++) { + if (!strcmp(func, group->funcs[k])) + break; + } + if (k < 4) + pinctrl_tegra30_set_func(ctrl, group->reg, k); + else + dev_warn(ctrl->pinctrl.dev, + "invalid function %s for pingroup %s in node %s\n", + func, group->name, np->name); + } + + if (pull >= 0) + pinctrl_tegra30_set_pull(ctrl, group->reg, pull); + + if (in >= 0) + pinctrl_tegra30_set_input(ctrl, group->reg, in); + + if (tri >= 0) + pinctrl_tegra30_set_tristate(ctrl, group->reg, tri); + + if (od >= 0) + pinctrl_tegra30_set_opendrain(ctrl, group->reg, od); + + if (ior >= 0) + pinctrl_tegra30_set_ioreset(ctrl, group->reg, ior); + } + + return 0; +} + +static struct pinctrl_ops pinctrl_tegra30_ops = { + .set_state = pinctrl_tegra30_set_state, +}; + +static int pinctrl_tegra30_probe(struct device_d *dev) +{ + struct pinctrl_tegra30 *ctrl; + int i, ret; + u32 **regs; + + ctrl = xzalloc(sizeof(*ctrl)); + + /* + * Tegra pincontrol is split out into four independent memory ranges: + * tristate control, function mux, pullup/down control, pad control + * (from lowest to highest hardware address). + * We are only interested in the first three for now. + */ + regs = (u32 **)&ctrl->regs; + for (i = 0; i <= 1; i++) { + regs[i] = dev_request_mem_region(dev, i); + if (!regs[i]) { + dev_err(dev, "Could not get iomem region %d\n", i); + return -ENODEV; + } + } + + ctrl->pinctrl.dev = dev; + ctrl->pinctrl.ops = &pinctrl_tegra30_ops; + + ret = pinctrl_register(&ctrl->pinctrl); + if (ret) + free(ctrl); + + return ret; +} + +static __maybe_unused struct of_device_id pinctrl_tegra30_dt_ids[] = { + { + .compatible = "nvidia,tegra30-pinmux", + }, { + /* sentinel */ + } +}; + +static struct driver_d pinctrl_tegra30_driver = { + .name = "pinctrl-tegra30", + .probe = pinctrl_tegra30_probe, + .of_compatible = DRV_OF_COMPAT(pinctrl_tegra30_dt_ids), +}; + +static int pinctrl_tegra30_init(void) +{ + return platform_driver_register(&pinctrl_tegra30_driver); +} +postcore_initcall(pinctrl_tegra30_init); diff --git a/images/Makefile.tegra b/images/Makefile.tegra index f03503e83..c95759995 100644 --- a/images/Makefile.tegra +++ b/images/Makefile.tegra @@ -12,3 +12,8 @@ image-$(CONFIG_MACH_TOSHIBA_AC100) += barebox-tegra20-toshiba-ac100.img pblx-$(CONFIG_MACH_TORADEX_COLIBRI_T20) += start_toradex_colibri_t20_iris FILE_barebox-tegra20-toradex-colibri-t20-iris.img = start_toradex_colibri_t20_iris.pblx image-$(CONFIG_MACH_TORADEX_COLIBRI_T20) += barebox-tegra20-toradex-colibri-t20-iris.img + +# ----------------------- Tegra30 based boards --------------------------- +pblx-$(CONFIG_MACH_NVIDIA_BEAVER) += start_nvidia_beaver +FILE_barebox-tegra30-nvidia-beaver.img = start_nvidia_beaver.pblx +image-$(CONFIG_MACH_NVIDIA_BEAVER) += barebox-tegra30-nvidia-beaver.img diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h new file mode 100644 index 000000000..e40fae8f9 --- /dev/null +++ b/include/dt-bindings/clock/tegra30-car.h @@ -0,0 +1,265 @@ +/* + * This header provides constants for binding nvidia,tegra30-car. + * + * The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB + * registers. These IDs often match those in the CAR's RST_DEVICES registers, + * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In + * this case, those clocks are assigned IDs above 160 in order to highlight + * this issue. Implementations that interpret these clock IDs as bit values + * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to + * explicitly handle these special cases. + * + * The balance of the clocks controlled by the CAR are assigned IDs of 160 and + * above. + */ + +#ifndef _DT_BINDINGS_CLOCK_TEGRA30_CAR_H +#define _DT_BINDINGS_CLOCK_TEGRA30_CAR_H + +#define TEGRA30_CLK_CPU 0 +/* 1 */ +/* 2 */ +/* 3 */ +#define TEGRA30_CLK_RTC 4 +#define TEGRA30_CLK_TIMER 5 +#define TEGRA30_CLK_UARTA 6 +/* 7 (register bit affects uartb and vfir) */ +#define TEGRA30_CLK_GPIO 8 +#define TEGRA30_CLK_SDMMC2 9 +/* 10 (register bit affects spdif_in and spdif_out) */ +#define TEGRA30_CLK_I2S1 11 +#define TEGRA30_CLK_I2C1 12 +#define TEGRA30_CLK_NDFLASH 13 +#define TEGRA30_CLK_SDMMC1 14 +#define TEGRA30_CLK_SDMMC4 15 +/* 16 */ +#define TEGRA30_CLK_PWM 17 +#define TEGRA30_CLK_I2S2 18 +#define TEGRA30_CLK_EPP 19 +/* 20 (register bit affects vi and vi_sensor) */ +#define TEGRA30_CLK_GR2D 21 +#define TEGRA30_CLK_USBD 22 +#define TEGRA30_CLK_ISP 23 +#define TEGRA30_CLK_GR3D 24 +/* 25 */ +#define TEGRA30_CLK_DISP2 26 +#define TEGRA30_CLK_DISP1 27 +#define TEGRA30_CLK_HOST1X 28 +#define TEGRA30_CLK_VCP 29 +#define TEGRA30_CLK_I2S0 30 +#define TEGRA30_CLK_COP_CACHE 31 + +#define TEGRA30_CLK_MC 32 +#define TEGRA30_CLK_AHBDMA 33 +#define TEGRA30_CLK_APBDMA 34 +/* 35 */ +#define TEGRA30_CLK_KBC 36 +#define TEGRA30_CLK_STATMON 37 +#define TEGRA30_CLK_PMC 38 +/* 39 (register bit affects fuse and fuse_burn) */ +#define TEGRA30_CLK_KFUSE 40 +#define TEGRA30_CLK_SBC1 41 +#define TEGRA30_CLK_NOR 42 +/* 43 */ +#define TEGRA30_CLK_SBC2 44 +/* 45 */ +#define TEGRA30_CLK_SBC3 46 +#define TEGRA30_CLK_I2C5 47 +#define TEGRA30_CLK_DSIA 48 +/* 49 (register bit affects cve and tvo) */ +#define TEGRA30_CLK_MIPI 50 +#define TEGRA30_CLK_HDMI 51 +#define TEGRA30_CLK_CSI 52 +#define TEGRA30_CLK_TVDAC 53 +#define TEGRA30_CLK_I2C2 54 +#define TEGRA30_CLK_UARTC 55 +/* 56 */ +#define TEGRA30_CLK_EMC 57 +#define TEGRA30_CLK_USB2 58 +#define TEGRA30_CLK_USB3 59 +#define TEGRA30_CLK_MPE 60 +#define TEGRA30_CLK_VDE 61 +#define TEGRA30_CLK_BSEA 62 +#define TEGRA30_CLK_BSEV 63 + +#define TEGRA30_CLK_SPEEDO 64 +#define TEGRA30_CLK_UARTD 65 +#define TEGRA30_CLK_UARTE 66 +#define TEGRA30_CLK_I2C3 67 +#define TEGRA30_CLK_SBC4 68 +#define TEGRA30_CLK_SDMMC3 69 +#define TEGRA30_CLK_PCIE 70 +#define TEGRA30_CLK_OWR 71 +#define TEGRA30_CLK_AFI 72 +#define TEGRA30_CLK_CSITE 73 +#define TEGRA30_CLK_PCIEX 74 +#define TEGRA30_CLK_AVPUCQ 75 +#define TEGRA30_CLK_LA 76 +/* 77 */ +/* 78 */ +#define TEGRA30_CLK_DTV 79 +#define TEGRA30_CLK_NDSPEED 80 +#define TEGRA30_CLK_I2CSLOW 81 +#define TEGRA30_CLK_DSIB 82 +/* 83 */ +#define TEGRA30_CLK_IRAMA 84 +#define TEGRA30_CLK_IRAMB 85 +#define TEGRA30_CLK_IRAMC 86 +#define TEGRA30_CLK_IRAMD 87 +#define TEGRA30_CLK_CRAM2 88 +/* 89 */ +#define TEGRA30_CLK_AUDIO_2X 90 /* a/k/a audio_2x_sync_clk */ +/* 91 */ +#define TEGRA30_CLK_CSUS 92 +#define TEGRA30_CLK_CDEV2 93 +#define TEGRA30_CLK_CDEV1 94 +/* 95 */ + +#define TEGRA30_CLK_CPU_G 96 +#define TEGRA30_CLK_CPU_LP 97 +#define TEGRA30_CLK_GR3D2 98 +#define TEGRA30_CLK_MSELECT 99 +#define TEGRA30_CLK_TSENSOR 100 +#define TEGRA30_CLK_I2S3 101 +#define TEGRA30_CLK_I2S4 102 +#define TEGRA30_CLK_I2C4 103 +#define TEGRA30_CLK_SBC5 104 +#define TEGRA30_CLK_SBC6 105 +#define TEGRA30_CLK_D_AUDIO 106 +#define TEGRA30_CLK_APBIF 107 +#define TEGRA30_CLK_DAM0 108 +#define TEGRA30_CLK_DAM1 109 +#define TEGRA30_CLK_DAM2 110 +#define TEGRA30_CLK_HDA2CODEC_2X 111 +#define TEGRA30_CLK_ATOMICS 112 +#define TEGRA30_CLK_AUDIO0_2X 113 +#define TEGRA30_CLK_AUDIO1_2X 114 +#define TEGRA30_CLK_AUDIO2_2X 115 +#define TEGRA30_CLK_AUDIO3_2X 116 +#define TEGRA30_CLK_AUDIO4_2X 117 +#define TEGRA30_CLK_SPDIF_2X 118 +#define TEGRA30_CLK_ACTMON 119 +#define TEGRA30_CLK_EXTERN1 120 +#define TEGRA30_CLK_EXTERN2 121 +#define TEGRA30_CLK_EXTERN3 122 +#define TEGRA30_CLK_SATA_OOB 123 +#define TEGRA30_CLK_SATA 124 +#define TEGRA30_CLK_HDA 125 +/* 126 */ +#define TEGRA30_CLK_SE 127 + +#define TEGRA30_CLK_HDA2HDMI 128 +#define TEGRA30_CLK_SATA_COLD 129 +/* 130 */ +/* 131 */ +/* 132 */ +/* 133 */ +/* 134 */ +/* 135 */ +/* 136 */ +/* 137 */ +/* 138 */ +/* 139 */ +/* 140 */ +/* 141 */ +/* 142 */ +/* 143 */ +/* 144 */ +/* 145 */ +/* 146 */ +/* 147 */ +/* 148 */ +/* 149 */ +/* 150 */ +/* 151 */ +/* 152 */ +/* 153 */ +/* 154 */ +/* 155 */ +/* 156 */ +/* 157 */ +/* 158 */ +/* 159 */ + +#define TEGRA30_CLK_UARTB 160 +#define TEGRA30_CLK_VFIR 161 +#define TEGRA30_CLK_SPDIF_IN 162 +#define TEGRA30_CLK_SPDIF_OUT 163 +#define TEGRA30_CLK_VI 164 +#define TEGRA30_CLK_VI_SENSOR 165 +#define TEGRA30_CLK_FUSE 166 +#define TEGRA30_CLK_FUSE_BURN 167 +#define TEGRA30_CLK_CVE 168 +#define TEGRA30_CLK_TVO 169 +#define TEGRA30_CLK_CLK_32K 170 +#define TEGRA30_CLK_CLK_M 171 +#define TEGRA30_CLK_CLK_M_DIV2 172 +#define TEGRA30_CLK_CLK_M_DIV4 173 +#define TEGRA30_CLK_PLL_REF 174 +#define TEGRA30_CLK_PLL_C 175 +#define TEGRA30_CLK_PLL_C_OUT1 176 +#define TEGRA30_CLK_PLL_M 177 +#define TEGRA30_CLK_PLL_M_OUT1 178 +#define TEGRA30_CLK_PLL_P 179 +#define TEGRA30_CLK_PLL_P_OUT1 180 +#define TEGRA30_CLK_PLL_P_OUT2 181 +#define TEGRA30_CLK_PLL_P_OUT3 182 +#define TEGRA30_CLK_PLL_P_OUT4 183 +#define TEGRA30_CLK_PLL_A 184 +#define TEGRA30_CLK_PLL_A_OUT0 185 +#define TEGRA30_CLK_PLL_D 186 +#define TEGRA30_CLK_PLL_D_OUT0 187 +#define TEGRA30_CLK_PLL_D2 188 +#define TEGRA30_CLK_PLL_D2_OUT0 189 +#define TEGRA30_CLK_PLL_U 190 +#define TEGRA30_CLK_PLL_X 191 + +#define TEGRA30_CLK_PLL_X_OUT0 192 +#define TEGRA30_CLK_PLL_E 193 +#define TEGRA30_CLK_SPDIF_IN_SYNC 194 +#define TEGRA30_CLK_I2S0_SYNC 195 +#define TEGRA30_CLK_I2S1_SYNC 196 +#define TEGRA30_CLK_I2S2_SYNC 197 +#define TEGRA30_CLK_I2S3_SYNC 198 +#define TEGRA30_CLK_I2S4_SYNC 199 +#define TEGRA30_CLK_VIMCLK_SYNC 200 +#define TEGRA30_CLK_AUDIO0 201 +#define TEGRA30_CLK_AUDIO1 202 +#define TEGRA30_CLK_AUDIO2 203 +#define TEGRA30_CLK_AUDIO3 204 +#define TEGRA30_CLK_AUDIO4 205 +#define TEGRA30_CLK_SPDIF 206 +#define TEGRA30_CLK_CLK_OUT_1 207 /* (extern1) */ +#define TEGRA30_CLK_CLK_OUT_2 208 /* (extern2) */ +#define TEGRA30_CLK_CLK_OUT_3 209 /* (extern3) */ +#define TEGRA30_CLK_SCLK 210 +#define TEGRA30_CLK_BLINK 211 +#define TEGRA30_CLK_CCLK_G 212 +#define TEGRA30_CLK_CCLK_LP 213 +#define TEGRA30_CLK_TWD 214 +#define TEGRA30_CLK_CML0 215 +#define TEGRA30_CLK_CML1 216 +#define TEGRA30_CLK_HCLK 217 +#define TEGRA30_CLK_PCLK 218 +/* 219 */ +/* 220 */ +/* 221 */ +/* 222 */ +/* 223 */ + +/* 288 */ +/* 289 */ +/* 290 */ +/* 291 */ +/* 292 */ +/* 293 */ +/* 294 */ +/* 295 */ +/* 296 */ +/* 297 */ +/* 298 */ +/* 299 */ +#define TEGRA30_CLK_CLK_OUT_1_MUX 300 +#define TEGRA30_CLK_CLK_MAX 301 + +#endif /* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */ diff --git a/include/dt-bindings/pinctrl/pinctrl-tegra.h b/include/dt-bindings/pinctrl/pinctrl-tegra.h new file mode 100644 index 000000000..ebafa498b --- /dev/null +++ b/include/dt-bindings/pinctrl/pinctrl-tegra.h @@ -0,0 +1,45 @@ +/* + * This header provides constants for Tegra pinctrl bindings. + * + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * Author: Laxman Dewangan + * + * 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. + */ + +#ifndef _DT_BINDINGS_PINCTRL_TEGRA_H +#define _DT_BINDINGS_PINCTRL_TEGRA_H + +/* + * Enable/disable for diffeent dt properties. This is applicable for + * properties nvidia,enable-input, nvidia,tristate, nvidia,open-drain, + * nvidia,lock, nvidia,rcv-sel, nvidia,high-speed-mode, nvidia,schmitt. + */ +#define TEGRA_PIN_DISABLE 0 +#define TEGRA_PIN_ENABLE 1 + +#define TEGRA_PIN_PULL_NONE 0 +#define TEGRA_PIN_PULL_DOWN 1 +#define TEGRA_PIN_PULL_UP 2 + +/* Low power mode driver */ +#define TEGRA_PIN_LP_DRIVE_DIV_8 0 +#define TEGRA_PIN_LP_DRIVE_DIV_4 1 +#define TEGRA_PIN_LP_DRIVE_DIV_2 2 +#define TEGRA_PIN_LP_DRIVE_DIV_1 3 + +/* Rising/Falling slew rate */ +#define TEGRA_PIN_SLEW_RATE_FASTEST 0 +#define TEGRA_PIN_SLEW_RATE_FAST 1 +#define TEGRA_PIN_SLEW_RATE_SLOW 2 +#define TEGRA_PIN_SLEW_RATE_SLOWEST 3 + +#endif