Guest User

Modern Switch Linux Patch

a guest
Aug 8th, 2018
788
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 243.21 KB | None | 0 0
  1. diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
  2. index dff236f..a4903f7 100644
  3. --- a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
  4. +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
  5. @@ -23,7 +23,8 @@ Required properties:
  6.  - clock-names: Must include the following entries:
  7.    - soc: Clock source for the DFLL control logic.
  8.    - ref: The closed loop reference clock
  9. -  - i2c: Clock source for the integrated I2C master.
  10. +  - i2c: Clock source for the integrated I2C master (only required when
  11. +    using I2C mode).
  12.  - resets: Must contain an entry for each entry in reset-names.
  13.    See ../reset/reset.txt for details.
  14.  - reset-names: Must include the following entries:
  15. @@ -45,10 +46,28 @@ Required properties for the control loop parameters:
  16.  Optional properties for the control loop parameters:
  17.  - nvidia,cg-scale: Boolean value, see the field DFLL_PARAMS_CG_SCALE in the TRM.
  18.  
  19. +Optional properties for mode selection:
  20. +- nvidia,pwm-to-pmic: Use PWM to control regulator rather then I2C.
  21. +
  22.  Required properties for I2C mode:
  23.  - nvidia,i2c-fs-rate: I2C transfer rate, if using full speed mode.
  24.  
  25. -Example:
  26. +Required properties for PWM mode:
  27. +- nvidia,pwm-period: period of PWM square wave in us.
  28. +- nvidia,init-uv: Regulator voltage in uV when PWM control is disabled.
  29. +- nvidia,align-offset-uv: Regulator voltage in uV when PWM control is enabled
  30. +             and PWM output is low.
  31. +- nvidia,align-step-uv: Voltage increase in uV corresponding to a 1/33th
  32. +           increase in duty cycle. Eg the voltage for 2/33th duty
  33. +           cycle would be:
  34. +           nvidia,align-offset-uv + nvidia,align-step-uv * 2.
  35. +- pinctrl-0: I/O pad configuration when PWM control is enabled.
  36. +- pinctrl-1: I/O pad configuration when PWM control is disabled.
  37. +- pinctrl-names: must include the following entries:
  38. +  - dvfs_pwm_enable: I/O pad configuration when PWM control is enabled.
  39. +  - dvfs_pwm_disable: I/O pad configuration when PWM control is disabled.
  40. +
  41. +Example for I2C:
  42.  
  43.  clock@70110000 {
  44.          compatible = "nvidia,tegra124-dfll";
  45. @@ -76,3 +95,56 @@ clock@70110000 {
  46.  
  47.          nvidia,i2c-fs-rate = <400000>;
  48.  };
  49. +
  50. +Example for PWM:
  51. +
  52. +clock@70110000 {
  53. +        compatible = "nvidia,tegra124-dfll";
  54. +        reg = <0 0x70110000 0 0x100>, /* DFLL control */
  55. +              <0 0x70110000 0 0x100>, /* I2C output control */
  56. +              <0 0x70110100 0 0x100>, /* Integrated I2C controller */
  57. +              <0 0x70110200 0 0x100>; /* Look-up table RAM */
  58. +        interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
  59. +        clocks = <&tegra_car TEGRA210_CLK_DFLL_SOC>,
  60. +                 <&tegra_car TEGRA210_CLK_DFLL_REF>;
  61. +        clock-names = "soc", "ref";
  62. +        resets = <&tegra_car TEGRA124_RST_DFLL_DVCO>;
  63. +        reset-names = "dvco";
  64. +        #clock-cells = <0>;
  65. +        clock-output-names = "dfllCPU_out";
  66. +   nvidia,pwm-to-pmic;
  67. +   nvidia,init-uv = <1000000>;
  68. +   nvidia,align-step-uv = <19200>; /* 19.2mV */
  69. +   nvidia,align-offset-uv = <708000>; /* 708mV */
  70. +   nvidia,sample-rate = <25000>;
  71. +   nvidia,droop-ctrl = <0x00000f00>;
  72. +   nvidia,force-mode = <1>;
  73. +   nvidia,cf = <6>;
  74. +   nvidia,ci = <0>;
  75. +   nvidia,cg = <2>;
  76. +   nvidia,idle-override;
  77. +   nvidia,one-shot-calibrate;
  78. +   nvidia,pwm-period = <2500>; /* 2.5us */
  79. +   pinctrl-names = "dvfs_pwm_enable", "dvfs_pwm_disable";
  80. +   pinctrl-0 = <&dvfs_pwm_active_state>;
  81. +   pinctrl-1 = <&dvfs_pwm_inactive_state>;
  82. +};
  83. +
  84. +/* pinmux nodes added for completeness. Binding doc can be found in:
  85. + * Documentation/devicetree/bindings/pinctrl/nvidia,tegra210-pinmux.txt
  86. + */
  87. +
  88. +pinmux: pinmux@700008d4 {
  89. +   dvfs_pwm_active_state: dvfs_pwm_active {
  90. +       dvfs_pwm_pbb1 {
  91. +           nvidia,pins = "dvfs_pwm_pbb1";
  92. +           nvidia,tristate = <TEGRA_PIN_DISABLE>;
  93. +       };
  94. +   };
  95. +   dvfs_pwm_inactive_state: dvfs_pwm_inactive {
  96. +       dvfs_pwm_pbb1 {
  97. +           nvidia,pins = "dvfs_pwm_pbb1";
  98. +           nvidia,tristate = <TEGRA_PIN_ENABLE>;
  99. +       };
  100. +   };
  101. +};
  102. diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
  103. index 9bce578..cda29fd 100644
  104. --- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
  105. +++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
  106. @@ -23,6 +23,8 @@ Required properties:
  107.  
  108.  Optional properties:
  109.  - power-gpios : Specify GPIOs for power control
  110. +- nvidia,pad : Specify the pad ID for controlling the I/O voltage level.
  111. +  Required for 1.8V mode support on Tegra210.
  112.  
  113.  Example:
  114.  
  115. diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
  116. index 7c13d7d..17ab6c4 100644
  117. --- a/arch/arm64/boot/dts/nvidia/Makefile
  118. +++ b/arch/arm64/boot/dts/nvidia/Makefile
  119. @@ -1,5 +1,6 @@
  120.  # SPDX-License-Identifier: GPL-2.0
  121.  dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb
  122. +dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-nintendo-switch.dtb
  123.  dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-0000.dtb
  124.  dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb
  125.  dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb
  126. diff --git a/arch/arm64/boot/dts/nvidia/tegra210-nintendo-switch.dts b/arch/arm64/boot/dts/nvidia/tegra210-nintendo-switch.dts
  127. new file mode 100644
  128. index 0000000..44de6b5
  129. --- /dev/null
  130. +++ b/arch/arm64/boot/dts/nvidia/tegra210-nintendo-switch.dts
  131. @@ -0,0 +1,1325 @@
  132. +// SPDX-License-Identifier: GPL-2.0
  133. +/dts-v1/;
  134. +
  135. +#include <dt-bindings/input/input.h>
  136. +#include <dt-bindings/mfd/max77620.h>
  137. +#include <dt-bindings/pwm/pwm.h>
  138. +#include <dt-bindings/thermal/thermal.h>
  139. +
  140. +#include "tegra210.dtsi"
  141. +
  142. +/ {
  143. +   model = "Nintendo Switch";
  144. +   compatible = "nintendo,switch", "nvidia,tegra210";
  145. +
  146. +   aliases {
  147. +       i2c1 = "/i2c@7000c000";
  148. +       i2c2 = "/i2c@7000c400";
  149. +       i2c3 = "/i2c@7000c500";
  150. +       i2c5 = "/i2c@7000d000";
  151. +       rtc0 = "/i2c@7000d000/max77620@3c";
  152. +       rtc1 = "/rtc@7000e000";
  153. +       serial0 = &uarta;
  154. +       serial1 = &uartb;
  155. +       serial2 = &uartc;
  156. +       serial3 = &uartd;
  157. +   };
  158. +
  159. +   chosen {
  160. +       bootargs = "earlycon drm.debug=0x3f";
  161. +       stdout-path = "serial1:115200n8";
  162. +   };
  163. +
  164. +   memory {
  165. +       device_type = "memory";
  166. +       reg = <0x0 0x80000000 0x1 0x0>;
  167. +   };
  168. +
  169. +   cpus {
  170. +       cpu@0 {
  171. +           vdd-cpu-supply = <&max77621_cpu>;
  172. +       };
  173. +   };
  174. +
  175. +   clock@70110000 {
  176. +       status = "okay";
  177. +
  178. +       vdd-cpu-supply = <&max77621_cpu>;
  179. +       nvidia,sample-rate = <12500>;
  180. +       nvidia,droop-ctrl = <0x00000f00>;
  181. +       nvidia,force-mode = <1>;
  182. +       nvidia,cf = <10>;
  183. +       nvidia,ci = <0>;
  184. +       nvidia,cg = <2>;
  185. +       nvidia,i2c-fs-rate = <400000>;
  186. +   };
  187. +
  188. +   pcie@1003000 {
  189. +       status = "okay";
  190. +
  191. +       avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
  192. +       hvddio-pex-supply = <&vdd_1v8>;
  193. +       dvddio-pex-supply = <&vdd_pex_1v05>;
  194. +       dvdd-pex-pll-supply = <&vdd_pex_1v05>;
  195. +       hvdd-pex-pll-e-supply = <&vdd_1v8>;
  196. +       vddio-pex-ctl-supply = <&vdd_1v8>;
  197. +
  198. +       pci@1,0 {
  199. +           phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
  200. +                  <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>,
  201. +                  <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>,
  202. +                  <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
  203. +           phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3";
  204. +           status = "okay";
  205. +       };
  206. +
  207. +       pci@2,0 {
  208. +           phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>;
  209. +           phy-names = "pcie-0";
  210. +           status = "okay";
  211. +       };
  212. +   };
  213. +
  214. +   host1x@50000000 {
  215. +       dsi@54300000 {
  216. +           status = "okay";
  217. +
  218. +           avdd-dsi-csi-supply = <&vdd_dsi_csi>;
  219. +
  220. +           panel@0 {
  221. +               compatible = "jdi,lpm062m326a";
  222. +               reg = <0>;
  223. +
  224. +               reset-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
  225. +               vdd1-supply = <&vdd_lcd_1>;
  226. +               vdd2-supply = <&vdd_lcd_2>;
  227. +               backlight = <&backlight>;
  228. +           };
  229. +       };
  230. +
  231. +       dpaux@54040000 {
  232. +           //status = "okay";
  233. +       };
  234. +
  235. +   };
  236. +
  237. +   backlight: backlight {
  238. +       compatible = "pwm-backlight";
  239. +       pwms = <&pwm 0 1666666 0>;
  240. +       pwm-names = "backlight";
  241. +       brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  242. +                            17 18 19 20 21 22 23 24 25 26 27 28 29 30
  243. +                            31 32 33 34 35 36 37 38 39 40 41 42 43 44
  244. +                            45 46 47 48 49 50 51 52 53 54 55 56 57 58
  245. +                            59 60 61 62 63 64 65 66 67 68 69 70 71 72
  246. +                            73 74 75 76 77 78 79 80 81 82 83 84 85 86
  247. +                            87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
  248. +       default-brightness-level = <80>;
  249. +
  250. +       enable-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
  251. +   };
  252. +
  253. +   gpu@57000000 {
  254. +       vdd-supply = <&max77621_gpu>;
  255. +   };
  256. +
  257. +   pinmux: pinmux@700008d4 {
  258. +       pinctrl-names = "default";
  259. +       pinctrl-0 = <&state_default>;
  260. +
  261. +       state_default: pinmux {
  262. +           // I2C
  263. +           i2c1 {
  264. +               nvidia,pins = "gen1_i2c_sda_pj0", "gen1_i2c_scl_pj1";
  265. +               nvidia,function = "i2c1";
  266. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  267. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  268. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  269. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  270. +               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
  271. +           };
  272. +           i2c2 {
  273. +               nvidia,pins = "gen2_i2c_scl_pj2", "gen2_i2c_sda_pj3";
  274. +               nvidia,function = "i2c2";
  275. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  276. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  277. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  278. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  279. +               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
  280. +           };
  281. +           i2c3 {
  282. +               nvidia,pins = "gen3_i2c_scl_pf0", "gen3_i2c_sda_pf1";
  283. +               nvidia,function = "i2c3";
  284. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  285. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  286. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  287. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  288. +               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
  289. +           };
  290. +           i2c5 {
  291. +               nvidia,pins = "pwr_i2c_scl_py3", "pwr_i2c_sda_py4";
  292. +               nvidia,function = "i2cpmu";
  293. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  294. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  295. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  296. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  297. +               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
  298. +           };
  299. +
  300. +           // Right side Joy-Con
  301. +           uart2_tx {
  302. +               nvidia,pins = "uart2_tx_pg0", "uart2_rts_pg2";
  303. +               nvidia,function = "uartb";
  304. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  305. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  306. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  307. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  308. +           };
  309. +           uart2_rx {
  310. +               nvidia,pins = "uart2_rx_pg1", "uart2_cts_pg3";
  311. +               nvidia,function = "uartb";
  312. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  313. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  314. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  315. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  316. +           };
  317. +           joycon_right_insert_tx {
  318. +               nvidia,pins = "ph6";
  319. +               nvidia,function = "rsvd0";
  320. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  321. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  322. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  323. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  324. +           };
  325. +           joycon_right_charge {
  326. +               nvidia,pins = "pk3";
  327. +               nvidia,function = "rsvd2";
  328. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  329. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  330. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  331. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  332. +           };
  333. +
  334. +           // Left side Joy-Con
  335. +           uart3_tx {
  336. +               nvidia,pins = "uart3_tx_pd1", "uart3_rts_pd3";
  337. +               nvidia,function = "uartc";
  338. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  339. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  340. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  341. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  342. +           };
  343. +           uart3_rx {
  344. +               nvidia,pins = "uart3_rx_pd2", "uart3_cts_pd4";
  345. +               nvidia,function = "uartc";
  346. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  347. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  348. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  349. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  350. +           };
  351. +           joycon_left_insert_tx {
  352. +               nvidia,pins = "pe6";
  353. +               nvidia,function = "rsvd0";
  354. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  355. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  356. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  357. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  358. +           };
  359. +           joycon_left_charge {
  360. +               nvidia,pins = "spdif_in_pcc3";
  361. +               nvidia,function = "rsvd1";
  362. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  363. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  364. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  365. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  366. +           };
  367. +
  368. +           // SD card
  369. +           sdmmc1_clk {
  370. +               nvidia,pins = "sdmmc1_clk_pm0";
  371. +               nvidia,function = "sdmmc1";
  372. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  373. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  374. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  375. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  376. +           };
  377. +           sdmmc1_io {
  378. +               nvidia,pins = "sdmmc1_cmd_pm1", "sdmmc1_dat3_pm2", "sdmmc1_dat2_pm3", "sdmmc1_dat1_pm4", "sdmmc1_dat0_pm5";
  379. +               nvidia,function = "sdmmc1";
  380. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  381. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  382. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  383. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  384. +           };
  385. +           sdmmc1_cd {
  386. +               nvidia,pins = "pz1";
  387. +               nvidia,function = "sdmmc1";
  388. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  389. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  390. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  391. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  392. +           };
  393. +           sdmmc1_pwr {
  394. +               nvidia,pins = "dmic3_clk_pe4";
  395. +               nvidia,function = "rsvd3";
  396. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  397. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  398. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  399. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  400. +           };
  401. +
  402. +           // LCD control
  403. +           lcd_bl_pwm {
  404. +               nvidia,pins = "lcd_bl_pwm_pv0";
  405. +               nvidia,function = "pwm0";
  406. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  407. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  408. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  409. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  410. +           };
  411. +           lcd_gpio {
  412. +               // bl_en, rst, pwr1, pwr2
  413. +               nvidia,pins = "lcd_bl_en_pv1", "lcd_rst_pv2", "nfc_en_pi0", "nfc_int_pi1";
  414. +               nvidia,function = "rsvd3";
  415. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  416. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  417. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  418. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  419. +           };
  420. +
  421. +           // Buttons
  422. +           buttons {
  423. +               nvidia,pins = "button_vol_up_px6", "button_vol_down_px7";
  424. +               nvidia,function = "rsvd3";
  425. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  426. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  427. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  428. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  429. +           };
  430. +
  431. +           // Audio codec
  432. +           rt5639_pwr { // or reset?
  433. +               nvidia,pins = "pz4";
  434. +               nvidia,function = "rsvd3";
  435. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  436. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  437. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  438. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  439. +           };
  440. +           rt5639_irq { // guess, could be bb4
  441. +               nvidia,pins = "touch_rst_pv6";
  442. +               nvidia,function = "rsvd3";
  443. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  444. +               nvidia,tristate = <TEGRA_PIN_ENABLE>;
  445. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  446. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  447. +           };
  448. +
  449. +           // Fan
  450. +           fan_pwr {
  451. +               nvidia,pins = "sata_led_active_pa5", "usb_vbus_en0_pcc4";
  452. +               nvidia,function = "rsvd3";
  453. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  454. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  455. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  456. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  457. +           };
  458. +           fan_pwm {
  459. +               nvidia,pins = "lcd_gpio2_pv4";
  460. +               nvidia,function = "pwm1";
  461. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  462. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  463. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  464. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  465. +           };
  466. +
  467. +           // Touchscreen
  468. +           touch_enable {
  469. +               nvidia,pins = "dap4_sclk_pj7";
  470. +               nvidia,function = "rsvd3";
  471. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  472. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  473. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  474. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  475. +           };
  476. +
  477. +           // Bluetooth
  478. +           bt_rst {
  479. +               nvidia,pins = "bt_rst_ph4";
  480. +               nvidia,function = "rsvd0";
  481. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  482. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  483. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  484. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  485. +           };
  486. +           bt_wake {
  487. +               nvidia,pins = "ap_wake_bt_ph3";
  488. +               nvidia,function = "rsvd0";
  489. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  490. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  491. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  492. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  493. +           };
  494. +           bt_uart_tx {
  495. +               nvidia,pins = "uart4_tx_pi4", "uart4_rts_pi6";
  496. +               nvidia,function = "uartd";
  497. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  498. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  499. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  500. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  501. +           };
  502. +           bt_uart_rx {
  503. +               nvidia,pins = "uart4_rx_pi5", "uart4_cts_pi7";
  504. +               nvidia,function = "uartd";
  505. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  506. +               nvidia,tristate = <TEGRA_PIN_ENABLE>;
  507. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  508. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  509. +           };
  510. +
  511. +           // Misc unknown GPIOs
  512. +           in_none {
  513. +               // p5,p4,p3,p2,s1,h5,x5,y1,e6,h6,k2
  514. +               nvidia,pins = "sdmmc3_dat0_pp5", "sdmmc3_dat1_pp4", "sdmmc3_dat2_pp3", "sdmmc3_dat3_pp2", "cam2_mclk_ps1", "bt_wake_ap_ph5", "button_power_on_px5", "button_home_py1", "pe6", "ph6", "pk2";
  515. +               nvidia,function = "rsvd3";
  516. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  517. +               nvidia,tristate = <TEGRA_PIN_ENABLE>;
  518. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  519. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  520. +           };
  521. +           in_up {
  522. +               // s3,bb2,cc2,s7,x1,x4,y0,k4,k6,k7,z0,z3
  523. +               nvidia,pins = "cam_i2c_sda_ps3", "dvfs_clk_pbb2", "spdif_out_pcc2", "cam1_pwdn_ps7", "touch_int_px1", "temp_alert_px4", "button_slide_sw_py0", "pk4", "pk6", "pk7", "pz0", "pz3";
  524. +               nvidia,function = "rsvd3";
  525. +               nvidia,pull = <TEGRA_PIN_PULL_UP>;
  526. +               nvidia,tristate = <TEGRA_PIN_ENABLE>;
  527. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  528. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  529. +           };
  530. +           in_down {
  531. +               // p0,s0,h2,x2,k0,k1,z2,bb4
  532. +               nvidia,pins = "sdmmc3_clk_pp0", "cam1_mclk_ps0", "wifi_wake_ap_ph2", "motion_int_px2", "pk0", "pk1", "pz2", "gpio_x3_aud_pbb4";
  533. +               nvidia,function = "rsvd3";
  534. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  535. +               nvidia,tristate = <TEGRA_PIN_ENABLE>;
  536. +               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
  537. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  538. +           };
  539. +           out_none {
  540. +               // h7
  541. +               nvidia,pins = "ap_wake_nfc_ph7";
  542. +               nvidia,function = "rsvd3";
  543. +               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
  544. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  545. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  546. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  547. +           };
  548. +           out_down {
  549. +               // e5,j5,bb3,cc3,h0,h1,s6,v5,k3,k5,l0
  550. +               nvidia,pins = "dmic3_dat_pe5", "dap4_din_pj5", "gpio_x1_aud_pbb3", "spdif_in_pcc3", "wifi_en_ph0", "wifi_rst_ph1", "cam_flash_en_ps6", "ap_ready_pv5", "pk3", "pk5", "pl0";
  551. +               nvidia,function = "rsvd3";
  552. +               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
  553. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  554. +               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
  555. +               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  556. +           };
  557. +       };
  558. +   };
  559. +
  560. +   /* debug port */
  561. +   serial@70006000 {
  562. +       status = "okay";
  563. +   };
  564. +
  565. +   /* joycon ports:
  566. +   invert TXD and RTS via IRDA_CSR
  567. +   start @ 1000000 baud, switch to 3000000
  568. +   when they are >= 3000000 baud, use 2 stop bits
  569. +   use flow control
  570. +   Note: hsuart driver is required for flow control
  571. +   */
  572. +   /* right joycon */
  573. +   serial@70006040 {
  574. +       status = "okay";
  575. +       compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";
  576. +       nvidia,invert-txd;
  577. +       nvidia,invert-rts;
  578. +
  579. +       joycon {
  580. +           compatible = "nintendo,joycon-uart";
  581. +           charge-gpios = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_HIGH>;
  582. +       };
  583. +   };
  584. +
  585. +   /* left joycon */
  586. +   serial@70006200 {
  587. +       status = "okay";
  588. +       compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";
  589. +       nvidia,invert-txd;
  590. +       nvidia,invert-rts;
  591. +
  592. +       joycon {
  593. +           compatible = "nintendo,joycon-uart";
  594. +           charge-gpios = <&gpio TEGRA_GPIO(CC, 3) GPIO_ACTIVE_HIGH>;
  595. +       };
  596. +   };
  597. +
  598. +   /* bluetooth */
  599. +   serial@70006300 {
  600. +       status = "okay";
  601. +       // starts @ 115200, switches to 3000000
  602. +       // flow control, 1 stop bit
  603. +       compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";
  604. +
  605. +       bluetooth {
  606. +           compatible = "brcm,bcm43438-bt";
  607. +           shutdown-gpios = <&gpio TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
  608. +           // level correct?
  609. +           device-wakeup-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_LOW>;
  610. +       };
  611. +   };
  612. +
  613. +   pwm@7000a000 {
  614. +       status = "okay";
  615. +       #pwm-cells = <3>;
  616. +   };
  617. +
  618. +   fan: pwm-fan {
  619. +       compatible = "pwm-fan";
  620. +       cooling-min-state = <0>;
  621. +       cooling-max-state = <7>;
  622. +       #cooling-cells = <2>;
  623. +       pwms = <&pwm 1 40000 PWM_POLARITY_INVERTED>;
  624. +       enable-gpios = <&gpio TEGRA_GPIO(A, 5) GPIO_ACTIVE_HIGH>;
  625. +       cooling-levels = <0 64 80 96 128 160 192 255>;
  626. +   };
  627. +
  628. +   bat: battery {
  629. +       compatible = "simple-battery";
  630. +       precharge-current-microamp = <512000>;
  631. +       charge-term-current-microamp = <256000>;
  632. +   };
  633. +
  634. +   /* i2c1 @ 100000hz
  635. +   18: rohm usb-pd
  636. +   1c: realtek 5639
  637. +   36: maxim fuel gauge
  638. +   4c: ti temperature sensor
  639. +   6b: ti charger
  640. +   */
  641. +   i2c@7000c000 {
  642. +       status = "okay";
  643. +       clock-frequency = <100000>;
  644. +
  645. +       audio-codec@1c {
  646. +           compatible = "realtek,rt5639";
  647. +           reg = <0x1c>;
  648. +           interrupt-parent = <&gpio>;
  649. +           interrupts = <TEGRA_GPIO(V, 6) IRQ_TYPE_LEVEL_HIGH>;
  650. +           realtek,ldo1-en-gpios = <&gpio TEGRA_GPIO(Z, 4) GPIO_ACTIVE_LOW>;
  651. +           status = "okay";
  652. +       };
  653. +
  654. +       temperature-sensor@4c {
  655. +           compatible = "ti,tmp451";
  656. +           reg = <0x4c>;
  657. +       };
  658. +
  659. +       bq24190: charger@6b {
  660. +           compatible = "ti,bq24190";
  661. +           reg = <0x6b>;
  662. +           interrupt-parent = <&gpio>;
  663. +           interrupts = <TEGRA_GPIO(Z, 0) IRQ_TYPE_EDGE_FALLING>;
  664. +           ti,system-minimum-microvolt = <3200000>;
  665. +           monitored-battery = <&bat>;
  666. +           status = "okay";
  667. +           omit-battery-class;
  668. +       };
  669. +
  670. +       battery-charger@36 {
  671. +           compatible = "maxim,max17050";
  672. +           reg = <0x36>;
  673. +           interrupt-parent = <&gpio>;
  674. +           interrupts = <TEGRA_GPIO(Y, 0) IRQ_TYPE_LEVEL_LOW>;
  675. +           maxim,rsns-microohm = <10000>;
  676. +           maxim,over-heat-temp = <600>;
  677. +           maxim,over-volt = <4300>;
  678. +           monitored-battery = <&bat>;
  679. +           power-supplies = <&bq24190>;
  680. +           status = "okay";
  681. +       };
  682. +   };
  683. +
  684. +   /* i2c2 @ 400000hz
  685. +   29: rohm ambient light sensor
  686. +   */
  687. +   i2c@7000c400 {
  688. +       status = "okay";
  689. +       clock-frequency = <400000>;
  690. +
  691. +       light-sensor@29 {
  692. +           compatible = "rohm,bh1730fvc";
  693. +           reg = <0x29>;
  694. +       };
  695. +   };
  696. +
  697. +   /* i2c3 @ 400000hz
  698. +   49: stm touchscreen controller
  699. +   */
  700. +   i2c@7000c500 {
  701. +       status = "okay";
  702. +       clock-frequency = <400000>;
  703. +
  704. +       stmfts: touchscreen@49 {
  705. +           compatible = "st,stmfts";
  706. +           reg = <0x49>;
  707. +           interrupt-parent = <&gpio>;
  708. +           interrupts = <TEGRA_GPIO(X, 1) IRQ_TYPE_LEVEL_LOW>;
  709. +           interrupt-enable-reg = <0x2c 0x48>;
  710. +           avdd-supply = <&avdd_touchscreen>;
  711. +           vdd-supply = <&vdd_touchscreen>;
  712. +           touchscreen-size-x = <1280>;
  713. +           touchscreen-size-y = <720>;
  714. +       };
  715. +   };
  716. +
  717. +   /* i2c5 @ 400000hz
  718. +   1b: max77621_cpu
  719. +   1c: max77621_gpu
  720. +   3c: max77620
  721. +   68: max77620_rtc
  722. +   */
  723. +   i2c@7000d000 {
  724. +       status = "okay";
  725. +       clock-frequency = <400000>;
  726. +
  727. +       max77620: max77620@3c {
  728. +           compatible = "maxim,max77620";
  729. +           reg = <0x3c>;
  730. +           interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
  731. +
  732. +           #interrupt-cells = <2>;
  733. +           interrupt-controller;
  734. +
  735. +           #gpio-cells = <2>;
  736. +           gpio-controller;
  737. +
  738. +           #thermal-sensor-cells = <0>;
  739. +
  740. +
  741. +           pinctrl-names = "default";
  742. +           pinctrl-0 = <&max77620_default>;
  743. +
  744. +           max77620_default: pinmux {
  745. +               gpio2 {
  746. +                   pins = "gpio2";
  747. +                   function = "fps-out";
  748. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
  749. +                   maxim,active-fps-power-up-slot = <0>;
  750. +                   maxim,active-fps-power-down-slot = <7>;
  751. +               };
  752. +
  753. +               gpio3 {
  754. +                   pins = "gpio3";
  755. +                   function = "fps-out";
  756. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
  757. +                   maxim,active-fps-power-up-slot = <4>;
  758. +                   maxim,active-fps-power-down-slot = <2>;
  759. +               };
  760. +
  761. +               pin_32k {
  762. +                   pins = "gpio4";
  763. +                   function = "32k-out1";
  764. +               };
  765. +
  766. +               gpio5_6_7 {
  767. +                   pins = "gpio5", "gpio6", "gpio7";
  768. +                   function = "gpio";
  769. +                   drive-push-pull = <1>;
  770. +               };
  771. +           };
  772. +
  773. +           fps {
  774. +               fps0 {
  775. +                   maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
  776. +                   maxim,suspend-fps-time-period-us = <5120>;
  777. +               };
  778. +
  779. +               fps1 {
  780. +                   maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
  781. +                   maxim,suspend-fps-time-period-us = <5120>;
  782. +               };
  783. +
  784. +               fps2 {
  785. +                   maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
  786. +                   maxim,suspend-fps-time-period-us = <5120>;
  787. +               };
  788. +           };
  789. +
  790. +           regulators {
  791. +               in-ldo0-1-supply = <&vdd_pre>;
  792. +               in-ldo7-8-supply = <&vdd_pre>;
  793. +
  794. +               vdd_soc: sd0 {
  795. +                   regulator-name = "VDD_SOC";
  796. +                   regulator-min-microvolt = <825000>;
  797. +                   regulator-max-microvolt = <1125000>;
  798. +                   regulator-always-on;
  799. +                   regulator-boot-on;
  800. +
  801. +                   regulator-enable-ramp-delay = <146>;
  802. +                   regulator-disable-ramp-delay = <4080>;
  803. +                   regulator-ramp-delay = <27500>;
  804. +
  805. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
  806. +                   maxim,active-fps-power-up-slot = <1>;
  807. +                   maxim,active-fps-power-down-slot = <7>;
  808. +               };
  809. +
  810. +               vdd_ddr: sd1 {
  811. +                   regulator-name = "VDD_DDR_1V1_PMIC";
  812. +                   regulator-min-microvolt = <1125000>;
  813. +                   regulator-max-microvolt = <1125000>;
  814. +                   regulator-always-on;
  815. +                   regulator-boot-on;
  816. +
  817. +                   regulator-enable-ramp-delay = <130>;
  818. +                   regulator-disable-ramp-delay = <145800>;
  819. +                   regulator-ramp-delay = <27500>;
  820. +
  821. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
  822. +                   maxim,active-fps-power-up-slot = <5>;
  823. +                   maxim,active-fps-power-down-slot = <1>;
  824. +               };
  825. +
  826. +               vdd_pre: sd2 {
  827. +                   regulator-name = "VDD_PRE_REG_1V35";
  828. +                   regulator-min-microvolt = <1325000>;
  829. +                   regulator-max-microvolt = <1350000>;
  830. +                   regulator-always-on;
  831. +                   regulator-boot-on;
  832. +
  833. +                   regulator-enable-ramp-delay = <176>;
  834. +                   regulator-disable-ramp-delay = <32000>;
  835. +                   regulator-ramp-delay = <27500>;
  836. +
  837. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
  838. +                   maxim,active-fps-power-up-slot = <2>;
  839. +                   maxim,active-fps-power-down-slot = <5>;
  840. +               };
  841. +
  842. +               vdd_1v8: sd3 {
  843. +                   regulator-name = "VDD_1V8";
  844. +                   regulator-min-microvolt = <1800000>;
  845. +                   regulator-max-microvolt = <1800000>;
  846. +                   regulator-always-on;
  847. +                   regulator-boot-on;
  848. +
  849. +                   regulator-enable-ramp-delay = <242>;
  850. +                   regulator-disable-ramp-delay = <118000>;
  851. +                   regulator-ramp-delay = <27500>;
  852. +
  853. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
  854. +                   maxim,active-fps-power-up-slot = <3>;
  855. +                   maxim,active-fps-power-down-slot = <3>;
  856. +               };
  857. +
  858. +               vdd_sys_1v2: ldo0 {
  859. +                   regulator-name = "AVDD_SYS_1V2";
  860. +                   regulator-min-microvolt = <1200000>;
  861. +                   regulator-max-microvolt = <1200000>;
  862. +                   regulator-always-on;
  863. +                   regulator-boot-on;
  864. +
  865. +                   regulator-enable-ramp-delay = <26>;
  866. +                   regulator-disable-ramp-delay = <626>;
  867. +                   regulator-ramp-delay = <100000>;
  868. +
  869. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
  870. +                   maxim,active-fps-power-up-slot = <0>;
  871. +                   maxim,active-fps-power-down-slot = <7>;
  872. +               };
  873. +
  874. +               vdd_pex_1v05: ldo1 {
  875. +                   regulator-name = "VDD_PEX_1V05";
  876. +                   regulator-min-microvolt = <1050000>;
  877. +                   regulator-max-microvolt = <1050000>;
  878. +                   regulator-always-on;
  879. +                   regulator-boot-on;
  880. +
  881. +                   regulator-enable-ramp-delay = <22>;
  882. +                   regulator-disable-ramp-delay = <630>;
  883. +                   regulator-ramp-delay = <100000>;
  884. +
  885. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
  886. +                   maxim,active-fps-power-up-slot = <0>;
  887. +                   maxim,active-fps-power-down-slot = <7>;
  888. +               };
  889. +
  890. +               vddio_sdmmc: ldo2 {
  891. +                   regulator-name = "VDDIO_SDMMC";
  892. +                   regulator-min-microvolt = <1800000>;
  893. +                   regulator-max-microvolt = <3300000>;
  894. +                   regulator-always-on;
  895. +                   regulator-boot-on;
  896. +
  897. +                   regulator-enable-ramp-delay = <62>;
  898. +                   regulator-disable-ramp-delay = <650>;
  899. +                   regulator-ramp-delay = <100000>;
  900. +
  901. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
  902. +                   maxim,active-fps-power-up-slot = <0>;
  903. +                   maxim,active-fps-power-down-slot = <7>;
  904. +               };
  905. +
  906. +               vdd_unk_ldo3: ldo3 {
  907. +                   regulator-name = "VDD_UNK_LDO3";
  908. +                   regulator-min-microvolt = <3100000>;
  909. +                   regulator-max-microvolt = <3100000>;
  910. +                   regulator-always-on;
  911. +                   regulator-boot-on;
  912. +
  913. +                   regulator-enable-ramp-delay = <50>;
  914. +                   regulator-disable-ramp-delay = <1110>;
  915. +                   regulator-ramp-delay = <100000>;
  916. +
  917. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
  918. +                   maxim,active-fps-power-up-slot = <0>;
  919. +                   maxim,active-fps-power-down-slot = <7>;
  920. +               };
  921. +
  922. +               vdd_rtc: ldo4 {
  923. +                   regulator-name = "VDD_RTC";
  924. +                   regulator-min-microvolt = <850000>;
  925. +                   regulator-max-microvolt = <850000>;
  926. +                   regulator-always-on;
  927. +                   regulator-boot-on;
  928. +
  929. +                   regulator-enable-ramp-delay = <22>;
  930. +                   regulator-disable-ramp-delay = <610>;
  931. +                   regulator-ramp-delay = <100000>;
  932. +
  933. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
  934. +                   maxim,active-fps-power-up-slot = <1>;
  935. +                   maxim,active-fps-power-down-slot = <7>;
  936. +               };
  937. +
  938. +               vdd_unk_ldo5: ldo5 {
  939. +                   regulator-name = "VDD_UNK_LDO5";
  940. +                   regulator-min-microvolt = <1800000>;
  941. +                   regulator-max-microvolt = <1800000>;
  942. +                   regulator-always-on;
  943. +                   regulator-boot-on;
  944. +
  945. +                   regulator-enable-ramp-delay = <62>;
  946. +                   regulator-disable-ramp-delay = <640>;
  947. +                   regulator-ramp-delay = <100000>;
  948. +
  949. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
  950. +                   maxim,active-fps-power-up-slot = <0>;
  951. +                   maxim,active-fps-power-down-slot = <7>;
  952. +               };
  953. +
  954. +               avdd_touchscreen: ldo6 {
  955. +                   regulator-name = "AVDD_TOUCHSCREEN";
  956. +                   regulator-min-microvolt = <2900000>;
  957. +                   regulator-max-microvolt = <2900000>;
  958. +
  959. +                   regulator-enable-ramp-delay = <36>;
  960. +                   regulator-disable-ramp-delay = <674>;
  961. +                   regulator-ramp-delay = <100000>;
  962. +
  963. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
  964. +                   maxim,active-fps-power-up-slot = <0>;
  965. +                   maxim,active-fps-power-down-slot = <7>;
  966. +               };
  967. +
  968. +               avdd_1v05_pll: ldo7 {
  969. +                   regulator-name = "AVDD_1V05_PLL";
  970. +                   regulator-min-microvolt = <1050000>;
  971. +                   regulator-max-microvolt = <1050000>;
  972. +                   regulator-always-on;
  973. +                   regulator-boot-on;
  974. +
  975. +                   regulator-enable-ramp-delay = <24>;
  976. +                   regulator-disable-ramp-delay = <2768>;
  977. +                   regulator-ramp-delay = <100000>;
  978. +
  979. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
  980. +                   maxim,active-fps-power-up-slot = <3>;
  981. +                   maxim,active-fps-power-down-slot = <4>;
  982. +               };
  983. +
  984. +               avdd_1v05: ldo8 {
  985. +                   regulator-name = "AVDD_SATA_HDMI_DP_1V05";
  986. +                   regulator-min-microvolt = <1050000>;
  987. +                   regulator-max-microvolt = <1050000>;
  988. +                   regulator-always-on;
  989. +                   regulator-boot-on;
  990. +
  991. +                   regulator-enable-ramp-delay = <22>;
  992. +                   regulator-disable-ramp-delay = <1160>;
  993. +                   regulator-ramp-delay = <100000>;
  994. +
  995. +                   maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
  996. +                   maxim,active-fps-power-up-slot = <0>;
  997. +                   maxim,active-fps-power-down-slot = <7>;
  998. +               };
  999. +           };
  1000. +       };
  1001. +
  1002. +       max77621_cpu: pmic@1b {
  1003. +           compatible = "maxim,max77621";
  1004. +           reg = <0x1b>;
  1005. +//             interrupt-parent = <&gpio>;
  1006. +//             interrupts = <TEGRA_GPIO(Y, 1) IRQ_TYPE_LEVEL_LOW>;
  1007. +           regulator-name = "PPVAR_CPU";
  1008. +           // smaug: 800000..1231250
  1009. +           regulator-min-microvolt = <800000>;
  1010. +           regulator-max-microvolt = <1231250>;
  1011. +           regulator-ramp-delay = <12000>;
  1012. +           maxim,externally-enable;
  1013. +           maxim,enable-gpio = <&max77620 5 0>;
  1014. +           maxim,dvs-default-state = <1>;
  1015. +           regulator-always-on;
  1016. +           maxim,enable-remote-sense;
  1017. +           maxim,enable-active-discharge;
  1018. +           junction-warn-millicelsius = <120>;
  1019. +
  1020. +           // not supported in mainline yet
  1021. +           //maxim,inductor-value = <MAX8973_INDUCTOR_VAL_PLUS_30_PER>;
  1022. +
  1023. +           #thermal-sensor-cells = <0>;
  1024. +       };
  1025. +
  1026. +       max77621_gpu: pmic@1c {
  1027. +           compatible = "maxim,max77621";
  1028. +           reg = <0x1c>;
  1029. +//             interrupt-parent = <&gpio>;
  1030. +//             interrupts = <TEGRA_GPIO(A, 6) IRQ_TYPE_LEVEL_LOW>;
  1031. +           regulator-name = "PPVAR_GPU";
  1032. +           regulator-min-microvolt = <840000>;
  1033. +           regulator-max-microvolt = <1150000>;
  1034. +           regulator-ramp-delay = <12000>;
  1035. +           maxim,externally-enable;
  1036. +           maxim,enable-gpio = <&max77620 6 0>;
  1037. +           maxim,dvs-default-state = <1>;
  1038. +           maxim,enable-remote-sense;
  1039. +           maxim,enable-active-discharge;
  1040. +           junction-warn-millicelsius = <120>;
  1041. +
  1042. +           // not supported in mainline yet
  1043. +           //maxim,inductor-value = <MAX8973_INDUCTOR_VAL_PLUS_30_PER>;
  1044. +
  1045. +           #thermal-sensor-cells = <0>;
  1046. +       };
  1047. +   };
  1048. +
  1049. +   pmc@7000e400 {
  1050. +       nvidia,invert-interrupt;
  1051. +   };
  1052. +
  1053. +   usb@70090000 {
  1054. +       phys = <&{/padctl@7009f000/pads/usb2/lanes/usb2-0}>,
  1055. +              <&{/padctl@7009f000/pads/pcie/lanes/pcie-6}>;
  1056. +       phy-names = "usb2-0", "usb3-0";
  1057. +
  1058. +       dvddio-pex-supply = <&vdd_pex_1v05>;
  1059. +       hvddio-pex-supply = <&vdd_1v8>;
  1060. +       avdd-usb-supply = <&vdd_3v3_sys>;
  1061. +       avdd-pll-utmip-supply = <&vdd_1v8>;
  1062. +       avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
  1063. +       dvdd-usb-ss-pll-supply = <&vdd_pex_1v05>;
  1064. +       hvdd-usb-ss-pll-e-supply = <&vdd_1v8>;
  1065. +
  1066. +       status = "okay";
  1067. +   };
  1068. +
  1069. +   padctl@7009f000 {
  1070. +       status = "okay";
  1071. +
  1072. +       pads {
  1073. +           usb2 {
  1074. +               status = "okay";
  1075. +
  1076. +               lanes {
  1077. +                   usb2-0 {
  1078. +                       nvidia,function = "xusb";
  1079. +                       status = "okay";
  1080. +                   };
  1081. +               };
  1082. +           };
  1083. +
  1084. +           pcie {
  1085. +               status = "okay";
  1086. +
  1087. +               lanes {
  1088. +                   pcie-0 {
  1089. +                       nvidia,function = "pcie-x1";
  1090. +                       status = "okay";
  1091. +                   };
  1092. +                   pcie-1 {
  1093. +                       nvidia,function = "pcie-x4";
  1094. +                       status = "okay";
  1095. +                   };
  1096. +                   pcie-2 {
  1097. +                       nvidia,function = "pcie-x4";
  1098. +                       status = "okay";
  1099. +                   };
  1100. +                   pcie-3 {
  1101. +                       nvidia,function = "pcie-x4";
  1102. +                       status = "okay";
  1103. +                   };
  1104. +                   pcie-4 {
  1105. +                       nvidia,function = "pcie-x4";
  1106. +                       status = "okay";
  1107. +                   };
  1108. +                   pcie-5 {
  1109. +                       nvidia,function = "usb3-ss";
  1110. +                       status = "okay";
  1111. +                   };
  1112. +                   pcie-6 {
  1113. +                       nvidia,function = "usb3-ss";
  1114. +                       status = "okay";
  1115. +                   };
  1116. +               };
  1117. +           };
  1118. +       };
  1119. +
  1120. +       ports {
  1121. +           usb2-0 {
  1122. +               status = "okay";
  1123. +               vbus-supply = <&usbc_vbus>;
  1124. +               mode = "otg";
  1125. +           };
  1126. +
  1127. +           usb3-0 {
  1128. +               nvidia,usb2-companion = <0>;
  1129. +               vbus-supply = <&usbc_vbus>;
  1130. +               status = "okay";
  1131. +           };
  1132. +       };
  1133. +   };
  1134. +
  1135. +   /* MMC/SD */
  1136. +   sdhci@700b0000 {
  1137. +       status = "okay";
  1138. +       bus-width = <4>;
  1139. +
  1140. +       cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
  1141. +       power-gpios = <&gpio TEGRA_GPIO(E, 4) GPIO_ACTIVE_HIGH>;
  1142. +       vqmmc-supply = <&vddio_sdmmc>;
  1143. +   };
  1144. +
  1145. +   /* eMMC */
  1146. +   sdhci@700b0600 {
  1147. +       status = "okay";
  1148. +       bus-width = <8>;
  1149. +       non-removable;
  1150. +   };
  1151. +
  1152. +   aconnect@702c0000 {
  1153. +       status = "okay";
  1154. +
  1155. +       dma@702e2000 {
  1156. +           status = "okay";
  1157. +       };
  1158. +
  1159. +       agic@702f9000 {
  1160. +           status = "okay";
  1161. +       };
  1162. +   };
  1163. +
  1164. +   clocks {
  1165. +       compatible = "simple-bus";
  1166. +       #address-cells = <1>;
  1167. +       #size-cells = <0>;
  1168. +
  1169. +       clk32k_in: clock@0 {
  1170. +           compatible = "fixed-clock";
  1171. +           reg = <0>;
  1172. +           #clock-cells = <0>;
  1173. +           clock-frequency = <32768>;
  1174. +       };
  1175. +   };
  1176. +
  1177. +   gpio-keys {
  1178. +       compatible = "gpio-keys";
  1179. +       label = "gpio-keys";
  1180. +
  1181. +       volume_down {
  1182. +           label = "Volume Down";
  1183. +           gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>;
  1184. +           linux,code = <KEY_VOLUMEDOWN>;
  1185. +       };
  1186. +
  1187. +       volume_up {
  1188. +           label = "Volume Up";
  1189. +           gpios = <&gpio TEGRA_GPIO(X, 6) GPIO_ACTIVE_LOW>;
  1190. +           linux,code = <KEY_VOLUMEUP>;
  1191. +       };
  1192. +   };
  1193. +
  1194. +   regulators {
  1195. +       compatible = "simple-bus";
  1196. +       #address-cells = <1>;
  1197. +       #size-cells = <0>;
  1198. +
  1199. +       vdd_3v3_sys: regulator@0 {
  1200. +           compatible = "regulator-fixed";
  1201. +           reg = <0>;
  1202. +           regulator-name = "PP3300";
  1203. +           regulator-min-microvolt = <3300000>;
  1204. +           regulator-max-microvolt = <3300000>;
  1205. +           regulator-boot-on;
  1206. +           regulator-always-on;
  1207. +       };
  1208. +
  1209. +       vdd_lcd_1: regulator@1 {
  1210. +           compatible = "regulator-fixed";
  1211. +           reg = <1>;
  1212. +           regulator-name = "vcc_lcd_1";
  1213. +           regulator-min-microvolt = <1800000>;
  1214. +           regulator-max-microvolt = <1800000>;
  1215. +           gpio = <&gpio TEGRA_GPIO(I, 0) GPIO_ACTIVE_HIGH>;
  1216. +           enable-active-high;
  1217. +       };
  1218. +
  1219. +       vdd_lcd_2: regulator@2 {
  1220. +           compatible = "regulator-fixed";
  1221. +           reg = <2>;
  1222. +           regulator-name = "vcc_lcd_2";
  1223. +           regulator-min-microvolt = <1800000>;
  1224. +           regulator-max-microvolt = <1800000>;
  1225. +           gpio = <&gpio TEGRA_GPIO(I, 1) GPIO_ACTIVE_HIGH>;
  1226. +           enable-active-high;
  1227. +       };
  1228. +
  1229. +       vdd_dsi_csi: regulator@3 {
  1230. +           compatible = "regulator-fixed";
  1231. +           reg = <3>;
  1232. +           regulator-name = "AVDD_DSI_CSI_1V2";
  1233. +           gpio = <&max77620 7 0>;
  1234. +           enable-active-high;
  1235. +           regulator-min-microvolt = <1200000>;
  1236. +           regulator-max-microvolt = <1200000>;
  1237. +           vin-supply = <&vdd_sys_1v2>;
  1238. +           regulator-always-on;
  1239. +           regulator-boot-on;
  1240. +       };
  1241. +
  1242. +       usbc_vbus: regulator@4 {
  1243. +           compatible = "regulator-fixed";
  1244. +           reg = <4>;
  1245. +           regulator-name = "USBC_VBUS";
  1246. +           regulator-min-microvolt = <5000000>;
  1247. +           regulator-max-microvolt = <5000000>;
  1248. +       };
  1249. +
  1250. +       vdd_touchscreen: regulator@5 {
  1251. +           compatible = "regulator-fixed";
  1252. +           reg = <5>;
  1253. +           regulator-name = "vdd_touchscreen";
  1254. +           regulator-min-microvolt = <1800000>;
  1255. +           regulator-max-microvolt = <1800000>;
  1256. +           gpio = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_HIGH>;
  1257. +           enable-active-high;
  1258. +       };
  1259. +   };
  1260. +
  1261. +   thermal-zones {
  1262. +       cpu {
  1263. +           polling-delay-passive = <250>;
  1264. +           polling-delay = <500>;
  1265. +           hwmon;
  1266. +
  1267. +           trips {
  1268. +               cpu_alert0: cpu-alert-0 {
  1269. +                   temperature = <40000>;
  1270. +                   hysteresis = <5000>;
  1271. +                   type = "active";
  1272. +               };
  1273. +               cpu_alert1: cpu-alert-1 {
  1274. +                   temperature = <50000>;
  1275. +                   hysteresis = <5000>;
  1276. +                   type = "active";
  1277. +               };
  1278. +               cpu_alert2: cpu-alert-2 {
  1279. +                   temperature = <60000>;
  1280. +                   hysteresis = <5000>;
  1281. +                   type = "active";
  1282. +               };
  1283. +               cpu_alert3: cpu-alert-3 {
  1284. +                   temperature = <70000>;
  1285. +                   hysteresis = <5000>;
  1286. +                   type = "active";
  1287. +               };
  1288. +               cpu_alert4: cpu-alert-4 {
  1289. +                   temperature = <80000>;
  1290. +                   hysteresis = <5000>;
  1291. +                   type = "active";
  1292. +               };
  1293. +           };
  1294. +
  1295. +           cooling-maps {
  1296. +               map1 {
  1297. +                   trip = <&cpu_alert0>;
  1298. +                   cooling-device = <&fan 1 2>;
  1299. +               };
  1300. +               map2 {
  1301. +                   trip = <&cpu_alert1>;
  1302. +                   cooling-device = <&fan 2 3>;
  1303. +               };
  1304. +               map3 {
  1305. +                   trip = <&cpu_alert2>;
  1306. +                   cooling-device = <&fan 3 5>;
  1307. +               };
  1308. +               map4 {
  1309. +                   trip = <&cpu_alert3>;
  1310. +                   cooling-device = <&fan 5 6>;
  1311. +               };
  1312. +               map5 {
  1313. +                   trip = <&cpu_alert4>;
  1314. +                   cooling-device = <&fan 6 THERMAL_NO_LIMIT>;
  1315. +               };
  1316. +           };
  1317. +       };
  1318. +
  1319. +       gpu {
  1320. +           polling-delay-passive = <250>;
  1321. +           polling-delay = <500>;
  1322. +           hwmon;
  1323. +
  1324. +           trips {
  1325. +               gpu_alert0: gpu-alert-0 {
  1326. +                   temperature = <40000>;
  1327. +                   hysteresis = <5000>;
  1328. +                   type = "active";
  1329. +               };
  1330. +               gpu_alert1: gpu-alert-1 {
  1331. +                   temperature = <50000>;
  1332. +                   hysteresis = <5000>;
  1333. +                   type = "active";
  1334. +               };
  1335. +               gpu_alert2: gpu-alert-2 {
  1336. +                   temperature = <60000>;
  1337. +                   hysteresis = <5000>;
  1338. +                   type = "active";
  1339. +               };
  1340. +               gpu_alert3: gpu-alert-3 {
  1341. +                   temperature = <70000>;
  1342. +                   hysteresis = <5000>;
  1343. +                   type = "active";
  1344. +               };
  1345. +               gpu_alert4: gpu-alert-4 {
  1346. +                   temperature = <80000>;
  1347. +                   hysteresis = <5000>;
  1348. +                   type = "active";
  1349. +               };
  1350. +           };
  1351. +
  1352. +           cooling-maps {
  1353. +               map1 {
  1354. +                   trip = <&gpu_alert0>;
  1355. +                   cooling-device = <&fan 1 2>;
  1356. +               };
  1357. +               map2 {
  1358. +                   trip = <&gpu_alert1>;
  1359. +                   cooling-device = <&fan 2 3>;
  1360. +               };
  1361. +               map3 {
  1362. +                   trip = <&gpu_alert2>;
  1363. +                   cooling-device = <&fan 3 5>;
  1364. +               };
  1365. +               map4 {
  1366. +                   trip = <&gpu_alert3>;
  1367. +                   cooling-device = <&fan 5 6>;
  1368. +               };
  1369. +               map5 {
  1370. +                   trip = <&gpu_alert4>;
  1371. +                   cooling-device = <&fan 6 THERMAL_NO_LIMIT>;
  1372. +               };
  1373. +           };
  1374. +       };
  1375. +
  1376. +       mem {
  1377. +           hwmon;
  1378. +       };
  1379. +
  1380. +       pllx {
  1381. +           hwmon;
  1382. +       };
  1383. +
  1384. +       pmic {
  1385. +           polling-delay-passive = <250>;
  1386. +           polling-delay = <500>;
  1387. +           thermal-sensors = <&max77620>;
  1388. +
  1389. +           trips {
  1390. +               pmic_die_warn_temp_thresh: hot-die {
  1391. +                   temperature = <120000>;
  1392. +                   type = "hot";
  1393. +                   hysteresis = <0>;
  1394. +               };
  1395. +
  1396. +               pmic_die_cirt_temp_thresh: critical-die {
  1397. +                   temperature = <140000>;
  1398. +                   type = "critical";
  1399. +                   hysteresis = <0>;
  1400. +               };
  1401. +           };
  1402. +
  1403. +           cooling-maps {
  1404. +               map0 {
  1405. +                   trip = <&pmic_die_warn_temp_thresh>;
  1406. +                   cooling-device = <&throttle_heavy 1 1>;
  1407. +                   contribution = <100>;
  1408. +               };
  1409. +           };
  1410. +       };
  1411. +
  1412. +       cpu_vreg {
  1413. +           polling-delay-passive = <250>;
  1414. +           polling-delay = <500>;
  1415. +           thermal-sensors = <&max77621_cpu>;
  1416. +
  1417. +           trips {
  1418. +               cpu_vreg_die_warn_temp_thresh: hot-die {
  1419. +                   temperature = <120000>;
  1420. +                   type = "hot";
  1421. +                   hysteresis = <0>;
  1422. +               };
  1423. +           };
  1424. +
  1425. +           cooling-maps {
  1426. +               map0 {
  1427. +                   trip = <&cpu_vreg_die_warn_temp_thresh>;
  1428. +                   cooling-device = <&throttle_heavy 1 1>;
  1429. +                   contribution = <100>;
  1430. +               };
  1431. +           };
  1432. +       };
  1433. +
  1434. +       gpu_vreg {
  1435. +           polling-delay-passive = <250>;
  1436. +           polling-delay = <500>;
  1437. +           thermal-sensors = <&max77621_gpu>;
  1438. +
  1439. +           trips {
  1440. +               gpu_vreg_die_warn_temp_thresh: hot-die {
  1441. +                   temperature = <120000>;
  1442. +                   type = "hot";
  1443. +                   hysteresis = <0>;
  1444. +               };
  1445. +           };
  1446. +
  1447. +           cooling-maps {
  1448. +               /*
  1449. +               * There are currently no cooling maps,
  1450. +               * because there are no cooling devices.
  1451. +               */
  1452. +           };
  1453. +       };
  1454. +
  1455. +   };
  1456. +};
  1457. diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
  1458. index 212e663..19720b5 100644
  1459. --- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
  1460. +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
  1461. @@ -284,6 +284,24 @@
  1462.         non-removable;
  1463.     };
  1464.  
  1465. +   clock@70110000 {
  1466. +       status = "okay";
  1467. +       nvidia,pwm-to-pmic;
  1468. +       nvidia,init-uv = <1000000>;
  1469. +       nvidia,align-step-uv = <19200>; /* 19.2mV */
  1470. +       nvidia,align-offset-uv = <708000>; /* 708mV */
  1471. +       nvidia,sample-rate = <25000>;
  1472. +       nvidia,droop-ctrl = <0x00000f00>;
  1473. +       nvidia,force-mode = <1>;
  1474. +       nvidia,cf = <6>;
  1475. +       nvidia,ci = <0>;
  1476. +       nvidia,cg = <2>;
  1477. +       nvidia,pwm-period = <2500>; /* 2.5us */
  1478. +       pinctrl-names = "dvfs_pwm_enable", "dvfs_pwm_disable";
  1479. +       pinctrl-0 = <&dvfs_pwm_active_state>;
  1480. +       pinctrl-1 = <&dvfs_pwm_inactive_state>;
  1481. +   };
  1482. +
  1483.     clocks {
  1484.         compatible = "simple-bus";
  1485.         #address-cells = <1>;
  1486. diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
  1487. index 9d5a0e6..54b5235 100644
  1488. --- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
  1489. +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
  1490. @@ -1278,6 +1278,18 @@
  1491.                 nvidia,open-drain = <TEGRA_PIN_DISABLE>;
  1492.             };
  1493.         };
  1494. +       dvfs_pwm_active_state: dvfs_pwm_active {
  1495. +           dvfs_pwm_pbb1 {
  1496. +               nvidia,pins = "dvfs_pwm_pbb1";
  1497. +               nvidia,tristate = <TEGRA_PIN_DISABLE>;
  1498. +           };
  1499. +       };
  1500. +       dvfs_pwm_inactive_state: dvfs_pwm_inactive {
  1501. +           dvfs_pwm_pbb1 {
  1502. +               nvidia,pins = "dvfs_pwm_pbb1";
  1503. +               nvidia,tristate = <TEGRA_PIN_ENABLE>;
  1504. +           };
  1505. +       };
  1506.     };
  1507.  
  1508.     pwm@7000a000 {
  1509. diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
  1510. index 3be920e..1dc51aa 100644
  1511. --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
  1512. +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
  1513. @@ -3,8 +3,10 @@
  1514.  #include <dt-bindings/gpio/tegra-gpio.h>
  1515.  #include <dt-bindings/memory/tegra210-mc.h>
  1516.  #include <dt-bindings/pinctrl/pinctrl-tegra.h>
  1517. +#include <dt-bindings/reset/tegra210-car.h>
  1518.  #include <dt-bindings/interrupt-controller/arm-gic.h>
  1519.  #include <dt-bindings/thermal/tegra124-soctherm.h>
  1520. +#include <dt-bindings/soc/tegra/pmc.h>
  1521.  
  1522.  / {
  1523.     compatible = "nvidia,tegra210";
  1524. @@ -1027,6 +1029,7 @@
  1525.         clock-names = "sdhci";
  1526.         resets = <&tegra_car 14>;
  1527.         reset-names = "sdhci";
  1528. +       nvidia,pad = <TEGRA_IO_PAD_SDMMC1>;
  1529.         status = "disabled";
  1530.     };
  1531.  
  1532. @@ -1049,6 +1052,7 @@
  1533.         clock-names = "sdhci";
  1534.         resets = <&tegra_car 69>;
  1535.         reset-names = "sdhci";
  1536. +       nvidia,pad = <TEGRA_IO_PAD_SDMMC3>;
  1537.         status = "disabled";
  1538.     };
  1539.  
  1540. @@ -1072,6 +1076,25 @@
  1541.         #nvidia,mipi-calibrate-cells = <1>;
  1542.     };
  1543.  
  1544. +   dfll: clock@70110000 {
  1545. +       compatible = "nvidia,tegra210-dfll";
  1546. +       reg = <0 0x70110000 0 0x100>, /* DFLL control */
  1547. +             <0 0x70110000 0 0x100>, /* I2C output control */
  1548. +             <0 0x70110100 0 0x100>, /* Integrated I2C controller */
  1549. +             <0 0x70110200 0 0x100>; /* Look-up table RAM */
  1550. +       interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
  1551. +       clocks = <&tegra_car TEGRA210_CLK_DFLL_SOC>,
  1552. +            <&tegra_car TEGRA210_CLK_DFLL_REF>,
  1553. +            <&tegra_car TEGRA210_CLK_I2C5>;
  1554. +       clock-names = "soc", "ref", "i2c";
  1555. +       resets = <&tegra_car TEGRA210_RST_DFLL_DVCO>;
  1556. +       reset-names = "dvco";
  1557. +       #clock-cells = <0>;
  1558. +       clock-output-names = "dfllCPU_out";
  1559. +       out-clock-name="dfll_cpu";
  1560. +       status = "disabled";
  1561. +   };
  1562. +
  1563.     aconnect@702c0000 {
  1564.         compatible = "nvidia,tegra210-aconnect";
  1565.         clocks = <&tegra_car TEGRA210_CLK_APE>,
  1566. @@ -1226,6 +1249,13 @@
  1567.             device_type = "cpu";
  1568.             compatible = "arm,cortex-a57";
  1569.             reg = <0>;
  1570. +           clocks = <&tegra_car TEGRA210_CLK_CCLK_G>,
  1571. +                <&tegra_car TEGRA210_CLK_PLL_X>,
  1572. +                <&tegra_car TEGRA210_CLK_PLL_P_OUT_CPU>,
  1573. +                <&dfll>;
  1574. +           clock-names = "cpu_g", "pll_x", "pll_p", "dfll";
  1575. +           /* FIXME: what's the actual transition time? */
  1576. +           clock-latency = <300000>;
  1577.         };
  1578.  
  1579.         cpu@1 {
  1580. diff --git a/arch/arm64/configs/nintendo-switch_defconfig b/arch/arm64/configs/nintendo-switch_defconfig
  1581. new file mode 100644
  1582. index 0000000..653df8c
  1583. --- /dev/null
  1584. +++ b/arch/arm64/configs/nintendo-switch_defconfig
  1585. @@ -0,0 +1,602 @@
  1586. +CONFIG_CROSS_COMPILE="aarch64-linux-gnu-"
  1587. +CONFIG_SYSVIPC=y
  1588. +CONFIG_POSIX_MQUEUE=y
  1589. +CONFIG_NO_HZ=y
  1590. +CONFIG_HIGH_RES_TIMERS=y
  1591. +CONFIG_BSD_PROCESS_ACCT=y
  1592. +CONFIG_BSD_PROCESS_ACCT_V3=y
  1593. +CONFIG_TASKSTATS=y
  1594. +CONFIG_TASK_DELAY_ACCT=y
  1595. +CONFIG_TASK_XACCT=y
  1596. +CONFIG_TASK_IO_ACCOUNTING=y
  1597. +CONFIG_IKCONFIG=y
  1598. +CONFIG_IKCONFIG_PROC=y
  1599. +CONFIG_LOG_BUF_SHIFT=18
  1600. +CONFIG_LOG_CPU_MAX_BUF_SHIFT=14
  1601. +CONFIG_MEMCG=y
  1602. +CONFIG_MEMCG_SWAP=y
  1603. +CONFIG_BLK_CGROUP=y
  1604. +CONFIG_CFS_BANDWIDTH=y
  1605. +CONFIG_CGROUP_PIDS=y
  1606. +CONFIG_CGROUP_FREEZER=y
  1607. +CONFIG_CGROUP_HUGETLB=y
  1608. +CONFIG_CPUSETS=y
  1609. +CONFIG_CGROUP_DEVICE=y
  1610. +CONFIG_CGROUP_CPUACCT=y
  1611. +CONFIG_CGROUP_PERF=y
  1612. +CONFIG_CGROUP_BPF=y
  1613. +CONFIG_USER_NS=y
  1614. +CONFIG_SCHED_AUTOGROUP=y
  1615. +CONFIG_RELAY=y
  1616. +CONFIG_BLK_DEV_INITRD=y
  1617. +CONFIG_BPF_SYSCALL=y
  1618. +CONFIG_USERFAULTFD=y
  1619. +# CONFIG_COMPAT_BRK is not set
  1620. +CONFIG_SLAB=y
  1621. +CONFIG_SLAB_FREELIST_RANDOM=y
  1622. +CONFIG_PROFILING=y
  1623. +CONFIG_JUMP_LABEL=y
  1624. +CONFIG_CC_STACKPROTECTOR_STRONG=y
  1625. +CONFIG_BLK_DEV_BSGLIB=y
  1626. +CONFIG_BLK_DEV_INTEGRITY=y
  1627. +CONFIG_BLK_DEV_THROTTLING=y
  1628. +CONFIG_BLK_WBT=y
  1629. +CONFIG_BLK_WBT_SQ=y
  1630. +CONFIG_PARTITION_ADVANCED=y
  1631. +CONFIG_MAC_PARTITION=y
  1632. +CONFIG_CFQ_GROUP_IOSCHED=y
  1633. +CONFIG_IOSCHED_BFQ=y
  1634. +CONFIG_BFQ_GROUP_IOSCHED=y
  1635. +CONFIG_ARCH_TEGRA=y
  1636. +CONFIG_PCI=y
  1637. +CONFIG_PCIEPORTBUS=y
  1638. +CONFIG_PCI_PASID=y
  1639. +CONFIG_PCI_TEGRA=y
  1640. +# CONFIG_CAVIUM_ERRATUM_22375 is not set
  1641. +# CONFIG_CAVIUM_ERRATUM_23154 is not set
  1642. +# CONFIG_CAVIUM_ERRATUM_27456 is not set
  1643. +# CONFIG_CAVIUM_ERRATUM_30115 is not set
  1644. +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
  1645. +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
  1646. +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
  1647. +# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
  1648. +# CONFIG_HISILICON_ERRATUM_161600802 is not set
  1649. +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
  1650. +CONFIG_ARM64_VA_BITS_48=y
  1651. +CONFIG_SCHED_MC=y
  1652. +CONFIG_SCHED_SMT=y
  1653. +CONFIG_NR_CPUS=16
  1654. +CONFIG_PREEMPT=y
  1655. +CONFIG_HZ_1000=y
  1656. +CONFIG_KSM=y
  1657. +CONFIG_TRANSPARENT_HUGEPAGE=y
  1658. +CONFIG_CLEANCACHE=y
  1659. +CONFIG_FRONTSWAP=y
  1660. +CONFIG_CMA=y
  1661. +CONFIG_ZPOOL=y
  1662. +CONFIG_ZBUD=y
  1663. +CONFIG_Z3FOLD=y
  1664. +CONFIG_ZSMALLOC=y
  1665. +CONFIG_SECCOMP=y
  1666. +CONFIG_KEXEC=y
  1667. +# CONFIG_EFI is not set
  1668. +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  1669. +CONFIG_COMPAT=y
  1670. +CONFIG_PM_DEBUG=y
  1671. +CONFIG_PM_ADVANCED_DEBUG=y
  1672. +CONFIG_CPU_IDLE=y
  1673. +CONFIG_CPU_IDLE_GOV_LADDER=y
  1674. +CONFIG_ARM_CPUIDLE=y
  1675. +CONFIG_CPU_FREQ=y
  1676. +CONFIG_CPU_FREQ_STAT=y
  1677. +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
  1678. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  1679. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  1680. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  1681. +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
  1682. +CONFIG_CPUFREQ_DT=y
  1683. +CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
  1684. +CONFIG_ARM_DT_BL_CPUFREQ=y
  1685. +# CONFIG_ARM_TEGRA20_CPUFREQ is not set
  1686. +CONFIG_NET=y
  1687. +CONFIG_PACKET=y
  1688. +CONFIG_PACKET_DIAG=y
  1689. +CONFIG_UNIX=y
  1690. +CONFIG_UNIX_DIAG=y
  1691. +CONFIG_XFRM_USER=y
  1692. +CONFIG_NET_KEY=y
  1693. +CONFIG_INET=y
  1694. +CONFIG_IP_MULTICAST=y
  1695. +CONFIG_NET_IPIP=y
  1696. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  1697. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  1698. +# CONFIG_INET_XFRM_MODE_BEET is not set
  1699. +# CONFIG_INET_DIAG is not set
  1700. +CONFIG_INET6_AH=y
  1701. +CONFIG_INET6_ESP=y
  1702. +CONFIG_INET6_IPCOMP=y
  1703. +CONFIG_IPV6_MIP6=y
  1704. +CONFIG_IPV6_TUNNEL=y
  1705. +CONFIG_IPV6_MULTIPLE_TABLES=y
  1706. +CONFIG_IPV6_SUBTREES=y
  1707. +CONFIG_IPV6_MROUTE=y
  1708. +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
  1709. +CONFIG_IPV6_PIMSM_V2=y
  1710. +CONFIG_SCTP_COOKIE_HMAC_SHA1=y
  1711. +CONFIG_NETLINK_DIAG=y
  1712. +CONFIG_CGROUP_NET_PRIO=y
  1713. +CONFIG_CGROUP_NET_CLASSID=y
  1714. +CONFIG_BT=y
  1715. +CONFIG_BT_RFCOMM=y
  1716. +CONFIG_BT_RFCOMM_TTY=y
  1717. +CONFIG_BT_BNEP=y
  1718. +CONFIG_BT_BNEP_MC_FILTER=y
  1719. +CONFIG_BT_BNEP_PROTO_FILTER=y
  1720. +CONFIG_BT_HIDP=y
  1721. +CONFIG_BT_HCIUART=y
  1722. +CONFIG_BT_HCIUART_BCSP=y
  1723. +CONFIG_BT_HCIUART_BCM=y
  1724. +CONFIG_BT_HCIBCM203X=y
  1725. +CONFIG_CFG80211=y
  1726. +CONFIG_CFG80211_DEVELOPER_WARNINGS=y
  1727. +CONFIG_CFG80211_WEXT=y
  1728. +CONFIG_MAC80211=y
  1729. +CONFIG_MAC80211_LEDS=y
  1730. +CONFIG_RFKILL=y
  1731. +CONFIG_RFKILL_GPIO=y
  1732. +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
  1733. +CONFIG_DEVTMPFS=y
  1734. +CONFIG_EXTRA_FIRMWARE="nvidia/gm20b/pmu/desc.bin nvidia/gm20b/pmu/sig.bin nvidia/gm20b/pmu/image.bin nvidia/gm20b/acr/bl.bin nvidia/gm20b/acr/ucode_load.bin nvidia/gm20b/gr/sw_method_init.bin nvidia/gm20b/gr/gpccs_inst.bin nvidia/gm20b/gr/fecs_bl.bin nvidia/gm20b/gr/sw_bundle_init.bin nvidia/gm20b/gr/fecs_inst.bin nvidia/gm20b/gr/sw_ctx.bin nvidia/gm20b/gr/fecs_data.bin nvidia/gm20b/gr/gpccs_data.bin nvidia/gm20b/gr/sw_nonctx.bin nvidia/gm20b/gr/fecs_sig.bin nvidia/tegra210/xusb.bin nvidia/tegra210/vic04_ucode.bin brcm/brcmfmac4356-pcie.bin brcm/brcmfmac4356-pcie.txt"
  1735. +CONFIG_TEGRA_ACONNECT=y
  1736. +CONFIG_TEGRA_GMI=y
  1737. +CONFIG_CONNECTOR=y
  1738. +CONFIG_BLK_DEV_LOOP=y
  1739. +CONFIG_BLK_DEV_RAM=y
  1740. +CONFIG_EEPROM_AT24=y
  1741. +CONFIG_EEPROM_LEGACY=y
  1742. +CONFIG_EEPROM_93CX6=y
  1743. +CONFIG_SCSI=y
  1744. +CONFIG_SCSI_MQ_DEFAULT=y
  1745. +CONFIG_BLK_DEV_SD=y
  1746. +CONFIG_CHR_DEV_SG=y
  1747. +# CONFIG_SCSI_LOWLEVEL is not set
  1748. +CONFIG_NETDEVICES=y
  1749. +CONFIG_TUN=y
  1750. +CONFIG_VETH=y
  1751. +# CONFIG_NET_VENDOR_3COM is not set
  1752. +# CONFIG_NET_VENDOR_ADAPTEC is not set
  1753. +# CONFIG_NET_VENDOR_AGERE is not set
  1754. +# CONFIG_NET_VENDOR_ALACRITECH is not set
  1755. +# CONFIG_NET_VENDOR_ALTEON is not set
  1756. +# CONFIG_NET_VENDOR_AMAZON is not set
  1757. +# CONFIG_NET_VENDOR_AMD is not set
  1758. +# CONFIG_NET_VENDOR_AQUANTIA is not set
  1759. +# CONFIG_NET_VENDOR_ARC is not set
  1760. +# CONFIG_NET_VENDOR_ATHEROS is not set
  1761. +# CONFIG_NET_CADENCE is not set
  1762. +# CONFIG_NET_VENDOR_BROADCOM is not set
  1763. +# CONFIG_NET_VENDOR_BROCADE is not set
  1764. +# CONFIG_NET_VENDOR_CAVIUM is not set
  1765. +# CONFIG_NET_VENDOR_CHELSIO is not set
  1766. +# CONFIG_NET_VENDOR_CISCO is not set
  1767. +# CONFIG_NET_VENDOR_CORTINA is not set
  1768. +# CONFIG_NET_VENDOR_DEC is not set
  1769. +# CONFIG_NET_VENDOR_DLINK is not set
  1770. +# CONFIG_NET_VENDOR_EMULEX is not set
  1771. +# CONFIG_NET_VENDOR_EZCHIP is not set
  1772. +# CONFIG_NET_VENDOR_EXAR is not set
  1773. +# CONFIG_NET_VENDOR_HISILICON is not set
  1774. +# CONFIG_NET_VENDOR_HP is not set
  1775. +# CONFIG_NET_VENDOR_HUAWEI is not set
  1776. +# CONFIG_NET_VENDOR_INTEL is not set
  1777. +# CONFIG_NET_VENDOR_MARVELL is not set
  1778. +# CONFIG_NET_VENDOR_MELLANOX is not set
  1779. +# CONFIG_NET_VENDOR_MICREL is not set
  1780. +# CONFIG_NET_VENDOR_MYRI is not set
  1781. +# CONFIG_NET_VENDOR_NATSEMI is not set
  1782. +# CONFIG_NET_VENDOR_NETRONOME is not set
  1783. +# CONFIG_NET_VENDOR_NVIDIA is not set
  1784. +# CONFIG_NET_VENDOR_OKI is not set
  1785. +# CONFIG_NET_PACKET_ENGINE is not set
  1786. +# CONFIG_NET_VENDOR_QLOGIC is not set
  1787. +# CONFIG_NET_VENDOR_QUALCOMM is not set
  1788. +# CONFIG_NET_VENDOR_REALTEK is not set
  1789. +# CONFIG_NET_VENDOR_RENESAS is not set
  1790. +# CONFIG_NET_VENDOR_RDC is not set
  1791. +# CONFIG_NET_VENDOR_ROCKER is not set
  1792. +# CONFIG_NET_VENDOR_SAMSUNG is not set
  1793. +# CONFIG_NET_VENDOR_SEEQ is not set
  1794. +# CONFIG_NET_VENDOR_SILAN is not set
  1795. +# CONFIG_NET_VENDOR_SIS is not set
  1796. +# CONFIG_NET_VENDOR_SOLARFLARE is not set
  1797. +# CONFIG_NET_VENDOR_SMSC is not set
  1798. +# CONFIG_NET_VENDOR_SOCIONEXT is not set
  1799. +# CONFIG_NET_VENDOR_STMICRO is not set
  1800. +# CONFIG_NET_VENDOR_SUN is not set
  1801. +# CONFIG_NET_VENDOR_TEHUTI is not set
  1802. +# CONFIG_NET_VENDOR_TI is not set
  1803. +# CONFIG_NET_VENDOR_VIA is not set
  1804. +# CONFIG_NET_VENDOR_WIZNET is not set
  1805. +# CONFIG_NET_VENDOR_SYNOPSYS is not set
  1806. +CONFIG_PHYLIB=y
  1807. +# CONFIG_USB_NET_DRIVERS is not set
  1808. +# CONFIG_WLAN_VENDOR_ADMTEK is not set
  1809. +# CONFIG_WLAN_VENDOR_ATH is not set
  1810. +# CONFIG_WLAN_VENDOR_ATMEL is not set
  1811. +CONFIG_BRCMFMAC=y
  1812. +# CONFIG_BRCMFMAC_SDIO is not set
  1813. +CONFIG_BRCMFMAC_PCIE=y
  1814. +# CONFIG_WLAN_VENDOR_CISCO is not set
  1815. +# CONFIG_WLAN_VENDOR_INTEL is not set
  1816. +# CONFIG_WLAN_VENDOR_INTERSIL is not set
  1817. +# CONFIG_WLAN_VENDOR_MARVELL is not set
  1818. +# CONFIG_WLAN_VENDOR_MEDIATEK is not set
  1819. +# CONFIG_WLAN_VENDOR_RALINK is not set
  1820. +# CONFIG_WLAN_VENDOR_REALTEK is not set
  1821. +# CONFIG_WLAN_VENDOR_RSI is not set
  1822. +# CONFIG_WLAN_VENDOR_ST is not set
  1823. +# CONFIG_WLAN_VENDOR_TI is not set
  1824. +# CONFIG_WLAN_VENDOR_ZYDAS is not set
  1825. +# CONFIG_WLAN_VENDOR_QUANTENNA is not set
  1826. +CONFIG_INPUT_POLLDEV=y
  1827. +CONFIG_INPUT_SPARSEKMAP=y
  1828. +CONFIG_INPUT_MOUSEDEV=y
  1829. +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280
  1830. +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=720
  1831. +CONFIG_INPUT_JOYDEV=y
  1832. +CONFIG_INPUT_EVDEV=y
  1833. +CONFIG_KEYBOARD_GPIO=y
  1834. +# CONFIG_INPUT_MOUSE is not set
  1835. +CONFIG_INPUT_TOUCHSCREEN=y
  1836. +CONFIG_TOUCHSCREEN_STMFTS=y
  1837. +CONFIG_INPUT_MISC=y
  1838. +CONFIG_INPUT_UINPUT=y
  1839. +# CONFIG_LEGACY_PTYS is not set
  1840. +CONFIG_SERIAL_8250=y
  1841. +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
  1842. +CONFIG_SERIAL_8250_CONSOLE=y
  1843. +# CONFIG_SERIAL_8250_PCI is not set
  1844. +CONFIG_SERIAL_8250_EXTENDED=y
  1845. +CONFIG_SERIAL_8250_SHARE_IRQ=y
  1846. +CONFIG_SERIAL_OF_PLATFORM=y
  1847. +CONFIG_SERIAL_TEGRA=y
  1848. +CONFIG_SERIAL_DEV_BUS=y
  1849. +# CONFIG_HW_RANDOM_CAVIUM is not set
  1850. +# CONFIG_DEVPORT is not set
  1851. +CONFIG_I2C_CHARDEV=y
  1852. +CONFIG_I2C_MUX=y
  1853. +# CONFIG_I2C_HELPER_AUTO is not set
  1854. +CONFIG_I2C_SMBUS=y
  1855. +CONFIG_I2C_TEGRA=y
  1856. +CONFIG_DEBUG_PINCTRL=y
  1857. +CONFIG_PINCTRL_SINGLE=y
  1858. +CONFIG_PINCTRL_MAX77620=y
  1859. +CONFIG_GPIO_SYSFS=y
  1860. +CONFIG_GPIO_MAX77620=y
  1861. +CONFIG_POWER_RESET_GPIO=y
  1862. +CONFIG_POWER_RESET_GPIO_RESTART=y
  1863. +CONFIG_BATTERY_MAX17042=y
  1864. +CONFIG_CHARGER_BQ24190=y
  1865. +CONFIG_SENSORS_LM90=y
  1866. +CONFIG_SENSORS_PWM_FAN=y
  1867. +CONFIG_THERMAL=y
  1868. +CONFIG_THERMAL_WRITABLE_TRIPS=y
  1869. +CONFIG_THERMAL_GOV_USER_SPACE=y
  1870. +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
  1871. +CONFIG_CPU_THERMAL=y
  1872. +CONFIG_CLOCK_THERMAL=y
  1873. +CONFIG_MAX77620_THERMAL=y
  1874. +CONFIG_TEGRA_SOCTHERM=y
  1875. +CONFIG_MFD_MAX77620=y
  1876. +CONFIG_REGULATOR=y
  1877. +CONFIG_REGULATOR_DEBUG=y
  1878. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  1879. +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
  1880. +CONFIG_REGULATOR_USERSPACE_CONSUMER=y
  1881. +CONFIG_REGULATOR_MAX77620=y
  1882. +CONFIG_REGULATOR_MAX8973=y
  1883. +CONFIG_MEDIA_SUPPORT=y
  1884. +CONFIG_MEDIA_CEC_SUPPORT=y
  1885. +CONFIG_CEC_PLATFORM_DRIVERS=y
  1886. +CONFIG_CEC_GPIO=y
  1887. +CONFIG_VIDEO_TEGRA_HDMI_CEC=y
  1888. +# CONFIG_TEGRA_HOST1X_FIREWALL is not set
  1889. +CONFIG_DRM=y
  1890. +CONFIG_DRM_DP_AUX_CHARDEV=y
  1891. +CONFIG_DRM_I2C_NXP_TDA998X=y
  1892. +CONFIG_DRM_NOUVEAU=y
  1893. +CONFIG_DRM_TEGRA=y
  1894. +CONFIG_DRM_TEGRA_DEBUG=y
  1895. +CONFIG_DRM_TEGRA_STAGING=y
  1896. +CONFIG_DRM_PANEL_SIMPLE=y
  1897. +CONFIG_DRM_PANEL_JDI_LPM062M326A=y
  1898. +CONFIG_DRM_TINYDRM=y
  1899. +CONFIG_FB_MODE_HELPERS=y
  1900. +CONFIG_FB_SIMPLE=y
  1901. +CONFIG_LCD_PLATFORM=y
  1902. +# CONFIG_BACKLIGHT_GENERIC is not set
  1903. +CONFIG_BACKLIGHT_PWM=y
  1904. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  1905. +CONFIG_LOGO=y
  1906. +# CONFIG_LOGO_LINUX_MONO is not set
  1907. +# CONFIG_LOGO_LINUX_VGA16 is not set
  1908. +CONFIG_SOUND=y
  1909. +# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
  1910. +CONFIG_SND=y
  1911. +CONFIG_SND_OSSEMUL=y
  1912. +CONFIG_SND_MIXER_OSS=y
  1913. +CONFIG_SND_PCM_OSS=y
  1914. +CONFIG_SND_HRTIMER=y
  1915. +CONFIG_SND_DYNAMIC_MINORS=y
  1916. +CONFIG_SND_VERBOSE_PRINTK=y
  1917. +CONFIG_SND_DEBUG=y
  1918. +CONFIG_SND_SEQUENCER=y
  1919. +CONFIG_SND_SEQ_DUMMY=y
  1920. +CONFIG_SND_SEQUENCER_OSS=y
  1921. +# CONFIG_SND_DRIVERS is not set
  1922. +# CONFIG_SND_PCI is not set
  1923. +CONFIG_SND_HDA_TEGRA=y
  1924. +CONFIG_SND_HDA_HWDEP=y
  1925. +CONFIG_SND_HDA_RECONFIG=y
  1926. +CONFIG_SND_HDA_INPUT_BEEP=y
  1927. +CONFIG_SND_HDA_CODEC_REALTEK=y
  1928. +CONFIG_SND_HDA_CODEC_HDMI=y
  1929. +CONFIG_SND_HDA_PREALLOC_SIZE=2048
  1930. +# CONFIG_SND_USB is not set
  1931. +CONFIG_SND_SOC=y
  1932. +CONFIG_SND_SOC_TEGRA=y
  1933. +CONFIG_SND_SOC_TEGRA20_AC97=y
  1934. +CONFIG_SND_SOC_TEGRA20_I2S=y
  1935. +CONFIG_SND_SOC_TEGRA30_I2S=y
  1936. +CONFIG_SND_SOC_TEGRA_RT5640=y
  1937. +CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
  1938. +CONFIG_SND_SOC_TEGRA_ALC5632=y
  1939. +CONFIG_SND_SOC_TEGRA_RT5677=y
  1940. +CONFIG_SND_SOC_ALC5623=y
  1941. +CONFIG_SND_SOC_RT5616=y
  1942. +CONFIG_SND_SOC_RT5631=y
  1943. +CONFIG_SND_SIMPLE_CARD=y
  1944. +CONFIG_SND_SIMPLE_SCU_CARD=y
  1945. +CONFIG_SND_AUDIO_GRAPH_CARD=y
  1946. +CONFIG_SND_AUDIO_GRAPH_SCU_CARD=y
  1947. +CONFIG_HID_BATTERY_STRENGTH=y
  1948. +CONFIG_HIDRAW=y
  1949. +CONFIG_UHID=y
  1950. +# CONFIG_HID_A4TECH is not set
  1951. +# CONFIG_HID_APPLE is not set
  1952. +# CONFIG_HID_BELKIN is not set
  1953. +# CONFIG_HID_CHERRY is not set
  1954. +# CONFIG_HID_CHICONY is not set
  1955. +# CONFIG_HID_CYPRESS is not set
  1956. +# CONFIG_HID_EZKEY is not set
  1957. +# CONFIG_HID_ITE is not set
  1958. +# CONFIG_HID_KENSINGTON is not set
  1959. +# CONFIG_HID_LOGITECH is not set
  1960. +# CONFIG_HID_MICROSOFT is not set
  1961. +# CONFIG_HID_MONTEREY is not set
  1962. +CONFIG_HID_SONY=y
  1963. +CONFIG_SONY_FF=y
  1964. +CONFIG_HID_WIIMOTE=y
  1965. +CONFIG_USB_HIDDEV=y
  1966. +CONFIG_USB=y
  1967. +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
  1968. +CONFIG_USB_OTG=y
  1969. +CONFIG_USB_OTG_FSM=y
  1970. +CONFIG_USB_MON=y
  1971. +CONFIG_USB_XHCI_HCD=y
  1972. +CONFIG_USB_XHCI_PLATFORM=y
  1973. +CONFIG_USB_XHCI_TEGRA=y
  1974. +CONFIG_USB_EHCI_HCD=y
  1975. +CONFIG_USB_EHCI_TEGRA=y
  1976. +CONFIG_USB_EHCI_HCD_PLATFORM=y
  1977. +CONFIG_USB_STORAGE=y
  1978. +CONFIG_USB_STORAGE_CYPRESS_ATACB=y
  1979. +CONFIG_USB_UAS=y
  1980. +CONFIG_USB_MUSB_HDRC=y
  1981. +CONFIG_USB_SERIAL=y
  1982. +CONFIG_USB_SERIAL_GENERIC=y
  1983. +CONFIG_USB_SERIAL_SIMPLE=y
  1984. +CONFIG_USB_SERIAL_CH341=y
  1985. +CONFIG_USB_SERIAL_CP210X=y
  1986. +CONFIG_USB_SERIAL_FTDI_SIO=y
  1987. +CONFIG_USB_SERIAL_PL2303=y
  1988. +CONFIG_USB_GADGET=y
  1989. +CONFIG_U_SERIAL_CONSOLE=y
  1990. +CONFIG_USB_CONFIGFS=y
  1991. +CONFIG_USB_CONFIGFS_SERIAL=y
  1992. +CONFIG_USB_CONFIGFS_ECM=y
  1993. +CONFIG_USB_CONFIGFS_ECM_SUBSET=y
  1994. +CONFIG_USB_CONFIGFS_EEM=y
  1995. +CONFIG_USB_CONFIGFS_MASS_STORAGE=y
  1996. +CONFIG_TYPEC=y
  1997. +CONFIG_USB_ULPI_BUS=y
  1998. +CONFIG_MMC=y
  1999. +CONFIG_MMC_SDHCI=y
  2000. +CONFIG_MMC_SDHCI_PLTFM=y
  2001. +CONFIG_MMC_SDHCI_TEGRA=y
  2002. +CONFIG_NEW_LEDS=y
  2003. +CONFIG_LEDS_CLASS=y
  2004. +CONFIG_LEDS_TRIGGER_TIMER=y
  2005. +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
  2006. +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
  2007. +CONFIG_LEDS_TRIGGER_TRANSIENT=y
  2008. +CONFIG_RTC_CLASS=y
  2009. +# CONFIG_RTC_NVMEM is not set
  2010. +CONFIG_RTC_DRV_MAX77686=y
  2011. +CONFIG_RTC_DRV_TEGRA=y
  2012. +CONFIG_DMADEVICES=y
  2013. +CONFIG_TEGRA20_APB_DMA=y
  2014. +CONFIG_TEGRA210_ADMA=y
  2015. +CONFIG_UIO=y
  2016. +CONFIG_UIO_PDRV_GENIRQ=y
  2017. +# CONFIG_VIRTIO_MENU is not set
  2018. +CONFIG_STAGING=y
  2019. +# CONFIG_COMMON_CLK_XGENE is not set
  2020. +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
  2021. +CONFIG_TEGRA_IOMMU_SMMU=y
  2022. +CONFIG_ARM_SMMU=y
  2023. +CONFIG_ARM_SMMU_V3=y
  2024. +CONFIG_ARCH_TEGRA_210_SOC=y
  2025. +CONFIG_PM_DEVFREQ=y
  2026. +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
  2027. +CONFIG_DEVFREQ_GOV_PERFORMANCE=y
  2028. +CONFIG_DEVFREQ_GOV_POWERSAVE=y
  2029. +CONFIG_DEVFREQ_GOV_USERSPACE=y
  2030. +CONFIG_DEVFREQ_GOV_PASSIVE=y
  2031. +CONFIG_MEMORY=y
  2032. +CONFIG_IIO=y
  2033. +CONFIG_BH1730=y
  2034. +CONFIG_PWM=y
  2035. +CONFIG_PWM_TEGRA=y
  2036. +CONFIG_PHY_TEGRA_XUSB=y
  2037. +CONFIG_POWERCAP=y
  2038. +CONFIG_EXT4_FS=y
  2039. +CONFIG_EXT4_FS_POSIX_ACL=y
  2040. +CONFIG_EXT4_FS_SECURITY=y
  2041. +CONFIG_EXT4_ENCRYPTION=y
  2042. +CONFIG_FANOTIFY=y
  2043. +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
  2044. +CONFIG_AUTOFS4_FS=y
  2045. +CONFIG_FUSE_FS=y
  2046. +CONFIG_CUSE=y
  2047. +CONFIG_OVERLAY_FS=y
  2048. +CONFIG_OVERLAY_FS_INDEX=y
  2049. +CONFIG_FSCACHE=y
  2050. +CONFIG_CACHEFILES=y
  2051. +CONFIG_ISO9660_FS=y
  2052. +CONFIG_JOLIET=y
  2053. +CONFIG_ZISOFS=y
  2054. +CONFIG_UDF_FS=y
  2055. +CONFIG_MSDOS_FS=y
  2056. +CONFIG_VFAT_FS=y
  2057. +CONFIG_FAT_DEFAULT_CODEPAGE=850
  2058. +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
  2059. +CONFIG_FAT_DEFAULT_UTF8=y
  2060. +CONFIG_NTFS_FS=y
  2061. +CONFIG_TMPFS=y
  2062. +CONFIG_TMPFS_POSIX_ACL=y
  2063. +CONFIG_HUGETLBFS=y
  2064. +CONFIG_SQUASHFS=y
  2065. +CONFIG_SQUASHFS_XATTR=y
  2066. +CONFIG_SQUASHFS_LZ4=y
  2067. +CONFIG_SQUASHFS_LZO=y
  2068. +CONFIG_SQUASHFS_XZ=y
  2069. +CONFIG_SQUASHFS_ZSTD=y
  2070. +CONFIG_NFS_FS=y
  2071. +CONFIG_NFS_V4=y
  2072. +# CONFIG_RPCSEC_GSS_KRB5 is not set
  2073. +CONFIG_CIFS=y
  2074. +CONFIG_CIFS_XATTR=y
  2075. +# CONFIG_CIFS_DEBUG is not set
  2076. +CONFIG_NLS_DEFAULT="iso8859-15"
  2077. +CONFIG_NLS_CODEPAGE_437=y
  2078. +CONFIG_NLS_CODEPAGE_737=y
  2079. +CONFIG_NLS_CODEPAGE_775=y
  2080. +CONFIG_NLS_CODEPAGE_850=y
  2081. +CONFIG_NLS_CODEPAGE_852=y
  2082. +CONFIG_NLS_CODEPAGE_855=y
  2083. +CONFIG_NLS_CODEPAGE_857=y
  2084. +CONFIG_NLS_CODEPAGE_860=y
  2085. +CONFIG_NLS_CODEPAGE_861=y
  2086. +CONFIG_NLS_CODEPAGE_862=y
  2087. +CONFIG_NLS_CODEPAGE_863=y
  2088. +CONFIG_NLS_CODEPAGE_864=y
  2089. +CONFIG_NLS_CODEPAGE_865=y
  2090. +CONFIG_NLS_CODEPAGE_866=y
  2091. +CONFIG_NLS_CODEPAGE_869=y
  2092. +CONFIG_NLS_CODEPAGE_936=y
  2093. +CONFIG_NLS_CODEPAGE_950=y
  2094. +CONFIG_NLS_CODEPAGE_932=y
  2095. +CONFIG_NLS_CODEPAGE_949=y
  2096. +CONFIG_NLS_CODEPAGE_874=y
  2097. +CONFIG_NLS_ISO8859_8=y
  2098. +CONFIG_NLS_CODEPAGE_1250=y
  2099. +CONFIG_NLS_CODEPAGE_1251=y
  2100. +CONFIG_NLS_ASCII=y
  2101. +CONFIG_NLS_ISO8859_1=y
  2102. +CONFIG_NLS_ISO8859_2=y
  2103. +CONFIG_NLS_ISO8859_3=y
  2104. +CONFIG_NLS_ISO8859_4=y
  2105. +CONFIG_NLS_ISO8859_5=y
  2106. +CONFIG_NLS_ISO8859_6=y
  2107. +CONFIG_NLS_ISO8859_7=y
  2108. +CONFIG_NLS_ISO8859_9=y
  2109. +CONFIG_NLS_ISO8859_13=y
  2110. +CONFIG_NLS_ISO8859_14=y
  2111. +CONFIG_NLS_ISO8859_15=y
  2112. +CONFIG_NLS_KOI8_R=y
  2113. +CONFIG_NLS_KOI8_U=y
  2114. +CONFIG_NLS_UTF8=y
  2115. +CONFIG_DLM=y
  2116. +CONFIG_VIRTUALIZATION=y
  2117. +CONFIG_KVM=y
  2118. +CONFIG_VHOST_NET=y
  2119. +CONFIG_PRINTK_TIME=y
  2120. +CONFIG_DYNAMIC_DEBUG=y
  2121. +CONFIG_UNUSED_SYMBOLS=y
  2122. +CONFIG_DEBUG_FS=y
  2123. +CONFIG_MAGIC_SYSRQ=y
  2124. +CONFIG_DEBUG_KERNEL=y
  2125. +CONFIG_PAGE_POISONING=y
  2126. +CONFIG_PAGE_POISONING_NO_SANITY=y
  2127. +CONFIG_PAGE_POISONING_ZERO=y
  2128. +CONFIG_DEBUG_RODATA_TEST=y
  2129. +CONFIG_SOFTLOCKUP_DETECTOR=y
  2130. +CONFIG_PANIC_TIMEOUT=-1
  2131. +# CONFIG_SCHED_DEBUG is not set
  2132. +CONFIG_SCHED_STACK_END_CHECK=y
  2133. +# CONFIG_DEBUG_PREEMPT is not set
  2134. +CONFIG_STACKTRACE=y
  2135. +CONFIG_DEBUG_SG=y
  2136. +CONFIG_DEBUG_NOTIFIERS=y
  2137. +CONFIG_DEBUG_CREDENTIALS=y
  2138. +CONFIG_RCU_CPU_STALL_TIMEOUT=60
  2139. +# CONFIG_FTRACE is not set
  2140. +CONFIG_BUG_ON_DATA_CORRUPTION=y
  2141. +# CONFIG_STRICT_DEVMEM is not set
  2142. +CONFIG_DEBUG_WX=y
  2143. +CONFIG_SECURITY=y
  2144. +CONFIG_HARDENED_USERCOPY=y
  2145. +CONFIG_FORTIFY_SOURCE=y
  2146. +CONFIG_SECURITY_YAMA=y
  2147. +CONFIG_INTEGRITY_SIGNATURE=y
  2148. +CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
  2149. +CONFIG_CRYPTO_PCRYPT=y
  2150. +CONFIG_CRYPTO_MCRYPTD=y
  2151. +CONFIG_CRYPTO_CHACHA20POLY1305=y
  2152. +CONFIG_CRYPTO_LRW=y
  2153. +CONFIG_CRYPTO_PCBC=y
  2154. +CONFIG_CRYPTO_CRC32=y
  2155. +CONFIG_CRYPTO_SHA512=y
  2156. +CONFIG_CRYPTO_AES_TI=y
  2157. +CONFIG_CRYPTO_BLOWFISH=y
  2158. +CONFIG_CRYPTO_CAMELLIA=y
  2159. +CONFIG_CRYPTO_CAST5=y
  2160. +CONFIG_CRYPTO_CAST6=y
  2161. +CONFIG_CRYPTO_SERPENT=y
  2162. +CONFIG_CRYPTO_TEA=y
  2163. +CONFIG_CRYPTO_LZO=y
  2164. +CONFIG_CRYPTO_ANSI_CPRNG=y
  2165. +CONFIG_CRYPTO_DRBG_HASH=y
  2166. +CONFIG_CRYPTO_DRBG_CTR=y
  2167. +CONFIG_CRYPTO_USER_API_HASH=y
  2168. +CONFIG_CRYPTO_USER_API_SKCIPHER=y
  2169. +CONFIG_CRYPTO_USER_API_AEAD=y
  2170. +# CONFIG_CRYPTO_HW is not set
  2171. +CONFIG_ARM64_CRYPTO=y
  2172. +CONFIG_CRYPTO_SHA512_ARM64=y
  2173. +CONFIG_CRYPTO_SHA1_ARM64_CE=y
  2174. +CONFIG_CRYPTO_SHA2_ARM64_CE=y
  2175. +CONFIG_CRYPTO_GHASH_ARM64_CE=y
  2176. +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y
  2177. +CONFIG_CRYPTO_CRC32_ARM64_CE=y
  2178. +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
  2179. +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
  2180. +CONFIG_CRYPTO_CHACHA20_NEON=y
  2181. +CONFIG_CRYPTO_AES_ARM64_BS=y
  2182. +CONFIG_CRC_CCITT=y
  2183. +CONFIG_CRC7=y
  2184. +CONFIG_FONTS=y
  2185. +CONFIG_CRC8=y
  2186. +CONFIG_INPUT_JOYSTICK=y
  2187. +CONFIG_JOYSTICK_JOYCON=y
  2188. diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
  2189. index 6252234..6510c70 100644
  2190. --- a/arch/arm64/kernel/smccc-call.S
  2191. +++ b/arch/arm64/kernel/smccc-call.S
  2192. @@ -17,7 +17,7 @@
  2193.  
  2194.     .macro SMCCC instr
  2195.     .cfi_startproc
  2196. -   \instr  #0
  2197. +   \instr  #1
  2198.     ldr x4, [sp]
  2199.     stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
  2200.     stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
  2201. diff --git a/drivers/clk/tegra/Kconfig b/drivers/clk/tegra/Kconfig
  2202. index 7ddacae..57902ab 100644
  2203. --- a/drivers/clk/tegra/Kconfig
  2204. +++ b/drivers/clk/tegra/Kconfig
  2205. @@ -5,3 +5,8 @@ config TEGRA_CLK_EMC
  2206.  config CLK_TEGRA_BPMP
  2207.     def_bool y
  2208.     depends on TEGRA_BPMP
  2209. +
  2210. +config TEGRA_CLK_DFLL
  2211. +   depends on (ARCH_TEGRA_124_SOC || ARCH_TEGRA_210_SOC)
  2212. +   select PM_OPP
  2213. +   def_bool y
  2214. diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
  2215. index b716923..fc7f4b4 100644
  2216. --- a/drivers/clk/tegra/Makefile
  2217. +++ b/drivers/clk/tegra/Makefile
  2218. @@ -19,7 +19,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clk-tegra20.o
  2219.  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += clk-tegra30.o
  2220.  obj-$(CONFIG_ARCH_TEGRA_114_SOC)   += clk-tegra114.o
  2221.  obj-$(CONFIG_ARCH_TEGRA_124_SOC)   += clk-tegra124.o
  2222. -obj-$(CONFIG_ARCH_TEGRA_124_SOC)   += clk-tegra124-dfll-fcpu.o
  2223. +obj-$(CONFIG_TEGRA_CLK_DFLL)       += clk-tegra124-dfll-fcpu.o
  2224.  obj-$(CONFIG_ARCH_TEGRA_132_SOC)   += clk-tegra124.o
  2225.  obj-y                  += cvb.o
  2226.  obj-$(CONFIG_ARCH_TEGRA_210_SOC)   += clk-tegra210.o
  2227. diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
  2228. index 0a7deee..890829c 100644
  2229. --- a/drivers/clk/tegra/clk-dfll.c
  2230. +++ b/drivers/clk/tegra/clk-dfll.c
  2231. @@ -51,6 +51,7 @@
  2232.  #include <linux/pm_runtime.h>
  2233.  #include <linux/regmap.h>
  2234.  #include <linux/regulator/consumer.h>
  2235. +#include <linux/pinctrl/consumer.h>
  2236.  #include <linux/reset.h>
  2237.  #include <linux/seq_file.h>
  2238.  
  2239. @@ -243,6 +244,12 @@ enum dfll_tune_range {
  2240.     DFLL_TUNE_LOW = 1,
  2241.  };
  2242.  
  2243. +
  2244. +enum tegra_dfll_pmu_if {
  2245. +   TEGRA_DFLL_PMU_I2C = 0,
  2246. +   TEGRA_DFLL_PMU_PWM = 1,
  2247. +};
  2248. +
  2249.  /**
  2250.   * struct dfll_rate_req - target DFLL rate request data
  2251.   * @rate: target frequency, after the postscaling
  2252. @@ -294,16 +301,25 @@ struct tegra_dfll {
  2253.     u32             ci;
  2254.     u32             cg;
  2255.     bool                cg_scale;
  2256. +   u32             reg_init_uV;
  2257.  
  2258.     /* I2C interface parameters */
  2259.     u32             i2c_fs_rate;
  2260.     u32             i2c_reg;
  2261.     u32             i2c_slave_addr;
  2262.  
  2263. -   /* i2c_lut array entries are regulator framework selectors */
  2264. -   unsigned            i2c_lut[MAX_DFLL_VOLTAGES];
  2265. -   int             i2c_lut_size;
  2266. -   u8              lut_min, lut_max, lut_safe;
  2267. +   /* lut array entries are regulator framework selectors or PWM values*/
  2268. +   unsigned int            i2c_lut[MAX_DFLL_VOLTAGES];
  2269. +   unsigned int            lut_uv[MAX_DFLL_VOLTAGES];
  2270. +   int             lut_size;
  2271. +   u8              lut_bottom, lut_min, lut_max, lut_safe;
  2272. +
  2273. +   /* PWM interface */
  2274. +   enum tegra_dfll_pmu_if      pmu_if;
  2275. +   unsigned long           pwm_rate;
  2276. +   struct pinctrl          *pwm_pin;
  2277. +   struct pinctrl_state        *pwm_enable_state;
  2278. +   struct pinctrl_state        *pwm_disable_state;
  2279.  };
  2280.  
  2281.  #define clk_hw_to_dfll(_hw) container_of(_hw, struct tegra_dfll, dfll_clk_hw)
  2282. @@ -489,6 +505,36 @@ static void dfll_set_mode(struct tegra_dfll *td,
  2283.     dfll_wmb(td);
  2284.  }
  2285.  
  2286. +/*
  2287. + * DVCO rate control
  2288. + */
  2289. +
  2290. +static unsigned long get_dvco_rate_below(struct tegra_dfll *td, u8 out_min)
  2291. +{
  2292. +   struct dev_pm_opp *opp;
  2293. +   unsigned long rate, prev_rate;
  2294. +   int uv, min_uv;
  2295. +
  2296. +   min_uv = td->lut_uv[out_min];
  2297. +   for (rate = 0, prev_rate = 0; ; rate++) {
  2298. +       rcu_read_lock();
  2299. +       opp = dev_pm_opp_find_freq_ceil(td->soc->dev, &rate);
  2300. +       if (IS_ERR(opp)) {
  2301. +           rcu_read_unlock();
  2302. +           break;
  2303. +       }
  2304. +       uv = dev_pm_opp_get_voltage(opp);
  2305. +       rcu_read_unlock();
  2306. +
  2307. +       if (uv && uv > min_uv)
  2308. +           return prev_rate;
  2309. +
  2310. +       prev_rate = rate;
  2311. +   }
  2312. +
  2313. +   return prev_rate;
  2314. +}
  2315. +
  2316.  /*
  2317.   * DFLL-to-I2C controller interface
  2318.   */
  2319. @@ -518,6 +564,119 @@ static int dfll_i2c_set_output_enabled(struct tegra_dfll *td, bool enable)
  2320.     return 0;
  2321.  }
  2322.  
  2323. +
  2324. +/*
  2325. + * DFLL-to-PWM controller interface
  2326. + */
  2327. +
  2328. +/**
  2329. + * dfll_pwm_set_output_enabled - enable/disable PWM voltage requests
  2330. + * @td: DFLL instance
  2331. + * @enable: whether to enable or disable the PWM voltage requests
  2332. + *
  2333. + * Set the master enable control for PWM control value updates. If disabled,
  2334. + * then the PWM signal is not driven. Also configure the PWM output pad
  2335. + * to the appropriate state.
  2336. + */
  2337. +static int dfll_pwm_set_output_enabled(struct tegra_dfll *td, bool enable)
  2338. +{
  2339. +   int ret;
  2340. +   u32 val, div;
  2341. +
  2342. +   if (enable) {
  2343. +       ret = pinctrl_select_state(td->pwm_pin, td->pwm_enable_state);
  2344. +       if (ret < 0) {
  2345. +           dev_err(td->dev, "setting enable state failed\n");
  2346. +           return ret;
  2347. +       }
  2348. +       val = dfll_readl(td, DFLL_OUTPUT_CFG);
  2349. +       val &= ~DFLL_OUTPUT_CFG_PWM_DIV_MASK;
  2350. +       div = DIV_ROUND_UP(td->ref_rate, td->pwm_rate);
  2351. +       val |= (div << DFLL_OUTPUT_CFG_PWM_DIV_SHIFT)
  2352. +               & DFLL_OUTPUT_CFG_PWM_DIV_MASK;
  2353. +       dfll_writel(td, val, DFLL_OUTPUT_CFG);
  2354. +       dfll_wmb(td);
  2355. +
  2356. +       val |= DFLL_OUTPUT_CFG_PWM_ENABLE;
  2357. +       dfll_writel(td, val, DFLL_OUTPUT_CFG);
  2358. +       dfll_wmb(td);
  2359. +   } else {
  2360. +       ret = pinctrl_select_state(td->pwm_pin, td->pwm_disable_state);
  2361. +       if (ret < 0)
  2362. +           dev_warn(td->dev, "setting disable state failed\n");
  2363. +
  2364. +       val = dfll_readl(td, DFLL_OUTPUT_CFG);
  2365. +       val &= ~DFLL_OUTPUT_CFG_PWM_ENABLE;
  2366. +       dfll_writel(td, val, DFLL_OUTPUT_CFG);
  2367. +       dfll_wmb(td);
  2368. +   }
  2369. +
  2370. +   return 0;
  2371. +}
  2372. +/**
  2373. + * dfll_set_force_output_value - set fixed value for force output
  2374. + * @td: DFLL instance
  2375. + * @out_val: value to force output
  2376. + *
  2377. + * Set the fixed value for force output, DFLL will output this value when
  2378. + * force output is enabled.
  2379. + */
  2380. +static u32 dfll_set_force_output_value(struct tegra_dfll *td, u8 out_val)
  2381. +{
  2382. +   u32 val = dfll_readl(td, DFLL_OUTPUT_FORCE);
  2383. +
  2384. +   val &= ~OUT_MASK;
  2385. +   val = (val & DFLL_OUTPUT_FORCE_ENABLE) | (out_val & OUT_MASK);
  2386. +   dfll_writel(td, val, DFLL_OUTPUT_FORCE);
  2387. +   dfll_wmb(td);
  2388. +
  2389. +   return dfll_readl(td, DFLL_OUTPUT_FORCE);
  2390. +}
  2391. +
  2392. +/**
  2393. + * dfll_set_force_output_enabled - enable/disable force output
  2394. + * @td: DFLL instance
  2395. + * @enable: whether to enable or disable the force output
  2396. + *
  2397. + * Set the enable control for fouce output with fixed value.
  2398. + */
  2399. +static void dfll_set_force_output_enabled(struct tegra_dfll *td, bool enable)
  2400. +{
  2401. +   u32 val = dfll_readl(td, DFLL_OUTPUT_FORCE);
  2402. +
  2403. +   if (enable)
  2404. +       val |= DFLL_OUTPUT_FORCE_ENABLE;
  2405. +   else
  2406. +       val &= ~DFLL_OUTPUT_FORCE_ENABLE;
  2407. +
  2408. +   dfll_writel(td, val, DFLL_OUTPUT_FORCE);
  2409. +   dfll_wmb(td);
  2410. +}
  2411. +
  2412. +/**
  2413. + * dfll_i2c_set_output_enabled - enable/disable I2C PMIC voltage requests
  2414. + * @td: DFLL instance
  2415. + * @enable: whether to enable or disable the I2C voltage requests
  2416. + *
  2417. + * Set the master enable control for I2C control value updates. If disabled,
  2418. + * then I2C control messages are inhibited, regardless of the DFLL mode.
  2419. + */
  2420. +static int dfll_force_output(struct tegra_dfll *td, unsigned int out_sel)
  2421. +{
  2422. +   u32 val;
  2423. +
  2424. +   if (out_sel > OUT_MASK)
  2425. +       return -EINVAL;
  2426. +
  2427. +   val = dfll_set_force_output_value(td, out_sel);
  2428. +   if ((td->mode < DFLL_CLOSED_LOOP) &&
  2429. +       !(val & DFLL_OUTPUT_FORCE_ENABLE)) {
  2430. +       dfll_set_force_output_enabled(td, true);
  2431. +   }
  2432. +
  2433. +   return 0;
  2434. +}
  2435. +
  2436.  /**
  2437.   * dfll_load_lut - load the voltage lookup table
  2438.   * @td: struct tegra_dfll *
  2439. @@ -531,10 +690,10 @@ static void dfll_load_i2c_lut(struct tegra_dfll *td)
  2440.     u32 val;
  2441.  
  2442.     for (i = 0; i < MAX_DFLL_VOLTAGES; i++) {
  2443. -       if (i < td->lut_min)
  2444. -           lut_index = td->lut_min;
  2445. -       else if (i > td->lut_max)
  2446. -           lut_index = td->lut_max;
  2447. +       if (i < td->lut_bottom)
  2448. +           lut_index = td->lut_bottom;
  2449. +       else if (i > td->lut_size - 1)
  2450. +           lut_index = td->lut_size - 1;
  2451.         else
  2452.             lut_index = i;
  2453.  
  2454. @@ -594,24 +753,54 @@ static void dfll_init_out_if(struct tegra_dfll *td)
  2455.  {
  2456.     u32 val;
  2457.  
  2458. -   td->lut_min = 0;
  2459. -   td->lut_max = td->i2c_lut_size - 1;
  2460. -   td->lut_safe = td->lut_min + 1;
  2461. -
  2462. -   dfll_i2c_writel(td, 0, DFLL_OUTPUT_CFG);
  2463. -   val = (td->lut_safe << DFLL_OUTPUT_CFG_SAFE_SHIFT) |
  2464. -       (td->lut_max << DFLL_OUTPUT_CFG_MAX_SHIFT) |
  2465. -       (td->lut_min << DFLL_OUTPUT_CFG_MIN_SHIFT);
  2466. -   dfll_i2c_writel(td, val, DFLL_OUTPUT_CFG);
  2467. -   dfll_i2c_wmb(td);
  2468. -
  2469. -   dfll_writel(td, 0, DFLL_OUTPUT_FORCE);
  2470. -   dfll_i2c_writel(td, 0, DFLL_INTR_EN);
  2471. -   dfll_i2c_writel(td, DFLL_INTR_MAX_MASK | DFLL_INTR_MIN_MASK,
  2472. -           DFLL_INTR_STS);
  2473. -
  2474. -   dfll_load_i2c_lut(td);
  2475. -   dfll_init_i2c_if(td);
  2476. +   td->lut_min = td->lut_bottom;
  2477. +   td->lut_max = td->lut_size - 1;
  2478. +   td->lut_safe = td->lut_min + (td->lut_min < td->lut_max ? 1 : 0);
  2479. +
  2480. +   if (td->pmu_if == TEGRA_DFLL_PMU_PWM) {
  2481. +       int vinit = td->reg_init_uV;
  2482. +       int vstep = td->soc->alignment.step_uv;
  2483. +       int vmin = td->lut_uv[0];
  2484. +
  2485. +       /* clear DFLL_OUTPUT_CFG before setting new value */
  2486. +       dfll_writel(td, 0, DFLL_OUTPUT_CFG);
  2487. +       dfll_wmb(td);
  2488. +
  2489. +       val = dfll_readl(td, DFLL_OUTPUT_CFG);
  2490. +       val |= (td->lut_safe << DFLL_OUTPUT_CFG_SAFE_SHIFT) |
  2491. +              (td->lut_max << DFLL_OUTPUT_CFG_MAX_SHIFT) |
  2492. +              (td->lut_min << DFLL_OUTPUT_CFG_MIN_SHIFT);
  2493. +       dfll_writel(td, val, DFLL_OUTPUT_CFG);
  2494. +       dfll_wmb(td);
  2495. +
  2496. +       dfll_writel(td, 0, DFLL_OUTPUT_FORCE);
  2497. +       dfll_i2c_writel(td, 0, DFLL_INTR_EN);
  2498. +       dfll_i2c_writel(td, DFLL_INTR_MAX_MASK | DFLL_INTR_MIN_MASK,
  2499. +               DFLL_INTR_STS);
  2500. +
  2501. +       /* set initial voltage */
  2502. +       if ((vinit >= vmin) && vstep) {
  2503. +           unsigned int vsel;
  2504. +
  2505. +           vsel = DIV_ROUND_UP((vinit - vmin), vstep);
  2506. +           dfll_force_output(td, vsel);
  2507. +       }
  2508. +   } else {
  2509. +       dfll_i2c_writel(td, 0, DFLL_OUTPUT_CFG);
  2510. +       val = (td->lut_safe << DFLL_OUTPUT_CFG_SAFE_SHIFT) |
  2511. +           (td->lut_max << DFLL_OUTPUT_CFG_MAX_SHIFT) |
  2512. +           (td->lut_min << DFLL_OUTPUT_CFG_MIN_SHIFT);
  2513. +       dfll_i2c_writel(td, val, DFLL_OUTPUT_CFG);
  2514. +       dfll_i2c_wmb(td);
  2515. +
  2516. +       dfll_writel(td, 0, DFLL_OUTPUT_FORCE);
  2517. +       dfll_i2c_writel(td, 0, DFLL_INTR_EN);
  2518. +       dfll_i2c_writel(td, DFLL_INTR_MAX_MASK | DFLL_INTR_MIN_MASK,
  2519. +               DFLL_INTR_STS);
  2520. +
  2521. +       dfll_load_i2c_lut(td);
  2522. +       dfll_init_i2c_if(td);
  2523. +   }
  2524.  }
  2525.  
  2526.  /*
  2527. @@ -619,11 +808,11 @@ static void dfll_init_out_if(struct tegra_dfll *td)
  2528.   */
  2529.  
  2530.  /**
  2531. - * find_lut_index_for_rate - determine I2C LUT index for given DFLL rate
  2532. + * find_lut_index_for_rate - determine LUT index for given DFLL rate
  2533.   * @td: DFLL instance
  2534.   * @rate: clock rate
  2535.   *
  2536. - * Determines the index of a I2C LUT entry for a voltage that approximately
  2537. + * Determines the index of a LUT entry for a voltage that approximately
  2538.   * produces the given DFLL clock rate. This is used when forcing a value
  2539.   * to the integrator during rate changes. Returns -ENOENT if a suitable
  2540.   * LUT index is not found.
  2541. @@ -637,11 +826,11 @@ static int find_lut_index_for_rate(struct tegra_dfll *td, unsigned long rate)
  2542.     if (IS_ERR(opp))
  2543.         return PTR_ERR(opp);
  2544.  
  2545. -   uv = dev_pm_opp_get_voltage(opp);
  2546. +   uv = dev_pm_opp_get_voltage(opp) / td->soc->alignment.step_uv;
  2547.     dev_pm_opp_put(opp);
  2548.  
  2549. -   for (i = 0; i < td->i2c_lut_size; i++) {
  2550. -       if (regulator_list_voltage(td->vdd_reg, td->i2c_lut[i]) == uv)
  2551. +   for (i = td->lut_bottom; i < td->lut_size; i++) {
  2552. +       if ((td->lut_uv[i] / td->soc->alignment.step_uv) >= uv)
  2553.             return i;
  2554.     }
  2555.  
  2556. @@ -863,9 +1052,14 @@ static int dfll_lock(struct tegra_dfll *td)
  2557.             return -EINVAL;
  2558.         }
  2559.  
  2560. -       dfll_i2c_set_output_enabled(td, true);
  2561. +       if (td->pmu_if == TEGRA_DFLL_PMU_PWM)
  2562. +           dfll_pwm_set_output_enabled(td, true);
  2563. +       else
  2564. +           dfll_i2c_set_output_enabled(td, true);
  2565. +
  2566.         dfll_set_mode(td, DFLL_CLOSED_LOOP);
  2567.         dfll_set_frequency_request(td, req);
  2568. +       dfll_set_force_output_enabled(td, false);
  2569.         return 0;
  2570.  
  2571.     default:
  2572. @@ -889,7 +1083,10 @@ static int dfll_unlock(struct tegra_dfll *td)
  2573.     case DFLL_CLOSED_LOOP:
  2574.         dfll_set_open_loop_config(td);
  2575.         dfll_set_mode(td, DFLL_OPEN_LOOP);
  2576. -       dfll_i2c_set_output_enabled(td, false);
  2577. +       if (td->pmu_if == TEGRA_DFLL_PMU_PWM)
  2578. +           dfll_pwm_set_output_enabled(td, false);
  2579. +       else
  2580. +           dfll_i2c_set_output_enabled(td, false);
  2581.         return 0;
  2582.  
  2583.     case DFLL_OPEN_LOOP:
  2584. @@ -1171,15 +1368,17 @@ static int attr_registers_show(struct seq_file *s, void *data)
  2585.         seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
  2586.                dfll_i2c_readl(td, offs));
  2587.  
  2588. -   seq_puts(s, "\nINTEGRATED I2C CONTROLLER REGISTERS:\n");
  2589. -   offs = DFLL_I2C_CLK_DIVISOR;
  2590. -   seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
  2591. -          __raw_readl(td->i2c_controller_base + offs));
  2592. -
  2593. -   seq_puts(s, "\nLUT:\n");
  2594. -   for (offs = 0; offs <  4 * MAX_DFLL_VOLTAGES; offs += 4)
  2595. +   if (td->pmu_if == TEGRA_DFLL_PMU_I2C) {
  2596. +       seq_puts(s, "\nINTEGRATED I2C CONTROLLER REGISTERS:\n");
  2597. +       offs = DFLL_I2C_CLK_DIVISOR;
  2598.         seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
  2599. -              __raw_readl(td->lut_base + offs));
  2600. +              __raw_readl(td->i2c_controller_base + offs));
  2601. +
  2602. +       seq_puts(s, "\nLUT:\n");
  2603. +       for (offs = 0; offs <  4 * MAX_DFLL_VOLTAGES; offs += 4)
  2604. +           seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
  2605. +                  __raw_readl(td->lut_base + offs));
  2606. +   }
  2607.  
  2608.     return 0;
  2609.  }
  2610. @@ -1288,6 +1487,9 @@ static int dfll_init_clks(struct tegra_dfll *td)
  2611.         return PTR_ERR(td->soc_clk);
  2612.     }
  2613.  
  2614. +   if (td->pmu_if != TEGRA_DFLL_PMU_I2C)
  2615. +       return 0;
  2616. +
  2617.     td->i2c_clk = devm_clk_get(td->dev, "i2c");
  2618.     if (IS_ERR(td->i2c_clk)) {
  2619.         dev_err(td->dev, "missing i2c clock\n");
  2620. @@ -1377,15 +1579,17 @@ di_err1:
  2621.   */
  2622.  static int find_vdd_map_entry_exact(struct tegra_dfll *td, int uV)
  2623.  {
  2624. -   int i, n_voltages, reg_uV;
  2625. +   int i, n_voltages, reg_mult, align_mult;
  2626.  
  2627. +   align_mult = uV / td->soc->alignment.step_uv;
  2628.     n_voltages = regulator_count_voltages(td->vdd_reg);
  2629.     for (i = 0; i < n_voltages; i++) {
  2630. -       reg_uV = regulator_list_voltage(td->vdd_reg, i);
  2631. -       if (reg_uV < 0)
  2632. +       reg_mult = regulator_list_voltage(td->vdd_reg, i) /
  2633. +               td->soc->alignment.step_uv;
  2634. +       if (reg_mult < 0)
  2635.             break;
  2636.  
  2637. -       if (uV == reg_uV)
  2638. +       if (align_mult == reg_mult)
  2639.             return i;
  2640.     }
  2641.  
  2642. @@ -1399,15 +1603,17 @@ static int find_vdd_map_entry_exact(struct tegra_dfll *td, int uV)
  2643.   * */
  2644.  static int find_vdd_map_entry_min(struct tegra_dfll *td, int uV)
  2645.  {
  2646. -   int i, n_voltages, reg_uV;
  2647. +   int i, n_voltages, reg_mult, align_mult;
  2648.  
  2649. +   align_mult = uV / td->soc->alignment.step_uv;
  2650.     n_voltages = regulator_count_voltages(td->vdd_reg);
  2651.     for (i = 0; i < n_voltages; i++) {
  2652. -       reg_uV = regulator_list_voltage(td->vdd_reg, i);
  2653. -       if (reg_uV < 0)
  2654. +       reg_mult = regulator_list_voltage(td->vdd_reg, i) /
  2655. +               td->soc->alignment.step_uv;
  2656. +       if (reg_mult < 0)
  2657.             break;
  2658.  
  2659. -       if (uV <= reg_uV)
  2660. +       if (align_mult <= reg_mult)
  2661.             return i;
  2662.     }
  2663.  
  2664. @@ -1415,6 +1621,52 @@ static int find_vdd_map_entry_min(struct tegra_dfll *td, int uV)
  2665.     return -EINVAL;
  2666.  }
  2667.  
  2668. +/*
  2669. + * Look-up table in h/w is ignored when PWM is used as DFLL interface to PMIC.
  2670. + * In this case closed loop output is controlling duty cycle directly. The s/w
  2671. + * look-up that maps PWM duty cycle to voltage is still built by this function.
  2672. + */
  2673. +static int dfll_build_lut_pwm(struct tegra_dfll *td, int v_max)
  2674. +{
  2675. +   int i, reg_volt;
  2676. +   unsigned long rate;
  2677. +   u8 lut_bottom = MAX_DFLL_VOLTAGES;
  2678. +   int v_min = td->soc->cvb->min_millivolts * 1000;
  2679. +
  2680. +   for (i = 0; i < MAX_DFLL_VOLTAGES; i++) {
  2681. +       reg_volt = td->lut_uv[i];
  2682. +
  2683. +       /* since opp voltage is exact mv */
  2684. +       reg_volt = (reg_volt / 1000) * 1000;
  2685. +       if (reg_volt > v_max)
  2686. +           break;
  2687. +
  2688. +       if ((lut_bottom == MAX_DFLL_VOLTAGES) && (reg_volt >= v_min))
  2689. +           lut_bottom = i;
  2690. +   }
  2691. +
  2692. +   /* determine voltage boundaries */
  2693. +   td->lut_size = i;
  2694. +   if ((lut_bottom == MAX_DFLL_VOLTAGES) ||
  2695. +       (lut_bottom + 1 >= td->lut_size)) {
  2696. +       dev_err(td->dev, "no voltage above DFLL minimum %d mV\n",
  2697. +           td->soc->cvb->min_millivolts);
  2698. +       return -EINVAL;
  2699. +   }
  2700. +   td->lut_bottom = lut_bottom;
  2701. +
  2702. +   /* determine rate boundaries */
  2703. +   rate = get_dvco_rate_below(td, td->lut_bottom);
  2704. +   if (!rate) {
  2705. +       dev_err(td->dev, "no opp below DFLL minimum voltage %d mV\n",
  2706. +           td->soc->cvb->min_millivolts);
  2707. +       return -EINVAL;
  2708. +   }
  2709. +   td->dvco_rate_min = rate;
  2710. +
  2711. +   return 0;
  2712. +}
  2713. +
  2714.  /**
  2715.   * dfll_build_i2c_lut - build the I2C voltage register lookup table
  2716.   * @td: DFLL instance
  2717. @@ -1427,10 +1679,10 @@ static int find_vdd_map_entry_min(struct tegra_dfll *td, int uV)
  2718.   *
  2719.   * On success, fills in td->i2c_lut and returns 0, or -err on failure.
  2720.   */
  2721. -static int dfll_build_i2c_lut(struct tegra_dfll *td)
  2722. +static int dfll_build_i2c_lut(struct tegra_dfll *td, int v_max)
  2723.  {
  2724.     int ret = -EINVAL;
  2725. -   int j, v, v_max, v_opp;
  2726. +   int j, v, v_opp;
  2727.     int selector;
  2728.     unsigned long rate;
  2729.     struct dev_pm_opp *opp;
  2730. @@ -1450,8 +1702,10 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
  2731.     if (lut < 0)
  2732.         goto out;
  2733.     td->i2c_lut[0] = lut;
  2734. +   td->lut_bottom = 0;
  2735.  
  2736.     for (j = 1, rate = 0; ; rate++) {
  2737. +
  2738.         opp = dev_pm_opp_find_freq_ceil(td->soc->dev, &rate);
  2739.         if (IS_ERR(opp))
  2740.             break;
  2741. @@ -1484,18 +1738,47 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
  2742.         if (v >= v_max)
  2743.             break;
  2744.     }
  2745. -   td->i2c_lut_size = j;
  2746. +   td->lut_size = j;
  2747.  
  2748.     if (!td->dvco_rate_min)
  2749.         dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n",
  2750.             td->soc->cvb->min_millivolts);
  2751. -   else
  2752. +   else {
  2753.         ret = 0;
  2754. +       for (j = 0; j < td->lut_size; j++)
  2755. +           td->lut_uv[j] =
  2756. +               regulator_list_voltage(td->vdd_reg,
  2757. +                              td->i2c_lut[j]);
  2758. +   }
  2759.  
  2760.  out:
  2761.     return ret;
  2762.  }
  2763.  
  2764. +static int dfll_build_lut(struct tegra_dfll *td)
  2765. +{
  2766. +   unsigned long rate;
  2767. +   struct dev_pm_opp *opp;
  2768. +   int v_max;
  2769. +
  2770. +   rcu_read_lock();
  2771. +
  2772. +   rate = ULONG_MAX;
  2773. +   opp = dev_pm_opp_find_freq_floor(td->soc->dev, &rate);
  2774. +   if (IS_ERR(opp)) {
  2775. +       dev_err(td->dev, "couldn't get vmax opp, empty opp table?\n");
  2776. +       return -EINVAL;
  2777. +   }
  2778. +   v_max = dev_pm_opp_get_voltage(opp);
  2779. +
  2780. +   rcu_read_unlock();
  2781. +
  2782. +   if (td->pmu_if == TEGRA_DFLL_PMU_PWM)
  2783. +       return dfll_build_lut_pwm(td, v_max);
  2784. +   else
  2785. +       return dfll_build_i2c_lut(td, v_max);
  2786. +}
  2787. +
  2788.  /**
  2789.   * read_dt_param - helper function for reading required parameters from the DT
  2790.   * @td: DFLL instance
  2791. @@ -1554,11 +1837,54 @@ static int dfll_fetch_i2c_params(struct tegra_dfll *td)
  2792.     }
  2793.     td->i2c_reg = vsel_reg;
  2794.  
  2795. -   ret = dfll_build_i2c_lut(td);
  2796. -   if (ret) {
  2797. -       dev_err(td->dev, "couldn't build I2C LUT\n");
  2798. +   return 0;
  2799. +}
  2800. +
  2801. +static int dfll_fetch_pwm_params(struct tegra_dfll *td)
  2802. +{
  2803. +   int ret, i;
  2804. +   u32 pwm_period;
  2805. +
  2806. +   if (!td->soc->alignment.step_uv || !td->soc->alignment.offset_uv) {
  2807. +       dev_err(td->dev, "Missing step or alignment info for PWM regulator");
  2808. +       return -EINVAL;
  2809. +   }
  2810. +   for (i = 0; i < MAX_DFLL_VOLTAGES; i++)
  2811. +       td->lut_uv[i] = td->soc->alignment.offset_uv +
  2812. +               i * td->soc->alignment.step_uv;
  2813. +
  2814. +   ret = read_dt_param(td, "nvidia,init-uv", &td->reg_init_uV);
  2815. +   if (!ret) {
  2816. +       dev_err(td->dev, "couldn't get initialized voltage\n");
  2817. +       return ret;
  2818. +   }
  2819. +
  2820. +   ret = read_dt_param(td, "nvidia,pwm-period", &pwm_period);
  2821. +   if (!ret) {
  2822. +       dev_err(td->dev, "couldn't get PWM period\n");
  2823.         return ret;
  2824.     }
  2825. +   td->pwm_rate = (NSEC_PER_SEC / pwm_period) * (MAX_DFLL_VOLTAGES - 1);
  2826. +
  2827. +   td->pwm_pin = devm_pinctrl_get(td->dev);
  2828. +   if (IS_ERR(td->pwm_pin)) {
  2829. +       dev_err(td->dev, "DT: missing pinctrl device\n");
  2830. +       return PTR_ERR(td->pwm_pin);
  2831. +   }
  2832. +
  2833. +   td->pwm_enable_state = pinctrl_lookup_state(td->pwm_pin,
  2834. +                           "dvfs_pwm_enable");
  2835. +   if (IS_ERR(td->pwm_enable_state)) {
  2836. +       dev_err(td->dev, "DT: missing pwm enabled state\n");
  2837. +       return PTR_ERR(td->pwm_enable_state);
  2838. +   }
  2839. +
  2840. +   td->pwm_disable_state = pinctrl_lookup_state(td->pwm_pin,
  2841. +                            "dvfs_pwm_disable");
  2842. +   if (IS_ERR(td->pwm_disable_state)) {
  2843. +       dev_err(td->dev, "DT: missing pwm disabled state\n");
  2844. +       return PTR_ERR(td->pwm_disable_state);
  2845. +   }
  2846.  
  2847.     return 0;
  2848.  }
  2849. @@ -1625,12 +1951,6 @@ int tegra_dfll_register(struct platform_device *pdev,
  2850.  
  2851.     td->soc = soc;
  2852.  
  2853. -   td->vdd_reg = devm_regulator_get(td->dev, "vdd-cpu");
  2854. -   if (IS_ERR(td->vdd_reg)) {
  2855. -       dev_err(td->dev, "couldn't get vdd_cpu regulator\n");
  2856. -       return PTR_ERR(td->vdd_reg);
  2857. -   }
  2858. -
  2859.     td->dvco_rst = devm_reset_control_get(td->dev, "dvco");
  2860.     if (IS_ERR(td->dvco_rst)) {
  2861.         dev_err(td->dev, "couldn't get dvco reset\n");
  2862. @@ -1643,10 +1963,27 @@ int tegra_dfll_register(struct platform_device *pdev,
  2863.         return ret;
  2864.     }
  2865.  
  2866. -   ret = dfll_fetch_i2c_params(td);
  2867. +   if (of_property_read_bool(td->dev->of_node, "nvidia,pwm-to-pmic")) {
  2868. +       td->pmu_if = TEGRA_DFLL_PMU_PWM;
  2869. +       ret = dfll_fetch_pwm_params(td);
  2870. +   } else  {
  2871. +       td->vdd_reg = devm_regulator_get(td->dev, "vdd-cpu");
  2872. +       if (IS_ERR(td->vdd_reg)) {
  2873. +           dev_err(td->dev, "couldn't get vdd_cpu regulator\n");
  2874. +           return PTR_ERR(td->vdd_reg);
  2875. +       }
  2876. +       td->pmu_if = TEGRA_DFLL_PMU_I2C;
  2877. +       ret = dfll_fetch_i2c_params(td);
  2878. +   }
  2879.     if (ret)
  2880.         return ret;
  2881.  
  2882. +   ret = dfll_build_lut(td);
  2883. +   if (ret) {
  2884. +       dev_err(td->dev, "couldn't build LUT\n");
  2885. +       return ret;
  2886. +   }
  2887. +
  2888.     mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  2889.     if (!mem) {
  2890.         dev_err(td->dev, "no control register resource\n");
  2891. diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h
  2892. index 83352c8..e7cbc5b 100644
  2893. --- a/drivers/clk/tegra/clk-dfll.h
  2894. +++ b/drivers/clk/tegra/clk-dfll.h
  2895. @@ -21,6 +21,7 @@
  2896.  #include <linux/platform_device.h>
  2897.  #include <linux/reset.h>
  2898.  #include <linux/types.h>
  2899. +#include "cvb.h"
  2900.  
  2901.  /**
  2902.   * struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver
  2903. @@ -35,6 +36,7 @@ struct tegra_dfll_soc_data {
  2904.     struct device *dev;
  2905.     unsigned long max_freq;
  2906.     const struct cvb_table *cvb;
  2907. +   struct rail_alignment alignment;
  2908.  
  2909.     void (*init_clock_trimmers)(void);
  2910.     void (*set_clock_trimmers_high)(void);
  2911. diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
  2912. index 269d359..9d413e4 100644
  2913. --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
  2914. +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
  2915. @@ -21,15 +21,24 @@
  2916.  #include <linux/err.h>
  2917.  #include <linux/kernel.h>
  2918.  #include <linux/init.h>
  2919. +#include <linux/of_device.h>
  2920.  #include <linux/platform_device.h>
  2921. +#include <linux/regulator/consumer.h>
  2922.  #include <soc/tegra/fuse.h>
  2923.  
  2924.  #include "clk.h"
  2925.  #include "clk-dfll.h"
  2926.  #include "cvb.h"
  2927.  
  2928. +struct dfll_fcpu_data {
  2929. +   const unsigned long *cpu_max_freq_table;
  2930. +   unsigned int cpu_max_freq_table_size;
  2931. +   const struct cvb_table *cpu_cvb_tables;
  2932. +   unsigned int cpu_cvb_tables_size;
  2933. +};
  2934. +
  2935.  /* Maximum CPU frequency, indexed by CPU speedo id */
  2936. -static const unsigned long cpu_max_freq_table[] = {
  2937. +static const unsigned long tegra124_cpu_max_freq_table[] = {
  2938.     [0] = 2014500000UL,
  2939.     [1] = 2320500000UL,
  2940.     [2] = 2116500000UL,
  2941. @@ -42,9 +51,6 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
  2942.         .process_id = -1,
  2943.         .min_millivolts = 900,
  2944.         .max_millivolts = 1260,
  2945. -       .alignment = {
  2946. -           .step_uv = 10000, /* 10mV */
  2947. -       },
  2948.         .speedo_scale = 100,
  2949.         .voltage_scale = 1000,
  2950.         .entries = {
  2951. @@ -82,16 +88,505 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
  2952.     },
  2953.  };
  2954.  
  2955. +static const unsigned long tegra210_cpu_max_freq_table[] = {
  2956. +   [0] = 1912500000UL,
  2957. +   [1] = 1912500000UL,
  2958. +   [2] = 2218500000UL,
  2959. +   [3] = 1785000000UL,
  2960. +   [4] = 1632000000UL,
  2961. +   [5] = 1912500000UL,
  2962. +   [6] = 2014500000UL,
  2963. +   [7] = 1734000000UL,
  2964. +   [8] = 1683000000UL,
  2965. +   [9] = 1555500000UL,
  2966. +   [10] = 1504500000UL,
  2967. +};
  2968. +
  2969. +#define CPU_CVB_TABLE \
  2970. +   .speedo_scale = 100,    \
  2971. +   .voltage_scale = 1000,  \
  2972. +   .entries = {        \
  2973. +       {204000000UL,   {1007452, -23865, 370} }, \
  2974. +       {306000000UL,   {1052709, -24875, 370} }, \
  2975. +       {408000000UL,   {1099069, -25895, 370} }, \
  2976. +       {510000000UL,   {1146534, -26905, 370} }, \
  2977. +       {612000000UL,   {1195102, -27915, 370} }, \
  2978. +       {714000000UL,   {1244773, -28925, 370} }, \
  2979. +       {816000000UL,   {1295549, -29935, 370} }, \
  2980. +       {918000000UL,   {1347428, -30955, 370} }, \
  2981. +       {1020000000UL,  {1400411, -31965, 370} }, \
  2982. +       {1122000000UL,  {1454497, -32975, 370} }, \
  2983. +       {1224000000UL,  {1509687, -33985, 370} }, \
  2984. +       {1326000000UL,  {1565981, -35005, 370} }, \
  2985. +       {1428000000UL,  {1623379, -36015, 370} }, \
  2986. +       {1530000000UL,  {1681880, -37025, 370} }, \
  2987. +       {1632000000UL,  {1741485, -38035, 370} }, \
  2988. +       {1734000000UL,  {1802194, -39055, 370} }, \
  2989. +       {1836000000UL,  {1864006, -40065, 370} }, \
  2990. +       {1912500000UL,  {1910780, -40815, 370} }, \
  2991. +       {2014500000UL,  {1227000,      0,   0} }, \
  2992. +       {2218500000UL,  {1227000,      0,   0} }, \
  2993. +       {0,     {      0,      0,   0} }, \
  2994. +   }
  2995. +
  2996. +#define CPU_CVB_TABLE_XA \
  2997. +   .speedo_scale = 100,    \
  2998. +   .voltage_scale = 1000,  \
  2999. +   .entries = {        \
  3000. +       {204000000UL,   {1250024, -39785, 565} }, \
  3001. +       {306000000UL,   {1297556, -41145, 565} }, \
  3002. +       {408000000UL,   {1346718, -42505, 565} }, \
  3003. +       {510000000UL,   {1397511, -43855, 565} }, \
  3004. +       {612000000UL,   {1449933, -45215, 565} }, \
  3005. +       {714000000UL,   {1503986, -46575, 565} }, \
  3006. +       {816000000UL,   {1559669, -47935, 565} }, \
  3007. +       {918000000UL,   {1616982, -49295, 565} }, \
  3008. +       {1020000000UL,  {1675926, -50645, 565} }, \
  3009. +       {1122000000UL,  {1736500, -52005, 565} }, \
  3010. +       {1224000000UL,  {1798704, -53365, 565} }, \
  3011. +       {1326000000UL,  {1862538, -54725, 565} }, \
  3012. +       {1428000000UL,  {1928003, -56085, 565} }, \
  3013. +       {1530000000UL,  {1995097, -57435, 565} }, \
  3014. +       {1606500000UL,  {2046149, -58445, 565} }, \
  3015. +       {1632000000UL,  {2063822, -58795, 565} }, \
  3016. +       {0,     {      0,      0,   0} }, \
  3017. +   }
  3018. +
  3019. +#define CPU_CVB_TABLE_EUCM1 \
  3020. +   .speedo_scale = 100,    \
  3021. +   .voltage_scale = 1000,  \
  3022. +   .entries = {        \
  3023. +       {204000000UL,   {734429, 0, 0} }, \
  3024. +       {306000000UL,   {768191, 0, 0} }, \
  3025. +       {408000000UL,   {801953, 0, 0} }, \
  3026. +       {510000000UL,   {835715, 0, 0} }, \
  3027. +       {612000000UL,   {869477, 0, 0} }, \
  3028. +       {714000000UL,   {903239, 0, 0} }, \
  3029. +       {816000000UL,   {937001, 0, 0} }, \
  3030. +       {918000000UL,   {970763, 0, 0} }, \
  3031. +       {1020000000UL,  {1004525, 0, 0} }, \
  3032. +       {1122000000UL,  {1038287, 0, 0} }, \
  3033. +       {1224000000UL,  {1072049, 0, 0} }, \
  3034. +       {1326000000UL,  {1105811, 0, 0} }, \
  3035. +       {1428000000UL,  {1130000, 0, 0} }, \
  3036. +       {1555500000UL,  {1130000, 0, 0} }, \
  3037. +       {1632000000UL,  {1170000, 0, 0} }, \
  3038. +       {1734000000UL,  {1227500, 0, 0} }, \
  3039. +       {0,     {      0, 0, 0} }, \
  3040. +   }
  3041. +
  3042. +#define CPU_CVB_TABLE_EUCM2 \
  3043. +   .speedo_scale = 100,    \
  3044. +   .voltage_scale = 1000,  \
  3045. +   .entries = {        \
  3046. +       {204000000UL,   {742283, 0, 0} }, \
  3047. +       {306000000UL,   {776249, 0, 0} }, \
  3048. +       {408000000UL,   {810215, 0, 0} }, \
  3049. +       {510000000UL,   {844181, 0, 0} }, \
  3050. +       {612000000UL,   {878147, 0, 0} }, \
  3051. +       {714000000UL,   {912113, 0, 0} }, \
  3052. +       {816000000UL,   {946079, 0, 0} }, \
  3053. +       {918000000UL,   {980045, 0, 0} }, \
  3054. +       {1020000000UL,  {1014011, 0, 0} }, \
  3055. +       {1122000000UL,  {1047977, 0, 0} }, \
  3056. +       {1224000000UL,  {1081943, 0, 0} }, \
  3057. +       {1326000000UL,  {1090000, 0, 0} }, \
  3058. +       {1479000000UL,  {1090000, 0, 0} }, \
  3059. +       {1555500000UL,  {1162000, 0, 0} }, \
  3060. +       {1683000000UL,  {1195000, 0, 0} }, \
  3061. +       {0,     {      0, 0, 0} }, \
  3062. +   }
  3063. +
  3064. +#define CPU_CVB_TABLE_EUCM2_JOINT_RAIL \
  3065. +   .speedo_scale = 100,    \
  3066. +   .voltage_scale = 1000,  \
  3067. +   .entries = {        \
  3068. +       {204000000UL,   {742283, 0, 0} }, \
  3069. +       {306000000UL,   {776249, 0, 0} }, \
  3070. +       {408000000UL,   {810215, 0, 0} }, \
  3071. +       {510000000UL,   {844181, 0, 0} }, \
  3072. +       {612000000UL,   {878147, 0, 0} }, \
  3073. +       {714000000UL,   {912113, 0, 0} }, \
  3074. +       {816000000UL,   {946079, 0, 0} }, \
  3075. +       {918000000UL,   {980045, 0, 0} }, \
  3076. +       {1020000000UL,  {1014011, 0, 0} }, \
  3077. +       {1122000000UL,  {1047977, 0, 0} }, \
  3078. +       {1224000000UL,  {1081943, 0, 0} }, \
  3079. +       {1326000000UL,  {1090000, 0, 0} }, \
  3080. +       {1479000000UL,  {1090000, 0, 0} }, \
  3081. +       {1504500000UL,  {1120000, 0, 0} }, \
  3082. +       {0,     {      0, 0, 0} }, \
  3083. +   }
  3084. +
  3085. +#define CPU_CVB_TABLE_ODN \
  3086. +   .speedo_scale = 100,    \
  3087. +   .voltage_scale = 1000,  \
  3088. +   .entries = {        \
  3089. +       {204000000UL,   {721094, 0, 0} }, \
  3090. +       {306000000UL,   {754040, 0, 0} }, \
  3091. +       {408000000UL,   {786986, 0, 0} }, \
  3092. +       {510000000UL,   {819932, 0, 0} }, \
  3093. +       {612000000UL,   {852878, 0, 0} }, \
  3094. +       {714000000UL,   {885824, 0, 0} }, \
  3095. +       {816000000UL,   {918770, 0, 0} }, \
  3096. +       {918000000UL,   {915716, 0, 0} }, \
  3097. +       {1020000000UL,  {984662, 0, 0} }, \
  3098. +       {1122000000UL,  {1017608, 0, 0} }, \
  3099. +       {1224000000UL,  {1050554, 0, 0} }, \
  3100. +       {1326000000UL,  {1083500, 0, 0} }, \
  3101. +       {1428000000UL,  {1116446, 0, 0} }, \
  3102. +       {1581000000UL,  {1130000, 0, 0} }, \
  3103. +       {1683000000UL,  {1168000, 0, 0} }, \
  3104. +       {1785000000UL,  {1227500, 0, 0} }, \
  3105. +       {0,     {      0, 0, 0} }, \
  3106. +   }
  3107. +
  3108. +struct cvb_table tegra210_cpu_cvb_tables[] = {
  3109. +   {
  3110. +       .speedo_id = 10,
  3111. +       .process_id = 0,
  3112. +       .min_millivolts = 840,
  3113. +       .max_millivolts = 1120,
  3114. +       CPU_CVB_TABLE_EUCM2_JOINT_RAIL,
  3115. +       .cpu_dfll_data = {
  3116. +           .tune0_low = 0xffead0ff,
  3117. +           .tune0_high = 0xffead0ff,
  3118. +           .tune1 = 0x20091d9,
  3119. +           .tune_high_min_millivolts = 864,
  3120. +       }
  3121. +   },
  3122. +   {
  3123. +       .speedo_id = 10,
  3124. +       .process_id = 1,
  3125. +       .min_millivolts = 840,
  3126. +       .max_millivolts = 1120,
  3127. +       CPU_CVB_TABLE_EUCM2_JOINT_RAIL,
  3128. +       .cpu_dfll_data = {
  3129. +           .tune0_low = 0xffead0ff,
  3130. +           .tune0_high = 0xffead0ff,
  3131. +           .tune1 = 0x20091d9,
  3132. +           .tune_high_min_millivolts = 864,
  3133. +       }
  3134. +   },
  3135. +   {
  3136. +       .speedo_id = 9,
  3137. +       .process_id = 0,
  3138. +       .min_millivolts = 900,
  3139. +       .max_millivolts = 1162,
  3140. +       CPU_CVB_TABLE_EUCM2,
  3141. +       .cpu_dfll_data = {
  3142. +           .tune0_low = 0xffead0ff,
  3143. +           .tune0_high = 0xffead0ff,
  3144. +           .tune1 = 0x20091d9,
  3145. +       }
  3146. +   },
  3147. +   {
  3148. +       .speedo_id = 9,
  3149. +       .process_id = 1,
  3150. +       .min_millivolts = 900,
  3151. +       .max_millivolts = 1162,
  3152. +       CPU_CVB_TABLE_EUCM2,
  3153. +       .cpu_dfll_data = {
  3154. +           .tune0_low = 0xffead0ff,
  3155. +           .tune0_high = 0xffead0ff,
  3156. +           .tune1 = 0x20091d9,
  3157. +       }
  3158. +   },
  3159. +   {
  3160. +       .speedo_id = 8,
  3161. +       .process_id = 0,
  3162. +       .min_millivolts = 900,
  3163. +       .max_millivolts = 1195,
  3164. +       CPU_CVB_TABLE_EUCM2,
  3165. +       .cpu_dfll_data = {
  3166. +           .tune0_low = 0xffead0ff,
  3167. +           .tune0_high = 0xffead0ff,
  3168. +           .tune1 = 0x20091d9,
  3169. +       }
  3170. +   },
  3171. +   {
  3172. +       .speedo_id = 8,
  3173. +       .process_id = 1,
  3174. +       .min_millivolts = 900,
  3175. +       .max_millivolts = 1195,
  3176. +       CPU_CVB_TABLE_EUCM2,
  3177. +       .cpu_dfll_data = {
  3178. +           .tune0_low = 0xffead0ff,
  3179. +           .tune0_high = 0xffead0ff,
  3180. +           .tune1 = 0x20091d9,
  3181. +       }
  3182. +   },
  3183. +   {
  3184. +       .speedo_id = 7,
  3185. +       .process_id = 0,
  3186. +       .min_millivolts = 841,
  3187. +       .max_millivolts = 1227,
  3188. +       CPU_CVB_TABLE_EUCM1,
  3189. +       .cpu_dfll_data = {
  3190. +           .tune0_low = 0xffead0ff,
  3191. +           .tune0_high = 0xffead0ff,
  3192. +           .tune1 = 0x20091d9,
  3193. +           .tune_high_min_millivolts = 864,
  3194. +       }
  3195. +   },
  3196. +   {
  3197. +       .speedo_id = 7,
  3198. +       .process_id = 1,
  3199. +       .min_millivolts = 841,
  3200. +       .max_millivolts = 1227,
  3201. +       CPU_CVB_TABLE_EUCM1,
  3202. +       .cpu_dfll_data = {
  3203. +           .tune0_low = 0xffead0ff,
  3204. +           .tune0_high = 0xffead0ff,
  3205. +           .tune1 = 0x20091d9,
  3206. +           .tune_high_min_millivolts = 864,
  3207. +       }
  3208. +   },
  3209. +   {
  3210. +       .speedo_id = 6,
  3211. +       .process_id = 0,
  3212. +       .min_millivolts = 870,
  3213. +       .max_millivolts = 1150,
  3214. +       CPU_CVB_TABLE,
  3215. +       .cpu_dfll_data = {
  3216. +           .tune0_low = 0xffead0ff,
  3217. +           .tune1 = 0x20091d9,
  3218. +       }
  3219. +   },
  3220. +   {
  3221. +       .speedo_id = 6,
  3222. +       .process_id = 1,
  3223. +       .min_millivolts = 870,
  3224. +       .max_millivolts = 1150,
  3225. +       CPU_CVB_TABLE,
  3226. +       .cpu_dfll_data = {
  3227. +           .tune0_low = 0xffead0ff,
  3228. +           .tune1 = 0x25501d0,
  3229. +       }
  3230. +   },
  3231. +   {
  3232. +       .speedo_id = 5,
  3233. +       .process_id = 0,
  3234. +       .min_millivolts = 818,
  3235. +       .max_millivolts = 1227,
  3236. +       CPU_CVB_TABLE,
  3237. +       .cpu_dfll_data = {
  3238. +           .tune0_low = 0xffead0ff,
  3239. +           .tune0_high = 0xffead0ff,
  3240. +           .tune1 = 0x20091d9,
  3241. +           .tune_high_min_millivolts = 864,
  3242. +       }
  3243. +   },
  3244. +   {
  3245. +       .speedo_id = 5,
  3246. +       .process_id = 1,
  3247. +       .min_millivolts = 818,
  3248. +       .max_millivolts = 1227,
  3249. +       CPU_CVB_TABLE,
  3250. +       .cpu_dfll_data = {
  3251. +           .tune0_low = 0xffead0ff,
  3252. +           .tune0_high = 0xffead0ff,
  3253. +           .tune1 = 0x25501d0,
  3254. +           .tune_high_min_millivolts = 864,
  3255. +       }
  3256. +   },
  3257. +   {
  3258. +       .speedo_id = 4,
  3259. +       .process_id = -1,
  3260. +       .min_millivolts = 918,
  3261. +       .max_millivolts = 1113,
  3262. +       CPU_CVB_TABLE_XA,
  3263. +       .cpu_dfll_data = {
  3264. +           .tune0_low = 0xffead0ff,
  3265. +           .tune1 = 0x17711BD,
  3266. +       }
  3267. +   },
  3268. +   {
  3269. +       .speedo_id = 3,
  3270. +       .process_id = 0,
  3271. +       .min_millivolts = 825,
  3272. +       .max_millivolts = 1227,
  3273. +       CPU_CVB_TABLE_ODN,
  3274. +       .cpu_dfll_data = {
  3275. +           .tune0_low = 0xffead0ff,
  3276. +           .tune0_high = 0xffead0ff,
  3277. +           .tune1 = 0x20091d9,
  3278. +           .tune_high_min_millivolts = 864,
  3279. +       }
  3280. +   },
  3281. +   {
  3282. +       .speedo_id = 3,
  3283. +       .process_id = 1,
  3284. +       .min_millivolts = 825,
  3285. +       .max_millivolts = 1227,
  3286. +       CPU_CVB_TABLE_ODN,
  3287. +       .cpu_dfll_data = {
  3288. +           .tune0_low = 0xffead0ff,
  3289. +           .tune0_high = 0xffead0ff,
  3290. +           .tune1 = 0x25501d0,
  3291. +           .tune_high_min_millivolts = 864,
  3292. +       }
  3293. +   },
  3294. +   {
  3295. +       .speedo_id = 2,
  3296. +       .process_id = 0,
  3297. +       .min_millivolts = 870,
  3298. +       .max_millivolts = 1227,
  3299. +       CPU_CVB_TABLE,
  3300. +       .cpu_dfll_data = {
  3301. +           .tune0_low = 0xffead0ff,
  3302. +           .tune1 = 0x20091d9,
  3303. +       }
  3304. +   },
  3305. +   {
  3306. +       .speedo_id = 2,
  3307. +       .process_id = 1,
  3308. +       .min_millivolts = 870,
  3309. +       .max_millivolts = 1227,
  3310. +       CPU_CVB_TABLE,
  3311. +       .cpu_dfll_data = {
  3312. +           .tune0_low = 0xffead0ff,
  3313. +           .tune1 = 0x25501d0,
  3314. +       }
  3315. +   },
  3316. +   {
  3317. +       .speedo_id = 1,
  3318. +       .process_id = 0,
  3319. +       .min_millivolts = 837,
  3320. +       .max_millivolts = 1227,
  3321. +       CPU_CVB_TABLE,
  3322. +       .cpu_dfll_data = {
  3323. +           .tune0_low = 0xffead0ff,
  3324. +           .tune0_high = 0xffead0ff,
  3325. +           .tune1 = 0x20091d9,
  3326. +           .tune_high_min_millivolts = 864,
  3327. +       }
  3328. +   },
  3329. +   {
  3330. +       .speedo_id = 1,
  3331. +       .process_id = 1,
  3332. +       .min_millivolts = 837,
  3333. +       .max_millivolts = 1227,
  3334. +       CPU_CVB_TABLE,
  3335. +       .cpu_dfll_data = {
  3336. +           .tune0_low = 0xffead0ff,
  3337. +           .tune0_high = 0xffead0ff,
  3338. +           .tune1 = 0x25501d0,
  3339. +           .tune_high_min_millivolts = 864,
  3340. +       }
  3341. +   },
  3342. +   {
  3343. +       .speedo_id = 0,
  3344. +       .process_id = 0,
  3345. +       .min_millivolts = 850,
  3346. +       .max_millivolts = 1170,
  3347. +       CPU_CVB_TABLE,
  3348. +       .cpu_dfll_data = {
  3349. +           .tune0_low = 0xffead0ff,
  3350. +           .tune0_high = 0xffead0ff,
  3351. +           .tune1 = 0x20091d9,
  3352. +           .tune_high_min_millivolts = 864,
  3353. +       }
  3354. +   },
  3355. +   {
  3356. +       .speedo_id = 0,
  3357. +       .process_id = 1,
  3358. +       .min_millivolts = 850,
  3359. +       .max_millivolts = 1170,
  3360. +       CPU_CVB_TABLE,
  3361. +       .cpu_dfll_data = {
  3362. +           .tune0_low = 0xffead0ff,
  3363. +           .tune0_high = 0xffead0ff,
  3364. +           .tune1 = 0x25501d0,
  3365. +           .tune_high_min_millivolts = 864,
  3366. +       }
  3367. +   },
  3368. +};
  3369. +
  3370. +static const struct dfll_fcpu_data tegra124_dfll_fcpu_data = {
  3371. +   .cpu_max_freq_table = tegra124_cpu_max_freq_table,
  3372. +   .cpu_max_freq_table_size = ARRAY_SIZE(tegra124_cpu_max_freq_table),
  3373. +   .cpu_cvb_tables = tegra124_cpu_cvb_tables,
  3374. +   .cpu_cvb_tables_size = ARRAY_SIZE(tegra124_cpu_cvb_tables)
  3375. +};
  3376. +
  3377. +static const struct dfll_fcpu_data tegra210_dfll_fcpu_data = {
  3378. +   .cpu_max_freq_table = tegra210_cpu_max_freq_table,
  3379. +   .cpu_max_freq_table_size = ARRAY_SIZE(tegra210_cpu_max_freq_table),
  3380. +   .cpu_cvb_tables = tegra210_cpu_cvb_tables,
  3381. +   .cpu_cvb_tables_size = ARRAY_SIZE(tegra210_cpu_cvb_tables),
  3382. +};
  3383. +
  3384. +static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
  3385. +   {
  3386. +       .compatible = "nvidia,tegra124-dfll",
  3387. +       .data = &tegra124_dfll_fcpu_data,
  3388. +   },
  3389. +   {
  3390. +       .compatible = "nvidia,tegra210-dfll",
  3391. +       .data = &tegra210_dfll_fcpu_data
  3392. +   },
  3393. +   { },
  3394. +};
  3395. +
  3396. +static int get_alignment_from_regulator(struct device *dev,
  3397. +                   struct rail_alignment *align)
  3398. +{
  3399. +   int min_uV, max_uV, n_voltages, ret;
  3400. +   struct regulator *reg;
  3401. +
  3402. +   reg = devm_regulator_get(dev, "vdd-cpu");
  3403. +   if (IS_ERR(reg))
  3404. +       return PTR_ERR(reg);
  3405. +
  3406. +   ret = regulator_get_constraint_voltages(reg, &min_uV, &max_uV);
  3407. +   if (!ret)
  3408. +       align->offset_uv = min_uV;
  3409. +   else
  3410. +       return ret;
  3411. +
  3412. +   align->step_uv = regulator_get_linear_step(reg);
  3413. +   if (!align->step_uv && !ret) {
  3414. +       n_voltages = regulator_count_voltages(reg);
  3415. +       if (n_voltages > 1)
  3416. +           align->step_uv = (max_uV - min_uV) / (n_voltages - 1);
  3417. +   }
  3418. +
  3419. +   devm_regulator_put(reg);
  3420. +
  3421. +   return 0;
  3422. +}
  3423. +
  3424. +static int get_alignment_from_dt(struct device *dev,
  3425. +                struct rail_alignment *align)
  3426. +{
  3427. +   int err;
  3428. +
  3429. +   err = of_property_read_u32(dev->of_node, "nvidia,align-step-uv",
  3430. +                  &align->step_uv);
  3431. +   if (err < 0)
  3432. +       return err;
  3433. +
  3434. +   err = of_property_read_u32(dev->of_node,
  3435. +                  "nvidia,align-offset-uv", &align->offset_uv);
  3436. +   return err;
  3437. +}
  3438. +
  3439.  static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
  3440.  {
  3441.     int process_id, speedo_id, speedo_value, err;
  3442.     struct tegra_dfll_soc_data *soc;
  3443. +   const struct of_device_id *of_id;
  3444. +   const struct dfll_fcpu_data *fcpu_data;
  3445. +
  3446. +   of_id = of_match_device(tegra124_dfll_fcpu_of_match, &pdev->dev);
  3447. +   fcpu_data = of_id->data;
  3448.  
  3449.     process_id = tegra_sku_info.cpu_process_id;
  3450.     speedo_id = tegra_sku_info.cpu_speedo_id;
  3451.     speedo_value = tegra_sku_info.cpu_speedo_value;
  3452.  
  3453. -   if (speedo_id >= ARRAY_SIZE(cpu_max_freq_table)) {
  3454. +   if (speedo_id >= fcpu_data->cpu_max_freq_table_size) {
  3455.         dev_err(&pdev->dev, "unknown max CPU freq for speedo_id=%d\n",
  3456.             speedo_id);
  3457.         return -ENODEV;
  3458. @@ -107,11 +602,19 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
  3459.         return -ENODEV;
  3460.     }
  3461.  
  3462. -   soc->max_freq = cpu_max_freq_table[speedo_id];
  3463. +   soc->max_freq = fcpu_data->cpu_max_freq_table[speedo_id];
  3464. +   if (of_property_read_bool(pdev->dev.of_node, "nvidia,pwm-to-pmic"))
  3465. +       err = get_alignment_from_dt(&pdev->dev, &soc->alignment);
  3466. +   else
  3467. +       err = get_alignment_from_regulator(&pdev->dev,
  3468. +                          &soc->alignment);
  3469. +   if (err < 0)
  3470. +       return err;
  3471.  
  3472. -   soc->cvb = tegra_cvb_add_opp_table(soc->dev, tegra124_cpu_cvb_tables,
  3473. -                      ARRAY_SIZE(tegra124_cpu_cvb_tables),
  3474. -                      process_id, speedo_id, speedo_value,
  3475. +   soc->cvb = tegra_cvb_add_opp_table(soc->dev, fcpu_data->cpu_cvb_tables,
  3476. +                      fcpu_data->cpu_cvb_tables_size,
  3477. +                      &soc->alignment, process_id,
  3478. +                      speedo_id, speedo_value,
  3479.                        soc->max_freq);
  3480.     if (IS_ERR(soc->cvb)) {
  3481.         dev_err(&pdev->dev, "couldn't add OPP table: %ld\n",
  3482. @@ -142,11 +645,6 @@ static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
  3483.     return 0;
  3484.  }
  3485.  
  3486. -static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
  3487. -   { .compatible = "nvidia,tegra124-dfll", },
  3488. -   { },
  3489. -};
  3490. -
  3491.  static const struct dev_pm_ops tegra124_dfll_pm_ops = {
  3492.     SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend,
  3493.                tegra_dfll_runtime_resume, NULL)
  3494. diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
  3495. index 9fb5d51..5484e46 100644
  3496. --- a/drivers/clk/tegra/clk-tegra210.c
  3497. +++ b/drivers/clk/tegra/clk-tegra210.c
  3498. @@ -3359,6 +3359,14 @@ static struct tegra_clk_init_table init_table[] __initdata = {
  3499.     { TEGRA210_CLK_CCLK_G, TEGRA210_CLK_CLK_MAX, 0, 1 },
  3500.     { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 },
  3501.     { TEGRA210_CLK_PLL_U_OUT2, TEGRA210_CLK_CLK_MAX, 60000000, 1 },
  3502. +   { TEGRA210_CLK_CLK72MHZ, TEGRA210_CLK_PLL_P_OUT3, 68000000, 0 },
  3503. +// { TEGRA210_CLK_DSIA, TEGRA210_CLK_PLL_D, 68000000, 0 },
  3504. +// { TEGRA210_CLK_DSIB, TEGRA210_CLK_PLL_D, 68000000, 0 },
  3505. +   { TEGRA210_CLK_DSIALP, TEGRA210_CLK_PLL_P, 68000000, 0 },
  3506. +   { TEGRA210_CLK_DSIBLP, TEGRA210_CLK_PLL_P, 68000000, 0 },
  3507. +   { TEGRA210_CLK_DISP1, TEGRA210_CLK_PLL_D_OUT0, 0, 0 },
  3508. +   { TEGRA210_CLK_DISP2, TEGRA210_CLK_PLL_D_OUT0, 0, 0 },
  3509. +   { TEGRA210_CLK_PWM, TEGRA210_CLK_PLL_P, 48000000, 0 },
  3510.     /* This MUST be the last entry. */
  3511.     { TEGRA210_CLK_CLK_MAX, TEGRA210_CLK_CLK_MAX, 0, 0 },
  3512.  };
  3513. @@ -3534,6 +3542,25 @@ static void __init tegra210_clock_init(struct device_node *np)
  3514.         return;
  3515.     }
  3516.  
  3517. +   ahub_base = ioremap(TEGRA210_AHUB_BASE, 64*1024);
  3518. +   if (!ahub_base) {
  3519. +       pr_err("ioremap tegra210 APE failed\n");
  3520. +       return;
  3521. +   }
  3522. +
  3523. +   dispa_base = ioremap(TEGRA210_DISPA_BASE, 256*1024);
  3524. +   if (!dispa_base) {
  3525. +       pr_err("ioremap tegra210 DISPA failed\n");
  3526. +       return;
  3527. +   }
  3528. +
  3529. +   vic_base = ioremap(TEGRA210_VIC_BASE, 256*1024);
  3530. +   if (!vic_base) {
  3531. +       pr_err("ioremap tegra210 VIC failed\n");
  3532. +       return;
  3533. +   }
  3534. +
  3535. +
  3536.     clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
  3537.                   TEGRA210_CAR_BANK_COUNT);
  3538.     if (!clks)
  3539. diff --git a/drivers/clk/tegra/cvb.c b/drivers/clk/tegra/cvb.c
  3540. index da9e8e7..2aa9639 100644
  3541. --- a/drivers/clk/tegra/cvb.c
  3542. +++ b/drivers/clk/tegra/cvb.c
  3543. @@ -62,11 +62,17 @@ static int round_voltage(int mv, const struct rail_alignment *align, int up)
  3544.  }
  3545.  
  3546.  static int build_opp_table(struct device *dev, const struct cvb_table *table,
  3547. +              struct rail_alignment *align,
  3548.                int speedo_value, unsigned long max_freq)
  3549.  {
  3550. -   const struct rail_alignment *align = &table->alignment;
  3551.     int i, ret, dfll_mv, min_mv, max_mv;
  3552.  
  3553. +   if (!align->step_uv)
  3554. +       return -EINVAL;
  3555. +
  3556. +   if (!align->offset_uv)
  3557. +       return -EINVAL;
  3558. +
  3559.     min_mv = round_voltage(table->min_millivolts, align, UP);
  3560.     max_mv = round_voltage(table->max_millivolts, align, DOWN);
  3561.  
  3562. @@ -109,8 +115,9 @@ static int build_opp_table(struct device *dev, const struct cvb_table *table,
  3563.   */
  3564.  const struct cvb_table *
  3565.  tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables,
  3566. -           size_t count, int process_id, int speedo_id,
  3567. -           int speedo_value, unsigned long max_freq)
  3568. +           size_t count, struct rail_alignment *align,
  3569. +           int process_id, int speedo_id, int speedo_value,
  3570. +           unsigned long max_freq)
  3571.  {
  3572.     size_t i;
  3573.     int ret;
  3574. @@ -124,7 +131,8 @@ tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables,
  3575.         if (table->process_id != -1 && table->process_id != process_id)
  3576.             continue;
  3577.  
  3578. -       ret = build_opp_table(dev, table, speedo_value, max_freq);
  3579. +       ret = build_opp_table(dev, table, align, speedo_value,
  3580. +                     max_freq);
  3581.         return ret ? ERR_PTR(ret) : table;
  3582.     }
  3583.  
  3584. diff --git a/drivers/clk/tegra/cvb.h b/drivers/clk/tegra/cvb.h
  3585. index c1f0779..91a1941 100644
  3586. --- a/drivers/clk/tegra/cvb.h
  3587. +++ b/drivers/clk/tegra/cvb.h
  3588. @@ -41,6 +41,7 @@ struct cvb_cpu_dfll_data {
  3589.     u32 tune0_low;
  3590.     u32 tune0_high;
  3591.     u32 tune1;
  3592. +   unsigned int tune_high_min_millivolts;
  3593.  };
  3594.  
  3595.  struct cvb_table {
  3596. @@ -49,7 +50,6 @@ struct cvb_table {
  3597.  
  3598.     int min_millivolts;
  3599.     int max_millivolts;
  3600. -   struct rail_alignment alignment;
  3601.  
  3602.     int speedo_scale;
  3603.     int voltage_scale;
  3604. @@ -59,8 +59,9 @@ struct cvb_table {
  3605.  
  3606.  const struct cvb_table *
  3607.  tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *cvb_tables,
  3608. -           size_t count, int process_id, int speedo_id,
  3609. -           int speedo_value, unsigned long max_freq);
  3610. +           size_t count, struct rail_alignment *align,
  3611. +           int process_id, int speedo_id, int speedo_value,
  3612. +           unsigned long max_freq);
  3613.  void tegra_cvb_remove_opp_table(struct device *dev,
  3614.                 const struct cvb_table *table,
  3615.                 unsigned long max_freq);
  3616. diff --git a/drivers/cpufreq/tegra124-cpufreq.c b/drivers/cpufreq/tegra124-cpufreq.c
  3617. index 4353025..f8e01a8 100644
  3618. --- a/drivers/cpufreq/tegra124-cpufreq.c
  3619. +++ b/drivers/cpufreq/tegra124-cpufreq.c
  3620. @@ -64,7 +64,8 @@ static void tegra124_cpu_switch_to_pllx(struct tegra124_cpufreq_priv *priv)
  3621.  {
  3622.     clk_set_parent(priv->cpu_clk, priv->pllp_clk);
  3623.     clk_disable_unprepare(priv->dfll_clk);
  3624. -   regulator_sync_voltage(priv->vdd_cpu_reg);
  3625. +   if (priv->vdd_cpu_reg)
  3626. +       regulator_sync_voltage(priv->vdd_cpu_reg);
  3627.     clk_set_parent(priv->cpu_clk, priv->pllx_clk);
  3628.  }
  3629.  
  3630. @@ -89,10 +90,10 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
  3631.         return -ENODEV;
  3632.  
  3633.     priv->vdd_cpu_reg = regulator_get(cpu_dev, "vdd-cpu");
  3634. -   if (IS_ERR(priv->vdd_cpu_reg)) {
  3635. -       ret = PTR_ERR(priv->vdd_cpu_reg);
  3636. -       goto out_put_np;
  3637. -   }
  3638. +   if (IS_ERR(priv->vdd_cpu_reg) != -EPROBE_DEFER)
  3639. +       priv->vdd_cpu_reg = NULL;
  3640. +   else
  3641. +       return -EPROBE_DEFER;
  3642.  
  3643.     priv->cpu_clk = of_clk_get_by_name(np, "cpu_g");
  3644.     if (IS_ERR(priv->cpu_clk)) {
  3645. @@ -148,7 +149,6 @@ out_put_cpu_clk:
  3646.     clk_put(priv->cpu_clk);
  3647.  out_put_vdd_cpu_reg:
  3648.     regulator_put(priv->vdd_cpu_reg);
  3649. -out_put_np:
  3650.     of_node_put(np);
  3651.  
  3652.     return ret;
  3653. @@ -181,7 +181,8 @@ static int __init tegra_cpufreq_init(void)
  3654.     int ret;
  3655.     struct platform_device *pdev;
  3656.  
  3657. -   if (!of_machine_is_compatible("nvidia,tegra124"))
  3658. +   if (!(of_machine_is_compatible("nvidia,tegra124")
  3659. +       || of_machine_is_compatible("nvidia,tegra210")))
  3660.         return -ENODEV;
  3661.  
  3662.     /*
  3663. diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
  3664. index 94396ca..a3694f0 100644
  3665. --- a/drivers/gpio/gpio-tegra.c
  3666. +++ b/drivers/gpio/gpio-tegra.c
  3667. @@ -356,6 +356,8 @@ static void tegra_gpio_irq_shutdown(struct irq_data *d)
  3668.     struct tegra_gpio_info *tgi = bank->tgi;
  3669.     unsigned int gpio = d->hwirq;
  3670.  
  3671. +   tegra_gpio_irq_mask(d);
  3672. +
  3673.     gpiochip_unlock_as_irq(&tgi->gc, gpio);
  3674.  }
  3675.  
  3676. diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
  3677. index 7856a9b..082f653 100644
  3678. --- a/drivers/gpu/drm/drm_prime.c
  3679. +++ b/drivers/gpu/drm/drm_prime.c
  3680. @@ -182,6 +182,7 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri
  3681.  
  3682.     return -ENOENT;
  3683.  }
  3684. +EXPORT_SYMBOL(drm_gem_map_detach);
  3685.  
  3686.  /**
  3687.   * drm_gem_map_attach - dma_buf attach implementation for GEM
  3688. diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
  3689. index ab61c03..1060ce4 100644
  3690. --- a/drivers/gpu/drm/nouveau/nouveau_bo.c
  3691. +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
  3692. @@ -544,6 +544,42 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
  3693.                     PAGE_SIZE, DMA_FROM_DEVICE);
  3694.  }
  3695.  
  3696. +int
  3697. +nouveau_bo_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan,
  3698. +       bool exclusive, bool intr)
  3699. +{
  3700. +   struct reservation_object *resv = nvbo->bo.resv;
  3701. +   struct reservation_object_list *fobj;
  3702. +   struct dma_fence *fence;
  3703. +   int ret = 0, i;
  3704. +
  3705. +   if (!exclusive) {
  3706. +       ret = reservation_object_reserve_shared(resv);
  3707. +       if (ret < 0)
  3708. +           return ret;
  3709. +   }
  3710. +
  3711. +   fobj = reservation_object_get_list(resv);
  3712. +   fence = reservation_object_get_excl(resv);
  3713. +
  3714. +   if (fence && (!exclusive || !fobj || !fobj->shared_count))
  3715. +       return nouveau_fence_sync(fence, chan, intr);
  3716. +
  3717. +   if (!exclusive || !fobj)
  3718. +       return ret;
  3719. +
  3720. +   for (i = 0; i < fobj->shared_count && !ret; ++i) {
  3721. +       fence = rcu_dereference_protected(fobj->shared[i],
  3722. +                         reservation_object_held(resv));
  3723. +
  3724. +       ret = nouveau_fence_sync(fence, chan, intr);
  3725. +       if (ret < 0)
  3726. +           break;
  3727. +   }
  3728. +
  3729. +   return ret;
  3730. +}
  3731. +
  3732.  int
  3733.  nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible,
  3734.             bool no_wait_gpu)
  3735. @@ -1111,7 +1147,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
  3736.     }
  3737.  
  3738.     mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING);
  3739. -   ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, intr);
  3740. +   ret = nouveau_bo_sync(nouveau_bo(bo), chan, true, intr);
  3741.     if (ret == 0) {
  3742.         ret = drm->ttm.move(chan, bo, &bo->mem, new_reg);
  3743.         if (ret == 0) {
  3744. diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h
  3745. index 73c4844..9a79502 100644
  3746. --- a/drivers/gpu/drm/nouveau/nouveau_bo.h
  3747. +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
  3748. @@ -91,6 +91,8 @@ int  nouveau_bo_validate(struct nouveau_bo *, bool interruptible,
  3749.              bool no_wait_gpu);
  3750.  void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo);
  3751.  void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo);
  3752. +int nouveau_bo_sync(struct nouveau_bo *nvbo, struct nouveau_channel *channel,
  3753. +           bool exclusive, bool intr);
  3754.  
  3755.  /* TODO: submit equivalent to TTM generic API upstream? */
  3756.  static inline void __iomem *
  3757. diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
  3758. index 4cba117..014a50f 100644
  3759. --- a/drivers/gpu/drm/nouveau/nouveau_display.c
  3760. +++ b/drivers/gpu/drm/nouveau/nouveau_display.c
  3761. @@ -761,7 +761,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
  3762.     spin_unlock_irqrestore(&dev->event_lock, flags);
  3763.  
  3764.     /* Synchronize with the old framebuffer */
  3765. -   ret = nouveau_fence_sync(old_bo, chan, false, false);
  3766. +   ret = nouveau_bo_sync(old_bo, chan, false, false);
  3767.     if (ret)
  3768.         goto fail;
  3769.  
  3770. @@ -825,7 +825,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
  3771.         goto fail_unpin;
  3772.  
  3773.     /* synchronise rendering channel with the kernel's channel */
  3774. -   ret = nouveau_fence_sync(new_bo, chan, false, true);
  3775. +   ret = nouveau_bo_sync(new_bo, chan, false, true);
  3776.     if (ret) {
  3777.         ttm_bo_unreserve(&new_bo->bo);
  3778.         goto fail_unpin;
  3779. diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
  3780. index f8e67ab..acfa5b5 100644
  3781. --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
  3782. +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
  3783. @@ -961,6 +961,7 @@ nouveau_ioctls[] = {
  3784.     DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH|DRM_RENDER_ALLOW),
  3785.     DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH|DRM_RENDER_ALLOW),
  3786.     DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH|DRM_RENDER_ALLOW),
  3787. +   DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF2, nouveau_gem_ioctl_pushbuf2, DRM_AUTH|DRM_RENDER_ALLOW),
  3788.  };
  3789.  
  3790.  long
  3791. @@ -1030,15 +1031,12 @@ driver_stub = {
  3792.  
  3793.     .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
  3794.     .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
  3795. -   .gem_prime_export = drm_gem_prime_export,
  3796. -   .gem_prime_import = drm_gem_prime_import,
  3797. +   .gem_prime_export = nouveau_gem_prime_export,
  3798. +   .gem_prime_import = nouveau_gem_prime_import,
  3799.     .gem_prime_pin = nouveau_gem_prime_pin,
  3800. -   .gem_prime_res_obj = nouveau_gem_prime_res_obj,
  3801.     .gem_prime_unpin = nouveau_gem_prime_unpin,
  3802. +   .gem_prime_res_obj = nouveau_gem_prime_res_obj,
  3803.     .gem_prime_get_sg_table = nouveau_gem_prime_get_sg_table,
  3804. -   .gem_prime_import_sg_table = nouveau_gem_prime_import_sg_table,
  3805. -   .gem_prime_vmap = nouveau_gem_prime_vmap,
  3806. -   .gem_prime_vunmap = nouveau_gem_prime_vunmap,
  3807.  
  3808.     .gem_free_object_unlocked = nouveau_gem_object_del,
  3809.     .gem_open_object = nouveau_gem_object_open,
  3810. diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
  3811. index 503fa94..63022bc 100644
  3812. --- a/drivers/gpu/drm/nouveau/nouveau_fence.c
  3813. +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
  3814. @@ -28,6 +28,7 @@
  3815.  
  3816.  #include <linux/ktime.h>
  3817.  #include <linux/hrtimer.h>
  3818. +#include <linux/dma-fence-array.h>
  3819.  #include <trace/events/dma_fence.h>
  3820.  
  3821.  #include <nvif/cl826e.h>
  3822. @@ -331,66 +332,50 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr)
  3823.         return 0;
  3824.  }
  3825.  
  3826. -int
  3827. -nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool exclusive, bool intr)
  3828. +static int
  3829. +__nouveau_fence_sync(struct dma_fence *fence, struct nouveau_channel *chan,
  3830. +            bool intr)
  3831.  {
  3832.     struct nouveau_fence_chan *fctx = chan->fence;
  3833. -   struct dma_fence *fence;
  3834. -   struct reservation_object *resv = nvbo->bo.resv;
  3835. -   struct reservation_object_list *fobj;
  3836. +   struct nouveau_channel *prev = NULL;
  3837.     struct nouveau_fence *f;
  3838. -   int ret = 0, i;
  3839. -
  3840. -   if (!exclusive) {
  3841. -       ret = reservation_object_reserve_shared(resv);
  3842. +   bool must_wait = true;
  3843. +   int ret = 0;
  3844.  
  3845. -       if (ret)
  3846. -           return ret;
  3847. +   f = nouveau_local_fence(fence, chan->drm);
  3848. +   if (f) {
  3849. +       rcu_read_lock();
  3850. +       prev = rcu_dereference(f->channel);
  3851. +       if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0))
  3852. +           must_wait = false;
  3853. +       rcu_read_unlock();
  3854.     }
  3855.  
  3856. -   fobj = reservation_object_get_list(resv);
  3857. -   fence = reservation_object_get_excl(resv);
  3858. -
  3859. -   if (fence && (!exclusive || !fobj || !fobj->shared_count)) {
  3860. -       struct nouveau_channel *prev = NULL;
  3861. -       bool must_wait = true;
  3862. +   if (must_wait)
  3863. +       ret = dma_fence_wait(fence, intr);
  3864.  
  3865. -       f = nouveau_local_fence(fence, chan->drm);
  3866. -       if (f) {
  3867. -           rcu_read_lock();
  3868. -           prev = rcu_dereference(f->channel);
  3869. -           if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0))
  3870. -               must_wait = false;
  3871. -           rcu_read_unlock();
  3872. -       }
  3873. -
  3874. -       if (must_wait)
  3875. -           ret = dma_fence_wait(fence, intr);
  3876. -
  3877. -       return ret;
  3878. -   }
  3879. +   return ret;
  3880. +}
  3881.  
  3882. -   if (!exclusive || !fobj)
  3883. -       return ret;
  3884. +int
  3885. +nouveau_fence_sync(struct dma_fence *fence, struct nouveau_channel *chan,
  3886. +          bool intr)
  3887. +{
  3888. +   int ret = 0;
  3889.  
  3890. -   for (i = 0; i < fobj->shared_count && !ret; ++i) {
  3891. -       struct nouveau_channel *prev = NULL;
  3892. -       bool must_wait = true;
  3893. +   if (dma_fence_is_array(fence)) {
  3894. +       struct dma_fence_array *array = to_dma_fence_array(fence);
  3895. +       unsigned int i;
  3896.  
  3897. -       fence = rcu_dereference_protected(fobj->shared[i],
  3898. -                       reservation_object_held(resv));
  3899. +       for (i = 0; i < array->num_fences; i++) {
  3900. +           struct dma_fence *f = array->fences[i];
  3901.  
  3902. -       f = nouveau_local_fence(fence, chan->drm);
  3903. -       if (f) {
  3904. -           rcu_read_lock();
  3905. -           prev = rcu_dereference(f->channel);
  3906. -           if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0))
  3907. -               must_wait = false;
  3908. -           rcu_read_unlock();
  3909. +           ret = __nouveau_fence_sync(f, chan, intr);
  3910. +           if (ret < 0)
  3911. +               break;
  3912.         }
  3913. -
  3914. -       if (must_wait)
  3915. -           ret = dma_fence_wait(fence, intr);
  3916. +   } else {
  3917. +       ret = __nouveau_fence_sync(fence, chan, intr);
  3918.     }
  3919.  
  3920.     return ret;
  3921. diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
  3922. index 5bd8d30..2c46d9e 100644
  3923. --- a/drivers/gpu/drm/nouveau/nouveau_fence.h
  3924. +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
  3925. @@ -24,7 +24,7 @@ void nouveau_fence_unref(struct nouveau_fence **);
  3926.  int  nouveau_fence_emit(struct nouveau_fence *, struct nouveau_channel *);
  3927.  bool nouveau_fence_done(struct nouveau_fence *);
  3928.  int  nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr);
  3929. -int  nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool exclusive, bool intr);
  3930. +int  nouveau_fence_sync(struct dma_fence *, struct nouveau_channel *, bool intr);
  3931.  
  3932.  struct nouveau_fence_chan {
  3933.     spinlock_t lock;
  3934. diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
  3935. index 707e02c..d690f11 100644
  3936. --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
  3937. +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
  3938. @@ -24,6 +24,8 @@
  3939.   *
  3940.   */
  3941.  
  3942. +#include <linux/sync_file.h>
  3943. +
  3944.  #include "nouveau_drv.h"
  3945.  #include "nouveau_dma.h"
  3946.  #include "nouveau_fence.h"
  3947. @@ -507,7 +509,7 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli,
  3948.             return ret;
  3949.         }
  3950.  
  3951. -       ret = nouveau_fence_sync(nvbo, chan, !!b->write_domains, true);
  3952. +       ret = nouveau_bo_sync(nvbo, chan, !!b->write_domains, true);
  3953.         if (unlikely(ret)) {
  3954.             if (ret != -ERESTARTSYS)
  3955.                 NV_PRINTK(err, cli, "fail post-validate sync\n");
  3956. @@ -679,22 +681,28 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
  3957.     return ret;
  3958.  }
  3959.  
  3960. -int
  3961. -nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
  3962. -             struct drm_file *file_priv)
  3963. +static int
  3964. +__nouveau_gem_ioctl_pushbuf(struct drm_device *dev,
  3965. +               struct drm_nouveau_gem_pushbuf2 *request,
  3966. +               struct drm_file *file_priv)
  3967.  {
  3968.     struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
  3969.     struct nouveau_cli *cli = nouveau_cli(file_priv);
  3970.     struct nouveau_abi16_chan *temp;
  3971.     struct nouveau_drm *drm = nouveau_drm(dev);
  3972. -   struct drm_nouveau_gem_pushbuf *req = data;
  3973. +   struct drm_nouveau_gem_pushbuf *req = &request->base;
  3974.     struct drm_nouveau_gem_pushbuf_push *push;
  3975.     struct drm_nouveau_gem_pushbuf_bo *bo;
  3976.     struct nouveau_channel *chan = NULL;
  3977.     struct validate_op op;
  3978.     struct nouveau_fence *fence = NULL;
  3979. +   struct dma_fence *prefence = NULL;
  3980.     int i, j, ret = 0, do_reloc = 0;
  3981.  
  3982. +   /* check for unrecognized flags */
  3983. +   if (request->flags & ~NOUVEAU_GEM_PUSHBUF_FLAGS)
  3984. +       return -EINVAL;
  3985. +
  3986.     if (unlikely(!abi16))
  3987.         return -ENOMEM;
  3988.  
  3989. @@ -759,6 +767,15 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
  3990.         goto out_prevalid;
  3991.     }
  3992.  
  3993. +   if (request->flags & NOUVEAU_GEM_PUSHBUF_FENCE_WAIT) {
  3994. +       prefence = sync_file_get_fence(request->fence);
  3995. +       if (prefence) {
  3996. +           ret = nouveau_fence_sync(prefence, chan, true);
  3997. +           if (ret < 0)
  3998. +               goto out;
  3999. +       }
  4000. +   }
  4001. +
  4002.     /* Apply any relocations that are required */
  4003.     if (do_reloc) {
  4004.         ret = nouveau_gem_pushbuf_reloc_apply(cli, req, bo);
  4005. @@ -843,7 +860,30 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
  4006.         goto out;
  4007.     }
  4008.  
  4009. +   if (request->flags & NOUVEAU_GEM_PUSHBUF_FENCE_EMIT) {
  4010. +       struct sync_file *file;
  4011. +       int fd;
  4012. +
  4013. +       fd = get_unused_fd_flags(O_CLOEXEC);
  4014. +       if (fd < 0) {
  4015. +           ret = fd;
  4016. +           goto out;
  4017. +       }
  4018. +
  4019. +       file = sync_file_create(&fence->base);
  4020. +       if (!file) {
  4021. +           put_unused_fd(fd);
  4022. +           goto out;
  4023. +       }
  4024. +
  4025. +       fd_install(fd, file->file);
  4026. +       request->fence = fd;
  4027. +   }
  4028. +
  4029.  out:
  4030. +   if (prefence)
  4031. +       dma_fence_put(prefence);
  4032. +
  4033.     validate_fini(&op, fence, bo);
  4034.     nouveau_fence_unref(&fence);
  4035.  
  4036. @@ -868,6 +908,27 @@ out_next:
  4037.     return nouveau_abi16_put(abi16, ret);
  4038.  }
  4039.  
  4040. +int
  4041. +nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
  4042. +             struct drm_file *file_priv)
  4043. +{
  4044. +   struct drm_nouveau_gem_pushbuf *request = data;
  4045. +   struct drm_nouveau_gem_pushbuf2 req;
  4046. +   int ret;
  4047. +
  4048. +   memset(&req, 0, sizeof(req));
  4049. +   memcpy(&req.base, request, sizeof(*request));
  4050. +
  4051. +   ret = __nouveau_gem_ioctl_pushbuf(dev, &req, file_priv);
  4052. +
  4053. +   request->gart_available = req.base.gart_available;
  4054. +   request->vram_available = req.base.vram_available;
  4055. +   request->suffix1 = req.base.suffix1;
  4056. +   request->suffix0 = req.base.suffix0;
  4057. +
  4058. +   return ret;
  4059. +}
  4060. +
  4061.  int
  4062.  nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
  4063.                struct drm_file *file_priv)
  4064. @@ -935,3 +996,12 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
  4065.     return ret;
  4066.  }
  4067.  
  4068. +int
  4069. +nouveau_gem_ioctl_pushbuf2(struct drm_device *dev, void *data,
  4070. +              struct drm_file *file_priv)
  4071. +{
  4072. +   struct drm_nouveau_gem_pushbuf2 *req = data;
  4073. +
  4074. +   return __nouveau_gem_ioctl_pushbuf(dev, req, file_priv);
  4075. +}
  4076. +
  4077. diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h
  4078. index fe39998..3c98b0f 100644
  4079. --- a/drivers/gpu/drm/nouveau/nouveau_gem.h
  4080. +++ b/drivers/gpu/drm/nouveau/nouveau_gem.h
  4081. @@ -31,14 +31,17 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
  4082.                       struct drm_file *);
  4083.  extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
  4084.                   struct drm_file *);
  4085. +extern int nouveau_gem_ioctl_pushbuf2(struct drm_device *, void *,
  4086. +                     struct drm_file *);
  4087.  
  4088. -extern int nouveau_gem_prime_pin(struct drm_gem_object *);
  4089. +struct dma_buf *nouveau_gem_prime_export(struct drm_device *dev,
  4090. +                    struct drm_gem_object *obj,
  4091. +                    int flags);
  4092. +struct drm_gem_object *nouveau_gem_prime_import(struct drm_device *drm,
  4093. +                       struct dma_buf *buf);
  4094. +int nouveau_gem_prime_pin(struct drm_gem_object *obj);
  4095. +void nouveau_gem_prime_unpin(struct drm_gem_object *obj);
  4096.  struct reservation_object *nouveau_gem_prime_res_obj(struct drm_gem_object *);
  4097. -extern void nouveau_gem_prime_unpin(struct drm_gem_object *);
  4098. -extern struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *);
  4099. -extern struct drm_gem_object *nouveau_gem_prime_import_sg_table(
  4100. -   struct drm_device *, struct dma_buf_attachment *, struct sg_table *);
  4101. -extern void *nouveau_gem_prime_vmap(struct drm_gem_object *);
  4102. -extern void nouveau_gem_prime_vunmap(struct drm_gem_object *, void *);
  4103. +struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *obj);
  4104.  
  4105.  #endif
  4106. diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
  4107. index 1fefc93..a3a586c 100644
  4108. --- a/drivers/gpu/drm/nouveau/nouveau_prime.c
  4109. +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
  4110. @@ -23,69 +23,206 @@
  4111.   */
  4112.  
  4113.  #include <drm/drmP.h>
  4114. +#include <drm/drm_legacy.h>
  4115.  #include <linux/dma-buf.h>
  4116.  
  4117.  #include "nouveau_drv.h"
  4118.  #include "nouveau_gem.h"
  4119.  
  4120. -struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *obj)
  4121. +static int nouveau_gem_prime_begin_cpu_access(struct dma_buf *buf,
  4122. +                         enum dma_data_direction direction)
  4123.  {
  4124. -   struct nouveau_bo *nvbo = nouveau_gem_object(obj);
  4125. -   int npages = nvbo->bo.num_pages;
  4126. +   struct nouveau_bo *bo = nouveau_gem_object(buf->priv);
  4127.  
  4128. -   return drm_prime_pages_to_sg(nvbo->bo.ttm->pages, npages);
  4129. +   nouveau_bo_sync_for_cpu(bo);
  4130. +
  4131. +   return 0;
  4132.  }
  4133.  
  4134. -void *nouveau_gem_prime_vmap(struct drm_gem_object *obj)
  4135. +static int nouveau_gem_prime_end_cpu_access(struct dma_buf *buf,
  4136. +                       enum dma_data_direction direction)
  4137.  {
  4138. -   struct nouveau_bo *nvbo = nouveau_gem_object(obj);
  4139. +   struct nouveau_bo *bo = nouveau_gem_object(buf->priv);
  4140. +
  4141. +   nouveau_bo_sync_for_device(bo);
  4142. +
  4143. +   return 0;
  4144. +}
  4145. +
  4146. +static void *nouveau_gem_prime_kmap_atomic(struct dma_buf *buf,
  4147. +                      unsigned long page)
  4148. +{
  4149. +   return NULL;
  4150. +}
  4151. +
  4152. +static void nouveau_gem_prime_kunmap_atomic(struct dma_buf *buf,
  4153. +                       unsigned long page, void *addr)
  4154. +{
  4155. +}
  4156. +
  4157. +static void *nouveau_gem_prime_kmap(struct dma_buf *buf, unsigned long page)
  4158. +{
  4159. +   return NULL;
  4160. +}
  4161. +
  4162. +static void nouveau_gem_prime_kunmap(struct dma_buf *buf, unsigned long page,
  4163. +                    void *addr)
  4164. +{
  4165. +}
  4166. +
  4167. +static inline u64 nouveau_bo_mmap_offset(struct nouveau_bo *bo)
  4168. +{
  4169. +   return drm_vma_node_offset_addr(&bo->bo.vma_node) >> PAGE_SHIFT;
  4170. +}
  4171. +
  4172. +static int nouveau_gem_prime_mmap(struct dma_buf *buf,
  4173. +                 struct vm_area_struct *vma)
  4174. +{
  4175. +   struct nouveau_bo *bo = nouveau_gem_object(buf->priv);
  4176. +   struct drm_gem_object *obj = buf->priv;
  4177. +   int ret;
  4178. +
  4179. +   /* check for valid size */
  4180. +   if (obj->size < vma->vm_end - vma->vm_start)
  4181. +       return -EINVAL;
  4182. +
  4183. +   vma->vm_pgoff += nouveau_bo_mmap_offset(bo);
  4184. +
  4185. +   if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
  4186. +       return drm_legacy_mmap(vma->vm_file, vma);
  4187. +
  4188. +   ret = drm_vma_node_allow(&obj->vma_node, vma->vm_file->private_data);
  4189. +   if (ret)
  4190. +       return ret;
  4191. +
  4192. +   ret = ttm_bo_mmap(vma->vm_file, vma, bo->bo.bdev);
  4193. +   drm_vma_node_revoke(&obj->vma_node, vma->vm_file->private_data);
  4194. +
  4195. +   return ret;
  4196. +}
  4197. +
  4198. +static void *nouveau_gem_prime_vmap(struct dma_buf *buf)
  4199. +{
  4200. +   struct nouveau_bo *bo = nouveau_gem_object(buf->priv);
  4201.     int ret;
  4202.  
  4203. -   ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.num_pages,
  4204. -             &nvbo->dma_buf_vmap);
  4205. +   ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->dma_buf_vmap);
  4206.     if (ret)
  4207.         return ERR_PTR(ret);
  4208.  
  4209. -   return nvbo->dma_buf_vmap.virtual;
  4210. +   return bo->dma_buf_vmap.virtual;
  4211.  }
  4212.  
  4213. -void nouveau_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
  4214. +static void nouveau_gem_prime_vunmap(struct dma_buf *buf, void *vaddr)
  4215.  {
  4216. -   struct nouveau_bo *nvbo = nouveau_gem_object(obj);
  4217. +   struct nouveau_bo *bo = nouveau_gem_object(buf->priv);
  4218.  
  4219. -   ttm_bo_kunmap(&nvbo->dma_buf_vmap);
  4220. +   ttm_bo_kunmap(&bo->dma_buf_vmap);
  4221.  }
  4222.  
  4223. -struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev,
  4224. -                            struct dma_buf_attachment *attach,
  4225. -                            struct sg_table *sg)
  4226. +static const struct dma_buf_ops nouveau_gem_prime_dmabuf_ops = {
  4227. +   .attach = drm_gem_map_attach,
  4228. +   .detach = drm_gem_map_detach,
  4229. +   .map_dma_buf = drm_gem_map_dma_buf,
  4230. +   .unmap_dma_buf = drm_gem_unmap_dma_buf,
  4231. +   .release = drm_gem_dmabuf_release,
  4232. +   .begin_cpu_access = nouveau_gem_prime_begin_cpu_access,
  4233. +   .end_cpu_access = nouveau_gem_prime_end_cpu_access,
  4234. +   .map_atomic = nouveau_gem_prime_kmap_atomic,
  4235. +   .unmap_atomic = nouveau_gem_prime_kunmap_atomic,
  4236. +   .map = nouveau_gem_prime_kmap,
  4237. +   .unmap = nouveau_gem_prime_kunmap,
  4238. +   .mmap = nouveau_gem_prime_mmap,
  4239. +   .vmap = nouveau_gem_prime_vmap,
  4240. +   .vunmap = nouveau_gem_prime_vunmap,
  4241. +};
  4242. +
  4243. +struct dma_buf *nouveau_gem_prime_export(struct drm_device *dev,
  4244. +                    struct drm_gem_object *obj,
  4245. +                    int flags)
  4246. +{
  4247. +   DEFINE_DMA_BUF_EXPORT_INFO(info);
  4248. +
  4249. +   info.exp_name = KBUILD_MODNAME;
  4250. +   info.owner = dev->driver->fops->owner;
  4251. +   info.ops = &nouveau_gem_prime_dmabuf_ops;
  4252. +   info.size = obj->size;
  4253. +   info.flags = flags;
  4254. +   info.priv = obj;
  4255. +
  4256. +   if (dev->driver->gem_prime_res_obj)
  4257. +       info.resv = dev->driver->gem_prime_res_obj(obj);
  4258. +
  4259. +   return drm_gem_dmabuf_export(dev, &info);
  4260. +}
  4261. +
  4262. +struct drm_gem_object *nouveau_gem_prime_import(struct drm_device *dev,
  4263. +                       struct dma_buf *buf)
  4264.  {
  4265.     struct nouveau_drm *drm = nouveau_drm(dev);
  4266. -   struct nouveau_bo *nvbo;
  4267. -   struct reservation_object *robj = attach->dmabuf->resv;
  4268. -   u32 flags = 0;
  4269. +   struct dma_buf_attachment *attach;
  4270. +   struct drm_gem_object *obj;
  4271. +   u32 flags = TTM_PL_FLAG_TT;
  4272. +   struct nouveau_bo *bo;
  4273. +   struct sg_table *sgt;
  4274.     int ret;
  4275.  
  4276. -   flags = TTM_PL_FLAG_TT;
  4277. +   if (buf->ops == &nouveau_gem_prime_dmabuf_ops) {
  4278. +       obj = buf->priv;
  4279.  
  4280. -   ww_mutex_lock(&robj->lock, NULL);
  4281. -   ret = nouveau_bo_new(&drm->client, attach->dmabuf->size, 0, flags, 0, 0,
  4282. -                sg, robj, &nvbo);
  4283. -   ww_mutex_unlock(&robj->lock);
  4284. -   if (ret)
  4285. -       return ERR_PTR(ret);
  4286. +       if (obj->dev == dev) {
  4287. +           /*
  4288. +            * Importing a DMA-BUF exported from our own GEM
  4289. +            * increases the reference count on the GEM itself
  4290. +            * instead of the f_count of the DMA-BUF.
  4291. +            */
  4292. +           drm_gem_object_get(obj);
  4293. +           return obj;
  4294. +       }
  4295. +   }
  4296.  
  4297. -   nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_GART;
  4298. +   attach = dma_buf_attach(buf, dev->dev);
  4299. +   if (IS_ERR(attach))
  4300. +       return ERR_CAST(attach);
  4301.  
  4302. -   /* Initialize the embedded gem-object. We return a single gem-reference
  4303. -    * to the caller, instead of a normal nouveau_bo ttm reference. */
  4304. -   ret = drm_gem_object_init(dev, &nvbo->gem, nvbo->bo.mem.size);
  4305. -   if (ret) {
  4306. -       nouveau_bo_ref(NULL, &nvbo);
  4307. -       return ERR_PTR(-ENOMEM);
  4308. +   get_dma_buf(buf);
  4309. +
  4310. +   sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
  4311. +   if (IS_ERR(sgt)) {
  4312. +       ret = PTR_ERR(sgt);
  4313. +       goto detach;
  4314.     }
  4315.  
  4316. -   return &nvbo->gem;
  4317. +   ww_mutex_lock(&attach->dmabuf->resv->lock, NULL);
  4318. +   ret = nouveau_bo_new(&drm->client, attach->dmabuf->size, 0, flags, 0,
  4319. +                0, sgt, attach->dmabuf->resv, &bo);
  4320. +   ww_mutex_unlock(&attach->dmabuf->resv->lock);
  4321. +   if (ret)
  4322. +       goto unmap;
  4323. +
  4324. +   bo->valid_domains = NOUVEAU_GEM_DOMAIN_GART;
  4325. +
  4326. +   /*
  4327. +    * Initialize the embedded GEM object. We return a single GEM reference
  4328. +    * to the caller, instead of a normal nouveau_bo TTM reference.
  4329. +    */
  4330. +   ret = drm_gem_object_init(dev, &bo->gem, bo->bo.mem.size);
  4331. +   if (ret)
  4332. +       goto unref;
  4333. +
  4334. +   bo->gem.import_attach = attach;
  4335. +
  4336. +   return &bo->gem;
  4337. +
  4338. +unref:
  4339. +   nouveau_bo_ref(NULL, &bo);
  4340. +unmap:
  4341. +   dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
  4342. +detach:
  4343. +   dma_buf_detach(buf, attach);
  4344. +   dma_buf_put(buf);
  4345. +
  4346. +   return ERR_PTR(ret);
  4347.  }
  4348.  
  4349.  int nouveau_gem_prime_pin(struct drm_gem_object *obj)
  4350. @@ -114,3 +251,11 @@ struct reservation_object *nouveau_gem_prime_res_obj(struct drm_gem_object *obj)
  4351.  
  4352.     return nvbo->bo.resv;
  4353.  }
  4354. +
  4355. +struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *obj)
  4356. +{
  4357. +   struct nouveau_bo *nvbo = nouveau_gem_object(obj);
  4358. +   int npages = nvbo->bo.num_pages;
  4359. +
  4360. +   return drm_prime_pages_to_sg(nvbo->bo.ttm->pages, npages);
  4361. +}
  4362. diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
  4363. index 25682ff..c453a8f 100644
  4364. --- a/drivers/gpu/drm/panel/Kconfig
  4365. +++ b/drivers/gpu/drm/panel/Kconfig
  4366. @@ -81,6 +81,15 @@ config DRM_PANEL_LG_LG4573
  4367.       Say Y here if you want to enable support for LG4573 RGB panel.
  4368.       To compile this driver as a module, choose M here.
  4369.  
  4370. +config DRM_PANEL_JDI_LPM062M326A
  4371. +   tristate "JDI LPM062M326A 720x1280 DSI panel"
  4372. +   depends on OF
  4373. +   depends on DRM_MIPI_DSI
  4374. +   depends on BACKLIGHT_CLASS_DEVICE
  4375. +   help
  4376. +     Say Y here if you want to enable support for the JDI LPM062M326A,
  4377. +     used in the Nintendo Switch.
  4378. +
  4379.  config DRM_PANEL_ORISETECH_OTM8009A
  4380.     tristate "Orise Technology otm8009a 480x800 dsi 2dl panel"
  4381.     depends on OF
  4382. diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
  4383. index f26efc1..17e2851 100644
  4384. --- a/drivers/gpu/drm/panel/Makefile
  4385. +++ b/drivers/gpu/drm/panel/Makefile
  4386. @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o
  4387.  obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
  4388.  obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
  4389.  obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
  4390. +obj-$(CONFIG_DRM_PANEL_JDI_LPM062M326A) += panel-jdi-lpm062m326a.o
  4391.  obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
  4392.  obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
  4393.  obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
  4394. diff --git a/drivers/gpu/drm/panel/panel-jdi-lpm062m326a.c b/drivers/gpu/drm/panel/panel-jdi-lpm062m326a.c
  4395. new file mode 100644
  4396. index 0000000..dc46f3b
  4397. --- /dev/null
  4398. +++ b/drivers/gpu/drm/panel/panel-jdi-lpm062m326a.c
  4399. @@ -0,0 +1,475 @@
  4400. +/*
  4401. + * Copyright (C) 2018 SwtcR <swtcr0@gmail.com>
  4402. + *
  4403. + * Based on Sharp ls043t1le01 panel driver by Werner Johansson <werner.johansson@sonymobile.com>
  4404. + *
  4405. + * This program is free software; you can redistribute it and/or modify it
  4406. + * under the terms of the GNU General Public License version 2 as published by
  4407. + * the Free Software Foundation.
  4408. + *
  4409. + * This program is distributed in the hope that it will be useful, but WITHOUT
  4410. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  4411. + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  4412. + * more details.
  4413. + *
  4414. + * You should have received a copy of the GNU General Public License along with
  4415. + * this program.  If not, see <http://www.gnu.org/licenses/>.
  4416. + */
  4417. +
  4418. +#include <linux/backlight.h>
  4419. +#include <linux/gpio/consumer.h>
  4420. +#include <linux/module.h>
  4421. +#include <linux/of.h>
  4422. +#include <linux/regulator/consumer.h>
  4423. +
  4424. +#include <drm/drmP.h>
  4425. +#include <drm/drm_crtc.h>
  4426. +#include <drm/drm_mipi_dsi.h>
  4427. +#include <drm/drm_panel.h>
  4428. +
  4429. +#include <video/mipi_display.h>
  4430. +
  4431. +#define SLEEPY 2
  4432. +
  4433. +struct jdi_panel {
  4434. +   struct drm_panel base;
  4435. +   struct mipi_dsi_device *dsi;
  4436. +
  4437. +   struct backlight_device *backlight;
  4438. +   struct regulator *supply1;
  4439. +   struct regulator *supply2;
  4440. +   struct gpio_desc *reset_gpio;
  4441. +
  4442. +   bool prepared;
  4443. +   bool enabled;
  4444. +
  4445. +   const struct drm_display_mode *mode;
  4446. +};
  4447. +
  4448. +struct init_cmd {
  4449. +   u8 cmd;
  4450. +   int length;
  4451. +   u8 data[0x40];
  4452. +};
  4453. +
  4454. +struct init_cmd init_cmds_0x10[] = {
  4455. +   { 0xb9, 3,    { 0xff, 0x83, 0x94 }},
  4456. +   { 0xbd, 1,    { 0x00 }},
  4457. +   { 0xd8, 0x18, { 0xaa, 0xaa, 0xaa, 0xeb, 0xaa, 0xaa,
  4458. +           0xaa, 0xaa, 0xaa, 0xeb, 0xaa, 0xaa,
  4459. +           0xaa, 0xaa, 0xaa, 0xeb, 0xaa, 0xaa,
  4460. +           0xaa, 0xaa, 0xaa, 0xeb, 0xaa, 0xaa }},
  4461. +   { 0xbd, 1,    { 0x01 }},
  4462. +   { 0xd8, 0x26, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  4463. +           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  4464. +           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  4465. +           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  4466. +           0xff, 0xff, 0xff, 0xff, 0xff, 0xff }},
  4467. +   { 0xbd, 1,    { 0x02 }},
  4468. +   { 0xd8, 0xe,  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  4469. +           0xff, 0xff, 0xff, 0xff, 0xff, 0xff }},
  4470. +   { 0xbd, 1,    { 0x00 }},
  4471. +   { 0xd9, 1,    { 0x06 }},
  4472. +   { 0xb9, 3,    { 0x00, 0x00, 0x00 }},
  4473. +   { 0x00, -1,   { 0x00, }},
  4474. +};
  4475. +
  4476. +static inline struct jdi_panel *to_jdi_panel(struct drm_panel *panel)
  4477. +{
  4478. +   return container_of(panel, struct jdi_panel, base);
  4479. +}
  4480. +
  4481. +static int jdi_panel_init(struct jdi_panel *jdi)
  4482. +{
  4483. +   struct mipi_dsi_device *dsi = jdi->dsi;
  4484. +   int ret;
  4485. +   u8 display_id[3] = {0};
  4486. +   struct init_cmd *init_cmds = NULL;
  4487. +
  4488. +   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
  4489. +
  4490. +   ret = mipi_dsi_set_maximum_return_packet_size(dsi, 3);
  4491. +   if (ret < 0)
  4492. +       return ret;
  4493. +
  4494. +   ret = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_ID, display_id,
  4495. +       sizeof(display_id));
  4496. +   if (ret < 0) {
  4497. +       dev_err(&dsi->dev, "failed to read panel ID: %d\n", ret);
  4498. +   } else {
  4499. +       dev_info(&dsi->dev, "display ID[%d]: %02x %02x %02x\n",
  4500. +           ret, display_id[0], display_id[1], display_id[2]);
  4501. +   }
  4502. +
  4503. +   switch (display_id[0]) {
  4504. +       case 0x10:
  4505. +           dev_info(&dsi->dev, "using init sequence for ID 0x10\n");
  4506. +           init_cmds = init_cmds_0x10;
  4507. +           break;
  4508. +       default:
  4509. +           dev_info(&dsi->dev, "unknown display, no extra init\n");
  4510. +           break;
  4511. +   }
  4512. +
  4513. +   msleep(10 * SLEEPY);
  4514. +
  4515. +   ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
  4516. +   if (ret < 0)
  4517. +       return ret;
  4518. +
  4519. +   while (init_cmds && init_cmds->length != -1) {
  4520. +       ret = mipi_dsi_dcs_write(dsi, init_cmds->cmd, init_cmds->data,
  4521. +                    init_cmds->length);
  4522. +       if (ret < 0)
  4523. +           return ret;
  4524. +       init_cmds++;
  4525. +   }
  4526. +
  4527. +   msleep(180 * SLEEPY);
  4528. +
  4529. +   ret = mipi_dsi_dcs_set_column_address(dsi, 0,
  4530. +               jdi->mode->hdisplay - 1);
  4531. +   if (ret < 0)
  4532. +       return ret;
  4533. +
  4534. +   ret = mipi_dsi_dcs_set_page_address(dsi, 0,
  4535. +               jdi->mode->vdisplay - 1);
  4536. +   if (ret < 0)
  4537. +       return ret;
  4538. +
  4539. +   ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
  4540. +   if (ret < 0)
  4541. +       return ret;
  4542. +
  4543. +//     ret = mipi_dsi_dcs_set_address_mode(dsi, false, false, false,
  4544. +//             false, false, false, false, false);
  4545. +//     if (ret < 0)
  4546. +//         return ret;
  4547. +
  4548. +   ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT);
  4549. +   if (ret < 0)
  4550. +       return ret;
  4551. +
  4552. +   return 0;
  4553. +}
  4554. +
  4555. +static int jdi_panel_on(struct jdi_panel *jdi)
  4556. +{
  4557. +   struct mipi_dsi_device *dsi = jdi->dsi;
  4558. +   int ret;
  4559. +
  4560. +   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
  4561. +
  4562. +   ret = mipi_dsi_dcs_set_display_on(dsi);
  4563. +   if (ret < 0)
  4564. +       return ret;
  4565. +
  4566. +   msleep(20 * SLEEPY);
  4567. +
  4568. +   return 0;
  4569. +}
  4570. +
  4571. +static int jdi_panel_off(struct jdi_panel *jdi)
  4572. +{
  4573. +   struct mipi_dsi_device *dsi = jdi->dsi;
  4574. +   int ret;
  4575. +
  4576. +   dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
  4577. +
  4578. +   ret = mipi_dsi_dcs_set_display_off(dsi);
  4579. +   if (ret < 0)
  4580. +       return ret;
  4581. +
  4582. +   ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
  4583. +   if (ret < 0)
  4584. +       return ret;
  4585. +
  4586. +   return 0;
  4587. +}
  4588. +
  4589. +
  4590. +static int jdi_panel_disable(struct drm_panel *panel)
  4591. +{
  4592. +   struct jdi_panel *jdi = to_jdi_panel(panel);
  4593. +
  4594. +   if (!jdi->enabled)
  4595. +       return 0;
  4596. +
  4597. +   if (jdi->backlight) {
  4598. +       jdi->backlight->props.power = FB_BLANK_POWERDOWN;
  4599. +       backlight_update_status(jdi->backlight);
  4600. +   }
  4601. +
  4602. +   jdi->enabled = false;
  4603. +
  4604. +   return 0;
  4605. +}
  4606. +
  4607. +static int jdi_panel_unprepare(struct drm_panel *panel)
  4608. +{
  4609. +   struct jdi_panel *jdi = to_jdi_panel(panel);
  4610. +   int ret;
  4611. +
  4612. +   if (!jdi->prepared)
  4613. +       return 0;
  4614. +
  4615. +   ret = jdi_panel_off(jdi);
  4616. +   if (ret < 0) {
  4617. +       dev_err(panel->dev, "failed to set panel off: %d\n", ret);
  4618. +       return ret;
  4619. +   }
  4620. +
  4621. +   if (jdi->reset_gpio)
  4622. +       gpiod_set_value(jdi->reset_gpio, 0);
  4623. +
  4624. +   msleep(10 * SLEEPY);
  4625. +   regulator_disable(jdi->supply2);
  4626. +   msleep(10 * SLEEPY);
  4627. +   regulator_disable(jdi->supply1);
  4628. +
  4629. +   jdi->prepared = false;
  4630. +
  4631. +   return 0;
  4632. +}
  4633. +
  4634. +static int jdi_panel_prepare(struct drm_panel *panel)
  4635. +{
  4636. +   struct jdi_panel *jdi = to_jdi_panel(panel);
  4637. +   int ret;
  4638. +
  4639. +   if (jdi->prepared)
  4640. +       return 0;
  4641. +
  4642. +   ret = regulator_enable(jdi->supply1);
  4643. +   if (ret < 0)
  4644. +       return ret;
  4645. +   msleep(10 * SLEEPY);
  4646. +   ret = regulator_enable(jdi->supply2);
  4647. +   if (ret < 0)
  4648. +       goto poweroff1;
  4649. +   msleep(10 * SLEEPY);
  4650. +
  4651. +   if (jdi->reset_gpio) {
  4652. +       gpiod_set_value(jdi->reset_gpio, 0);
  4653. +       msleep(10 * SLEEPY);
  4654. +       gpiod_set_value(jdi->reset_gpio, 1);
  4655. +       msleep(60 * SLEEPY);
  4656. +   }
  4657. +
  4658. +   ret = jdi_panel_init(jdi);
  4659. +   if (ret < 0) {
  4660. +       dev_err(panel->dev, "failed to init panel: %d\n", ret);
  4661. +       goto reset;
  4662. +   }
  4663. +
  4664. +   ret = jdi_panel_on(jdi);
  4665. +   if (ret < 0) {
  4666. +       dev_err(panel->dev, "failed to set panel on: %d\n", ret);
  4667. +       goto reset;
  4668. +   }
  4669. +
  4670. +   jdi->prepared = true;
  4671. +
  4672. +   return 0;
  4673. +
  4674. +reset:
  4675. +   if (jdi->reset_gpio)
  4676. +       gpiod_set_value(jdi->reset_gpio, 0);
  4677. +   regulator_disable(jdi->supply2);
  4678. +poweroff1:
  4679. +   regulator_disable(jdi->supply1);
  4680. +   return ret;
  4681. +}
  4682. +
  4683. +static int jdi_panel_enable(struct drm_panel *panel)
  4684. +{
  4685. +   struct jdi_panel *jdi = to_jdi_panel(panel);
  4686. +
  4687. +   if (jdi->enabled)
  4688. +       return 0;
  4689. +
  4690. +   if (jdi->backlight) {
  4691. +       jdi->backlight->props.power = FB_BLANK_UNBLANK;
  4692. +       backlight_update_status(jdi->backlight);
  4693. +   }
  4694. +
  4695. +   jdi->enabled = true;
  4696. +
  4697. +   return 0;
  4698. +}
  4699. +
  4700. +static const struct drm_display_mode default_mode = {
  4701. +   .clock = 78000,
  4702. +   .hdisplay = 720,
  4703. +   .hsync_start = 720 + 136,
  4704. +   .hsync_end = 720 + 136 + 72,
  4705. +   .htotal = 720 + 136 + 72 + 72,
  4706. +   .vdisplay = 1280,
  4707. +   .vsync_start = 1280 + 10,
  4708. +   .vsync_end = 1280 + 10 + 2,
  4709. +   .vtotal = 1280 + 10 + 1 + 9,
  4710. +   .vrefresh = 60,
  4711. +};
  4712. +
  4713. +static int jdi_panel_get_modes(struct drm_panel *panel)
  4714. +{
  4715. +   struct drm_display_mode *mode;
  4716. +
  4717. +   mode = drm_mode_duplicate(panel->drm, &default_mode);
  4718. +   if (!mode) {
  4719. +       dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
  4720. +               default_mode.hdisplay, default_mode.vdisplay,
  4721. +               default_mode.vrefresh);
  4722. +       return -ENOMEM;
  4723. +   }
  4724. +
  4725. +   drm_mode_set_name(mode);
  4726. +
  4727. +   drm_mode_probed_add(panel->connector, mode);
  4728. +
  4729. +   panel->connector->display_info.width_mm = 77;
  4730. +   panel->connector->display_info.height_mm = 137;
  4731. +
  4732. +   return 1;
  4733. +}
  4734. +
  4735. +static const struct drm_panel_funcs jdi_panel_funcs = {
  4736. +   .disable = jdi_panel_disable,
  4737. +   .unprepare = jdi_panel_unprepare,
  4738. +   .prepare = jdi_panel_prepare,
  4739. +   .enable = jdi_panel_enable,
  4740. +   .get_modes = jdi_panel_get_modes,
  4741. +};
  4742. +
  4743. +static int jdi_panel_add(struct jdi_panel *jdi)
  4744. +{
  4745. +   struct device *dev = &jdi->dsi->dev;
  4746. +   struct device_node *np;
  4747. +   int ret;
  4748. +
  4749. +   jdi->mode = &default_mode;
  4750. +
  4751. +   jdi->supply1 = devm_regulator_get(dev, "vdd1");
  4752. +   if (IS_ERR(jdi->supply1))
  4753. +       return PTR_ERR(jdi->supply1);
  4754. +
  4755. +   jdi->supply2 = devm_regulator_get(dev, "vdd2");
  4756. +   if (IS_ERR(jdi->supply2))
  4757. +       return PTR_ERR(jdi->supply2);
  4758. +
  4759. +   jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
  4760. +   if (IS_ERR(jdi->reset_gpio)) {
  4761. +       dev_err(dev, "cannot get reset-gpios %ld\n",
  4762. +           PTR_ERR(jdi->reset_gpio));
  4763. +       jdi->reset_gpio = NULL;
  4764. +   } else {
  4765. +       gpiod_set_value(jdi->reset_gpio, 0);
  4766. +   }
  4767. +
  4768. +   np = of_parse_phandle(dev->of_node, "backlight", 0);
  4769. +   if (np) {
  4770. +       jdi->backlight = of_find_backlight_by_node(np);
  4771. +       of_node_put(np);
  4772. +
  4773. +       if (!jdi->backlight)
  4774. +           return -EPROBE_DEFER;
  4775. +   }
  4776. +
  4777. +   drm_panel_init(&jdi->base);
  4778. +   jdi->base.funcs = &jdi_panel_funcs;
  4779. +   jdi->base.dev = &jdi->dsi->dev;
  4780. +
  4781. +   ret = drm_panel_add(&jdi->base);
  4782. +   if (ret < 0)
  4783. +       goto put_backlight;
  4784. +
  4785. +   return 0;
  4786. +
  4787. +put_backlight:
  4788. +   if (jdi->backlight)
  4789. +       put_device(&jdi->backlight->dev);
  4790. +
  4791. +   return ret;
  4792. +}
  4793. +
  4794. +static void jdi_panel_del(struct jdi_panel *jdi)
  4795. +{
  4796. +   if (jdi->base.dev)
  4797. +       drm_panel_remove(&jdi->base);
  4798. +
  4799. +   if (jdi->backlight)
  4800. +       put_device(&jdi->backlight->dev);
  4801. +}
  4802. +
  4803. +static int jdi_panel_probe(struct mipi_dsi_device *dsi)
  4804. +{
  4805. +   struct jdi_panel *jdi;
  4806. +   int ret;
  4807. +
  4808. +   dsi->lanes = 4;
  4809. +   dsi->format = MIPI_DSI_FMT_RGB888;
  4810. +   dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
  4811. +           MIPI_DSI_CLOCK_NON_CONTINUOUS |
  4812. +           MIPI_DSI_MODE_EOT_PACKET;
  4813. +
  4814. +   jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL);
  4815. +   if (!jdi)
  4816. +       return -ENOMEM;
  4817. +
  4818. +   mipi_dsi_set_drvdata(dsi, jdi);
  4819. +
  4820. +   jdi->dsi = dsi;
  4821. +
  4822. +   ret = jdi_panel_add(jdi);
  4823. +   if (ret < 0)
  4824. +       return ret;
  4825. +
  4826. +   return mipi_dsi_attach(dsi);
  4827. +}
  4828. +
  4829. +static int jdi_panel_remove(struct mipi_dsi_device *dsi)
  4830. +{
  4831. +   struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
  4832. +   int ret;
  4833. +
  4834. +   ret = jdi_panel_disable(&jdi->base);
  4835. +   if (ret < 0)
  4836. +       dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
  4837. +
  4838. +   ret = mipi_dsi_detach(dsi);
  4839. +   if (ret < 0)
  4840. +       dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
  4841. +
  4842. +   drm_panel_detach(&jdi->base);
  4843. +   jdi_panel_del(jdi);
  4844. +
  4845. +   return 0;
  4846. +}
  4847. +
  4848. +static void jdi_panel_shutdown(struct mipi_dsi_device *dsi)
  4849. +{
  4850. +   struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
  4851. +
  4852. +   jdi_panel_disable(&jdi->base);
  4853. +}
  4854. +
  4855. +static const struct of_device_id jdi_of_match[] = {
  4856. +   { .compatible = "jdi,lpm062m326a", },
  4857. +   { }
  4858. +};
  4859. +MODULE_DEVICE_TABLE(of, jdi_of_match);
  4860. +
  4861. +static struct mipi_dsi_driver jdi_panel_driver = {
  4862. +   .driver = {
  4863. +       .name = "panel-jdi-lpm062m326a",
  4864. +       .of_match_table = jdi_of_match,
  4865. +   },
  4866. +   .probe = jdi_panel_probe,
  4867. +   .remove = jdi_panel_remove,
  4868. +   .shutdown = jdi_panel_shutdown,
  4869. +};
  4870. +module_mipi_dsi_driver(jdi_panel_driver);
  4871. +
  4872. +MODULE_AUTHOR("SwtcR <swtcr0@gmail.com>");
  4873. +MODULE_DESCRIPTION("JDI LPM062M326A (720x1280) panel driver");
  4874. +MODULE_LICENSE("GPL v2");
  4875. diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
  4876. index 7afe2f6..9c4bb51 100644
  4877. --- a/drivers/gpu/drm/tegra/drm.c
  4878. +++ b/drivers/gpu/drm/tegra/drm.c
  4879. @@ -11,6 +11,7 @@
  4880.  #include <linux/host1x.h>
  4881.  #include <linux/idr.h>
  4882.  #include <linux/iommu.h>
  4883. +#include <linux/sync_file.h>
  4884.  
  4885.  #include <drm/drm_atomic.h>
  4886.  #include <drm/drm_atomic_helper.h>
  4887. @@ -347,6 +348,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4888.              struct drm_tegra_submit *args, struct drm_device *drm,
  4889.              struct drm_file *file)
  4890.  {
  4891. +   struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
  4892.     unsigned int num_cmdbufs = args->num_cmdbufs;
  4893.     unsigned int num_relocs = args->num_relocs;
  4894.     unsigned int num_waitchks = args->num_waitchks;
  4895. @@ -355,7 +357,6 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4896.     struct drm_tegra_waitchk __user *user_waitchks;
  4897.     struct drm_tegra_syncpt __user *user_syncpt;
  4898.     struct drm_tegra_syncpt syncpt;
  4899. -   struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
  4900.     struct drm_gem_object **refs;
  4901.     struct host1x_syncpt *sp;
  4902.     struct host1x_job *job;
  4903. @@ -375,6 +376,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4904.     if (args->num_waitchks != 0)
  4905.         return -EINVAL;
  4906.  
  4907. +   /* Check for unrecognized flags */
  4908. +   if (args->flags & ~DRM_TEGRA_SUBMIT_FLAGS)
  4909. +       return -EINVAL;
  4910. +
  4911.     job = host1x_job_alloc(context->channel, args->num_cmdbufs,
  4912.                    args->num_relocs, args->num_waitchks);
  4913.     if (!job)
  4914. @@ -386,6 +391,14 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4915.     job->class = context->client->base.class;
  4916.     job->serialize = true;
  4917.  
  4918. +   if (args->flags & DRM_TEGRA_SUBMIT_WAIT_FENCE_FD) {
  4919. +       job->prefence = sync_file_get_fence(args->fence);
  4920. +       if (!job->prefence) {
  4921. +           err = -ENOENT;
  4922. +           goto put;
  4923. +       }
  4924. +   }
  4925. +
  4926.     /*
  4927.      * Track referenced BOs so that they can be unreferenced after the
  4928.      * submission is complete.
  4929. @@ -409,7 +422,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4930.  
  4931.         if (copy_from_user(&cmdbuf, user_cmdbufs, sizeof(cmdbuf))) {
  4932.             err = -EFAULT;
  4933. -           goto fail;
  4934. +           goto put_bos;
  4935.         }
  4936.  
  4937.         /*
  4938. @@ -418,13 +431,13 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4939.          */
  4940.         if (cmdbuf.words > CDMA_GATHER_FETCHES_MAX_NB) {
  4941.             err = -EINVAL;
  4942. -           goto fail;
  4943. +           goto put_bos;
  4944.         }
  4945.  
  4946.         bo = host1x_bo_lookup(file, cmdbuf.handle);
  4947.         if (!bo) {
  4948.             err = -ENOENT;
  4949. -           goto fail;
  4950. +           goto put_bos;
  4951.         }
  4952.  
  4953.         offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32);
  4954. @@ -438,7 +451,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4955.          */
  4956.         if (offset & 3 || offset >= obj->gem.size) {
  4957.             err = -EINVAL;
  4958. -           goto fail;
  4959. +           goto put_bos;
  4960.         }
  4961.  
  4962.         host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset);
  4963. @@ -455,7 +468,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4964.                           &user_relocs[num_relocs], drm,
  4965.                           file);
  4966.         if (err < 0)
  4967. -           goto fail;
  4968. +           goto put_bos;
  4969.  
  4970.         reloc = &job->relocarray[num_relocs];
  4971.         obj = host1x_to_tegra_bo(reloc->cmdbuf.bo);
  4972. @@ -469,7 +482,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4973.         if (reloc->cmdbuf.offset & 3 ||
  4974.             reloc->cmdbuf.offset >= obj->gem.size) {
  4975.             err = -EINVAL;
  4976. -           goto fail;
  4977. +           goto put_bos;
  4978.         }
  4979.  
  4980.         obj = host1x_to_tegra_bo(reloc->target.bo);
  4981. @@ -477,7 +490,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4982.  
  4983.         if (reloc->target.offset >= obj->gem.size) {
  4984.             err = -EINVAL;
  4985. -           goto fail;
  4986. +           goto put_bos;
  4987.         }
  4988.     }
  4989.  
  4990. @@ -489,7 +502,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  4991.         err = host1x_waitchk_copy_from_user(
  4992.             wait, &user_waitchks[num_waitchks], file);
  4993.         if (err < 0)
  4994. -           goto fail;
  4995. +           goto put_bos;
  4996.  
  4997.         obj = host1x_to_tegra_bo(wait->bo);
  4998.         refs[num_refs++] = &obj->gem;
  4999. @@ -501,20 +514,20 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  5000.         if (wait->offset & 3 ||
  5001.             wait->offset >= obj->gem.size) {
  5002.             err = -EINVAL;
  5003. -           goto fail;
  5004. +           goto put_bos;
  5005.         }
  5006.     }
  5007.  
  5008.     if (copy_from_user(&syncpt, user_syncpt, sizeof(syncpt))) {
  5009.         err = -EFAULT;
  5010. -       goto fail;
  5011. +       goto put_bos;
  5012.     }
  5013.  
  5014.     /* check whether syncpoint ID is valid */
  5015.     sp = host1x_syncpt_get(host1x, syncpt.id);
  5016.     if (!sp) {
  5017.         err = -ENOENT;
  5018. -       goto fail;
  5019. +       goto put_bos;
  5020.     }
  5021.  
  5022.     job->is_addr_reg = context->client->ops->is_addr_reg;
  5023. @@ -528,23 +541,60 @@ int tegra_drm_submit(struct tegra_drm_context *context,
  5024.  
  5025.     err = host1x_job_pin(job, context->client->base.dev);
  5026.     if (err)
  5027. -       goto fail;
  5028. +       goto put_bos;
  5029.  
  5030.     err = host1x_job_submit(job);
  5031.     if (err) {
  5032.         host1x_job_unpin(job);
  5033. -       goto fail;
  5034. +       goto put_bos;
  5035.     }
  5036.  
  5037. -   args->fence = job->syncpt_end;
  5038. +   if (args->flags & DRM_TEGRA_SUBMIT_CREATE_FENCE_FD) {
  5039. +       struct host1x_syncpt *syncpt;
  5040. +       struct dma_fence *fence;
  5041. +       struct sync_file *file;
  5042. +
  5043. +       syncpt = host1x_syncpt_get(host1x, job->syncpt_id);
  5044. +       if (!syncpt) {
  5045. +           err = -EINVAL;
  5046. +           goto put_bos;
  5047. +       }
  5048.  
  5049. -fail:
  5050. +       fence = host1x_fence_create(host1x, syncpt, job->syncpt_end);
  5051. +       if (!fence) {
  5052. +           err = -ENOMEM;
  5053. +           goto put_bos;
  5054. +       }
  5055. +
  5056. +       file = sync_file_create(fence);
  5057. +       if (!file) {
  5058. +           dma_fence_put(fence);
  5059. +           err = -ENOMEM;
  5060. +           goto put_bos;
  5061. +       }
  5062. +
  5063. +       err = get_unused_fd_flags(O_CLOEXEC);
  5064. +       if (err < 0) {
  5065. +           dma_fence_put(fence);
  5066. +           goto put_bos;
  5067. +       }
  5068. +
  5069. +       fd_install(err, file->file);
  5070. +       args->fence = err;
  5071. +   } else {
  5072. +       args->fence = job->syncpt_end;
  5073. +   }
  5074. +
  5075. +put_bos:
  5076.     while (num_refs--)
  5077.         drm_gem_object_put_unlocked(refs[num_refs]);
  5078.  
  5079.     kfree(refs);
  5080.  
  5081.  put:
  5082. +   if (job->prefence)
  5083. +       dma_fence_put(job->prefence);
  5084. +
  5085.     host1x_job_put(job);
  5086.     return err;
  5087.  }
  5088. diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
  5089. index 87c5d89..0ff4c39 100644
  5090. --- a/drivers/gpu/drm/tegra/dsi.c
  5091. +++ b/drivers/gpu/drm/tegra/dsi.c
  5092. @@ -321,7 +321,7 @@ static const u32 pkt_seq_video_non_burst_sync_pulses[NUM_PKT_SEQ] = {
  5093.  /*
  5094.   * non-burst mode with sync events
  5095.   */
  5096. -static const u32 pkt_seq_video_non_burst_sync_events[NUM_PKT_SEQ] = {
  5097. +static const u32 pkt_seq_video_non_burst_sync_events_eotp[NUM_PKT_SEQ] = {
  5098.     [ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
  5099.            PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
  5100.            PKT_LP,
  5101. @@ -348,6 +348,32 @@ static const u32 pkt_seq_video_non_burst_sync_events[NUM_PKT_SEQ] = {
  5102.     [11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
  5103.  };
  5104.  
  5105. +/*
  5106. + * non-burst mode with sync events
  5107. + */
  5108. +static const u32 pkt_seq_video_non_burst_sync_events[NUM_PKT_SEQ] = {
  5109. +   [ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
  5110. +          PKT_LP,
  5111. +   [ 1] = 0,
  5112. +   [ 2] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
  5113. +          PKT_LP,
  5114. +   [ 3] = 0,
  5115. +   [ 4] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
  5116. +          PKT_LP,
  5117. +   [ 5] = 0,
  5118. +   [ 6] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
  5119. +          PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(2) |
  5120. +          PKT_ID2(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN2(3),
  5121. +   [ 7] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
  5122. +   [ 8] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
  5123. +          PKT_LP,
  5124. +   [ 9] = 0,
  5125. +   [10] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
  5126. +          PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(2) |
  5127. +          PKT_ID2(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN2(3),
  5128. +   [11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
  5129. +};
  5130. +
  5131.  static const u32 pkt_seq_command_mode[NUM_PKT_SEQ] = {
  5132.     [ 0] = 0,
  5133.     [ 1] = 0,
  5134. @@ -505,8 +531,13 @@ static void tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
  5135.         DRM_DEBUG_KMS("Non-burst video mode with sync pulses\n");
  5136.         pkt_seq = pkt_seq_video_non_burst_sync_pulses;
  5137.     } else if (dsi->flags & MIPI_DSI_MODE_VIDEO) {
  5138. -       DRM_DEBUG_KMS("Non-burst video mode with sync events\n");
  5139. -       pkt_seq = pkt_seq_video_non_burst_sync_events;
  5140. +       if (!(dsi->flags & MIPI_DSI_MODE_EOT_PACKET)) {
  5141. +           DRM_DEBUG_KMS("Non-burst video mode with sync events and EOTp\n");
  5142. +           pkt_seq = pkt_seq_video_non_burst_sync_events_eotp;
  5143. +       } else {
  5144. +           DRM_DEBUG_KMS("Non-burst video mode with sync events\n");
  5145. +           pkt_seq = pkt_seq_video_non_burst_sync_events;
  5146. +       }
  5147.     } else {
  5148.         DRM_DEBUG_KMS("Command mode\n");
  5149.         pkt_seq = pkt_seq_command_mode;
  5150. diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
  5151. index 7d2a955..c472578 100644
  5152. --- a/drivers/gpu/drm/tegra/sor.c
  5153. +++ b/drivers/gpu/drm/tegra/sor.c
  5154. @@ -342,7 +342,7 @@ struct tegra_sor {
  5155.     struct drm_info_list *debugfs_files;
  5156.  
  5157.     const struct tegra_sor_ops *ops;
  5158. -   enum tegra_io_pad pad;
  5159. +   unsigned int pad;
  5160.  
  5161.     /* for HDMI 2.0 */
  5162.     struct tegra_sor_hdmi_settings *settings;
  5163. diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
  5164. index 9191632..e41032e 100644
  5165. --- a/drivers/gpu/host1x/Kconfig
  5166. +++ b/drivers/gpu/host1x/Kconfig
  5167. @@ -1,6 +1,7 @@
  5168.  config TEGRA_HOST1X
  5169.     tristate "NVIDIA Tegra host1x driver"
  5170.     depends on ARCH_TEGRA || (ARM && COMPILE_TEST)
  5171. +   select DMA_SHARED_BUFFER
  5172.     select IOMMU_IOVA if IOMMU_SUPPORT
  5173.     help
  5174.       Driver for the NVIDIA Tegra host1x hardware.
  5175. diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
  5176. index b92016c..ae3a6ed 100644
  5177. --- a/drivers/gpu/host1x/Makefile
  5178. +++ b/drivers/gpu/host1x/Makefile
  5179. @@ -9,6 +9,7 @@ host1x-y = \
  5180.     job.o \
  5181.     debug.o \
  5182.     mipi.o \
  5183. +   fence.o \
  5184.     hw/host1x01.o \
  5185.     hw/host1x02.o \
  5186.     hw/host1x04.o \
  5187. diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
  5188. index 43e9fab..c9071c9 100644
  5189. --- a/drivers/gpu/host1x/dev.h
  5190. +++ b/drivers/gpu/host1x/dev.h
  5191. @@ -1,5 +1,5 @@
  5192.  /*
  5193. - * Copyright (c) 2012-2015, NVIDIA Corporation.
  5194. + * Copyright (C) 2012-2016 NVIDIA CORPORATION.  All rights reserved.
  5195.   *
  5196.   * This program is free software; you can redistribute it and/or modify it
  5197.   * under the terms and conditions of the GNU General Public License,
  5198. @@ -42,6 +42,7 @@ struct host1x_channel_ops {
  5199.     int (*init)(struct host1x_channel *channel, struct host1x *host,
  5200.             unsigned int id);
  5201.     int (*submit)(struct host1x_job *job);
  5202. +   void (*push_wait)(struct host1x_channel *ch, u32 id, u32 thresh);
  5203.  };
  5204.  
  5205.  struct host1x_cdma_ops {
  5206. @@ -117,6 +118,8 @@ struct host1x {
  5207.     struct clk *clk;
  5208.     struct reset_control *rst;
  5209.  
  5210. +   u64 fence_ctx_base;
  5211. +
  5212.     struct iommu_group *group;
  5213.     struct iommu_domain *domain;
  5214.     struct iova_domain iova;
  5215. @@ -250,6 +253,13 @@ static inline int host1x_hw_channel_submit(struct host1x *host,
  5216.     return host->channel_op->submit(job);
  5217.  }
  5218.  
  5219. +static inline void host1x_hw_channel_push_wait(struct host1x *host,
  5220. +                          struct host1x_channel *channel,
  5221. +                          u32 id, u32 thresh)
  5222. +{
  5223. +   host->channel_op->push_wait(channel, id, thresh);
  5224. +}
  5225. +
  5226.  static inline void host1x_hw_cdma_start(struct host1x *host,
  5227.                     struct host1x_cdma *cdma)
  5228.  {
  5229. diff --git a/drivers/gpu/host1x/fence.c b/drivers/gpu/host1x/fence.c
  5230. new file mode 100644
  5231. index 0000000..3b05662
  5232. --- /dev/null
  5233. +++ b/drivers/gpu/host1x/fence.c
  5234. @@ -0,0 +1,202 @@
  5235. +/*
  5236. + * Copyright (C) 2016 NVIDIA CORPORATION.  All rights reserved.
  5237. + *
  5238. + * This program is free software; you can redistribute it and/or modify it
  5239. + * under the terms and conditions of the GNU General Public License,
  5240. + * version 2, as published by the Free Software Foundation.
  5241. + *
  5242. + * This program is distributed in the hope it will be useful, but WITHOUT
  5243. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  5244. + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  5245. + * more details.
  5246. + *
  5247. + * You should have received a copy of the GNU General Public License
  5248. + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  5249. + */
  5250. +
  5251. +#include <linux/dma-fence.h>
  5252. +#include <linux/dma-fence-array.h>
  5253. +#include <linux/slab.h>
  5254. +
  5255. +#include "fence.h"
  5256. +#include "intr.h"
  5257. +#include "syncpt.h"
  5258. +#include "cdma.h"
  5259. +#include "channel.h"
  5260. +#include "dev.h"
  5261. +
  5262. +struct host1x_fence {
  5263. +   struct dma_fence base;
  5264. +   spinlock_t lock;
  5265. +
  5266. +   struct host1x_syncpt *syncpt;
  5267. +   u32 threshold;
  5268. +
  5269. +   struct host1x *host;
  5270. +   void *waiter;
  5271. +
  5272. +   char timeline_name[10];
  5273. +};
  5274. +
  5275. +static inline struct host1x_fence *to_host1x_fence(struct dma_fence *fence)
  5276. +{
  5277. +   return (struct host1x_fence *)fence;
  5278. +}
  5279. +
  5280. +static const char *host1x_fence_get_driver_name(struct dma_fence *fence)
  5281. +{
  5282. +   return "host1x";
  5283. +}
  5284. +
  5285. +static const char *host1x_fence_get_timeline_name(struct dma_fence *fence)
  5286. +{
  5287. +   struct host1x_fence *f = to_host1x_fence(fence);
  5288. +
  5289. +   return f->timeline_name;
  5290. +}
  5291. +
  5292. +static bool host1x_fence_enable_signaling(struct dma_fence *fence)
  5293. +{
  5294. +   struct host1x_fence *f = to_host1x_fence(fence);
  5295. +
  5296. +   if (host1x_syncpt_is_expired(f->syncpt, f->threshold))
  5297. +       return false;
  5298. +
  5299. +   return true;
  5300. +}
  5301. +
  5302. +static bool host1x_fence_signaled(struct dma_fence *fence)
  5303. +{
  5304. +   struct host1x_fence *f = to_host1x_fence(fence);
  5305. +
  5306. +   return host1x_syncpt_is_expired(f->syncpt, f->threshold);
  5307. +}
  5308. +
  5309. +static void host1x_fence_release(struct dma_fence *fence)
  5310. +{
  5311. +   struct host1x_fence *f = to_host1x_fence(fence);
  5312. +
  5313. +   if (f->waiter)
  5314. +       host1x_intr_put_ref(f->host, f->syncpt->id, f->waiter);
  5315. +
  5316. +   kfree(f);
  5317. +}
  5318. +
  5319. +const struct dma_fence_ops host1x_fence_ops = {
  5320. +   .get_driver_name = host1x_fence_get_driver_name,
  5321. +   .get_timeline_name = host1x_fence_get_timeline_name,
  5322. +   .enable_signaling = host1x_fence_enable_signaling,
  5323. +   .signaled = host1x_fence_signaled,
  5324. +   .wait = dma_fence_default_wait,
  5325. +   .release = host1x_fence_release,
  5326. +};
  5327. +
  5328. +static void host1x_fence_wait_single(struct host1x_fence *f,
  5329. +                    struct host1x *host,
  5330. +                    struct host1x_channel *ch)
  5331. +{
  5332. +   if (host1x_syncpt_is_expired(f->syncpt, f->threshold))
  5333. +       return;
  5334. +
  5335. +   host1x_hw_channel_push_wait(host, ch, f->syncpt->id, f->threshold);
  5336. +}
  5337. +
  5338. +/**
  5339. + * host1x_fence_is_waitable() - Check if DMA fence can be waited by hardware
  5340. + * @fence: DMA fence
  5341. + *
  5342. + * Check is @fence is only backed by Host1x syncpoints and can therefore be
  5343. + * waited using only hardware.
  5344. + */
  5345. +bool host1x_fence_is_waitable(struct dma_fence *fence)
  5346. +{
  5347. +   struct dma_fence_array *array;
  5348. +   int i;
  5349. +
  5350. +   array = to_dma_fence_array(fence);
  5351. +   if (!array)
  5352. +       return fence->ops == &host1x_fence_ops;
  5353. +
  5354. +   for (i = 0; i < array->num_fences; ++i) {
  5355. +       if (array->fences[i]->ops != &host1x_fence_ops)
  5356. +           return false;
  5357. +   }
  5358. +
  5359. +   return true;
  5360. +}
  5361. +
  5362. +/**
  5363. + * host1x_fence_wait() - Insert waits for fence into channel
  5364. + * @fence: DMA fence
  5365. + * @host: Host1x
  5366. + * @ch: Host1x channel
  5367. + *
  5368. + * Inserts wait commands into Host1x channel fences in @fence.
  5369. + * in @fence. @fence must only consist of syncpoint-backed fences.
  5370. + *
  5371. + * Return: 0 on success, -errno otherwise.
  5372. + */
  5373. +int host1x_fence_wait(struct dma_fence *fence, struct host1x *host,
  5374. +             struct host1x_channel *ch)
  5375. +{
  5376. +   struct dma_fence_array *array;
  5377. +   int i = 0;
  5378. +
  5379. +   if (!host1x_fence_is_waitable(fence))
  5380. +       return -EINVAL;
  5381. +
  5382. +   array = to_dma_fence_array(fence);
  5383. +   if (!array) {
  5384. +       host1x_fence_wait_single(to_host1x_fence(fence), host, ch);
  5385. +       return 0;
  5386. +   }
  5387. +
  5388. +   for (i = 0; i < array->num_fences; ++i) {
  5389. +       host1x_fence_wait_single(to_host1x_fence(array->fences[i]),
  5390. +                    host, ch);
  5391. +   }
  5392. +
  5393. +   return 0;
  5394. +}
  5395. +
  5396. +struct dma_fence *host1x_fence_create(struct host1x *host,
  5397. +                     struct host1x_syncpt *syncpt,
  5398. +                     u32 threshold)
  5399. +{
  5400. +   struct host1x_waitlist *waiter;
  5401. +   struct host1x_fence *f;
  5402. +   int err;
  5403. +
  5404. +   f = kzalloc(sizeof(*f), GFP_KERNEL);
  5405. +   if (!f)
  5406. +       return NULL;
  5407. +
  5408. +   waiter = kzalloc(sizeof(*waiter), GFP_KERNEL);
  5409. +   if (!waiter) {
  5410. +       kfree(f);
  5411. +       return NULL;
  5412. +   }
  5413. +
  5414. +   f->host = host;
  5415. +   f->syncpt = syncpt;
  5416. +   f->threshold = threshold;
  5417. +   f->waiter = NULL;
  5418. +   snprintf(f->timeline_name, ARRAY_SIZE(f->timeline_name),
  5419. +        "%d", syncpt->id);
  5420. +
  5421. +   spin_lock_init(&f->lock);
  5422. +   dma_fence_init(&f->base, &host1x_fence_ops, &f->lock,
  5423. +              host->fence_ctx_base + syncpt->id, threshold);
  5424. +
  5425. +   err = host1x_intr_add_action(f->host, f->syncpt->id, f->threshold,
  5426. +                    HOST1X_INTR_ACTION_SIGNAL_FENCE, f,
  5427. +                    waiter, &f->waiter);
  5428. +   if (err) {
  5429. +       kfree(waiter);
  5430. +       dma_fence_put((struct dma_fence *)f);
  5431. +       return NULL;
  5432. +   }
  5433. +
  5434. +   return (struct dma_fence *)f;
  5435. +}
  5436. +EXPORT_SYMBOL(host1x_fence_create);
  5437. diff --git a/drivers/gpu/host1x/fence.h b/drivers/gpu/host1x/fence.h
  5438. new file mode 100644
  5439. index 0000000..5725c95
  5440. --- /dev/null
  5441. +++ b/drivers/gpu/host1x/fence.h
  5442. @@ -0,0 +1,28 @@
  5443. +/*
  5444. + * Copyright (C) 2016 NVIDIA CORPORATION.  All rights reserved.
  5445. + *
  5446. + * This program is free software; you can redistribute it and/or modify it
  5447. + * under the terms and conditions of the GNU General Public License,
  5448. + * version 2, as published by the Free Software Foundation.
  5449. + *
  5450. + * This program is distributed in the hope it will be useful, but WITHOUT
  5451. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  5452. + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  5453. + * more details.
  5454. + *
  5455. + * You should have received a copy of the GNU General Public License
  5456. + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  5457. + */
  5458. +
  5459. +#ifndef __HOST1X_FENCE_H
  5460. +#define __HOST1X_FENCE_H
  5461. +
  5462. +struct host1x;
  5463. +struct host1x_channel;
  5464. +struct dma_fence;
  5465. +
  5466. +bool host1x_fence_is_waitable(struct dma_fence *fence);
  5467. +int host1x_fence_wait(struct dma_fence *fence, struct host1x *host,
  5468. +             struct host1x_channel *ch);
  5469. +
  5470. +#endif
  5471. diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c
  5472. index 9af7587..d438289 100644
  5473. --- a/drivers/gpu/host1x/hw/channel_hw.c
  5474. +++ b/drivers/gpu/host1x/hw/channel_hw.c
  5475. @@ -1,7 +1,7 @@
  5476.  /*
  5477.   * Tegra host1x Channel
  5478.   *
  5479. - * Copyright (c) 2010-2013, NVIDIA Corporation.
  5480. + * Copyright (C) 2010-2016 NVIDIA CORPORATION.  All rights reserved.
  5481.   *
  5482.   * This program is free software; you can redistribute it and/or modify it
  5483.   * under the terms and conditions of the GNU General Public License,
  5484. @@ -16,6 +16,7 @@
  5485.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  5486.   */
  5487.  
  5488. +#include <linux/dma-fence.h>
  5489.  #include <linux/host1x.h>
  5490.  #include <linux/slab.h>
  5491.  
  5492. @@ -23,6 +24,7 @@
  5493.  
  5494.  #include "../channel.h"
  5495.  #include "../dev.h"
  5496. +#include "../fence.h"
  5497.  #include "../intr.h"
  5498.  #include "../job.h"
  5499.  
  5500. @@ -68,11 +70,26 @@ static void submit_gathers(struct host1x_job *job)
  5501.         u32 op1 = host1x_opcode_gather(g->words);
  5502.         u32 op2 = g->base + g->offset;
  5503.  
  5504. +       /* add a setclass for modules that require it */
  5505. +       if (job->class)
  5506. +           host1x_cdma_push(cdma,
  5507. +                host1x_opcode_setclass(job->class, 0, 0),
  5508. +                HOST1X_OPCODE_NOP);
  5509. +
  5510.         trace_write_gather(cdma, g->bo, g->offset, op1 & 0xffff);
  5511.         host1x_cdma_push(cdma, op1, op2);
  5512.     }
  5513.  }
  5514.  
  5515. +static void channel_push_wait(struct host1x_channel *channel,
  5516. +                u32 id, u32 thresh)
  5517. +{
  5518. +   host1x_cdma_push(&channel->cdma,
  5519. +            host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
  5520. +               host1x_uclass_wait_syncpt_r(), 1),
  5521. +            host1x_class_host_wait_syncpt(id, thresh));
  5522. +}
  5523. +
  5524.  static inline void synchronize_syncpt_base(struct host1x_job *job)
  5525.  {
  5526.     struct host1x *host = dev_get_drvdata(job->channel->dev->parent);
  5527. @@ -110,6 +127,16 @@ static int channel_submit(struct host1x_job *job)
  5528.     /* before error checks, return current max */
  5529.     prev_max = job->syncpt_end = host1x_syncpt_read_max(sp);
  5530.  
  5531. +   if (job->prefence) {
  5532. +       if (host1x_fence_is_waitable(job->prefence)) {
  5533. +           host1x_fence_wait(job->prefence, host, job->channel);
  5534. +       } else {
  5535. +           err = dma_fence_wait(job->prefence, true);
  5536. +           if (err)
  5537. +               goto error;
  5538. +       }
  5539. +   }
  5540. +
  5541.     /* get submit lock */
  5542.     err = mutex_lock_interruptible(&ch->submitlock);
  5543.     if (err)
  5544. @@ -151,12 +178,6 @@ static int channel_submit(struct host1x_job *job)
  5545.  
  5546.     job->syncpt_end = syncval;
  5547.  
  5548. -   /* add a setclass for modules that require it */
  5549. -   if (job->class)
  5550. -       host1x_cdma_push(&ch->cdma,
  5551. -                host1x_opcode_setclass(job->class, 0, 0),
  5552. -                HOST1X_OPCODE_NOP);
  5553. -
  5554.     submit_gathers(job);
  5555.  
  5556.     /* end CDMA submit & stash pinned hMems into sync queue */
  5557. @@ -212,4 +233,5 @@ static int host1x_channel_init(struct host1x_channel *ch, struct host1x *dev,
  5558.  static const struct host1x_channel_ops host1x_channel_ops = {
  5559.     .init = host1x_channel_init,
  5560.     .submit = channel_submit,
  5561. +   .push_wait = channel_push_wait
  5562.  };
  5563. diff --git a/drivers/gpu/host1x/intr.c b/drivers/gpu/host1x/intr.c
  5564. index 8b4fad0..b3d5128 100644
  5565. --- a/drivers/gpu/host1x/intr.c
  5566. +++ b/drivers/gpu/host1x/intr.c
  5567. @@ -1,7 +1,7 @@
  5568.  /*
  5569.   * Tegra host1x Interrupt Management
  5570.   *
  5571. - * Copyright (c) 2010-2013, NVIDIA Corporation.
  5572. + * Copyright (C) 2010-2016 NVIDIA CORPORATION.  All rights reserved.
  5573.   *
  5574.   * This program is free software; you can redistribute it and/or modify it
  5575.   * under the terms and conditions of the GNU General Public License,
  5576. @@ -17,6 +17,7 @@
  5577.   */
  5578.  
  5579.  #include <linux/clk.h>
  5580. +#include <linux/dma-fence.h>
  5581.  #include <linux/interrupt.h>
  5582.  #include <linux/slab.h>
  5583.  #include <linux/irq.h>
  5584. @@ -133,12 +134,20 @@ static void action_wakeup_interruptible(struct host1x_waitlist *waiter)
  5585.     wake_up_interruptible(wq);
  5586.  }
  5587.  
  5588. +static void action_signal_fence(struct host1x_waitlist *waiter)
  5589. +{
  5590. +   struct dma_fence *fence = waiter->data;
  5591. +
  5592. +   dma_fence_signal(fence);
  5593. +}
  5594. +
  5595.  typedef void (*action_handler)(struct host1x_waitlist *waiter);
  5596.  
  5597.  static const action_handler action_handlers[HOST1X_INTR_ACTION_COUNT] = {
  5598.     action_submit_complete,
  5599.     action_wakeup,
  5600.     action_wakeup_interruptible,
  5601. +   action_signal_fence
  5602.  };
  5603.  
  5604.  static void run_handlers(struct list_head completed[HOST1X_INTR_ACTION_COUNT])
  5605. diff --git a/drivers/gpu/host1x/intr.h b/drivers/gpu/host1x/intr.h
  5606. index 1370c2b..6b2c090 100644
  5607. --- a/drivers/gpu/host1x/intr.h
  5608. +++ b/drivers/gpu/host1x/intr.h
  5609. @@ -1,7 +1,7 @@
  5610.  /*
  5611.   * Tegra host1x Interrupt Management
  5612.   *
  5613. - * Copyright (c) 2010-2013, NVIDIA Corporation.
  5614. + * Copyright (C) 2010-2016 NVIDIA CORPORATION.  All rights reserved.
  5615.   *
  5616.   * This program is free software; you can redistribute it and/or modify it
  5617.   * under the terms and conditions of the GNU General Public License,
  5618. @@ -43,6 +43,12 @@ enum host1x_intr_action {
  5619.      */
  5620.     HOST1X_INTR_ACTION_WAKEUP_INTERRUPTIBLE,
  5621.  
  5622. +   /*
  5623. +    * Signal a dma fence.
  5624. +    * 'data' points to a host1x_fence
  5625. +    */
  5626. +   HOST1X_INTR_ACTION_SIGNAL_FENCE,
  5627. +
  5628.     HOST1X_INTR_ACTION_COUNT
  5629.  };
  5630.  
  5631. diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
  5632. index a2a952a..652803b 100644
  5633. --- a/drivers/gpu/host1x/syncpt.c
  5634. +++ b/drivers/gpu/host1x/syncpt.c
  5635. @@ -18,6 +18,7 @@
  5636.  
  5637.  #include <linux/module.h>
  5638.  #include <linux/device.h>
  5639. +#include <linux/dma-fence.h>
  5640.  #include <linux/slab.h>
  5641.  
  5642.  #include <trace/events/host1x.h>
  5643. @@ -413,6 +414,7 @@ int host1x_syncpt_init(struct host1x *host)
  5644.     mutex_init(&host->syncpt_mutex);
  5645.     host->syncpt = syncpt;
  5646.     host->bases = bases;
  5647. +   host->fence_ctx_base = dma_fence_context_alloc(host->info->nb_pts);
  5648.  
  5649.     host1x_syncpt_restore(host);
  5650.     host1x_hw_syncpt_enable_protection(host);
  5651. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
  5652. index 6ec307c..5772de1 100644
  5653. --- a/drivers/hwmon/Kconfig
  5654. +++ b/drivers/hwmon/Kconfig
  5655. @@ -1291,7 +1291,7 @@ source drivers/hwmon/pmbus/Kconfig
  5656.  
  5657.  config SENSORS_PWM_FAN
  5658.     tristate "PWM fan"
  5659. -   depends on (PWM && OF) || COMPILE_TEST
  5660. +   depends on (PWM && OF && GPIOLIB && OF_GPIO) || COMPILE_TEST
  5661.     depends on THERMAL || THERMAL=n
  5662.     help
  5663.       If you say yes here you get support for fans connected to PWM lines.
  5664. diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
  5665. index 70cc0d1..c0cf501 100644
  5666. --- a/drivers/hwmon/pwm-fan.c
  5667. +++ b/drivers/hwmon/pwm-fan.c
  5668. @@ -18,6 +18,7 @@
  5669.  
  5670.  #include <linux/hwmon.h>
  5671.  #include <linux/hwmon-sysfs.h>
  5672. +#include <linux/gpio/consumer.h>
  5673.  #include <linux/module.h>
  5674.  #include <linux/mutex.h>
  5675.  #include <linux/of.h>
  5676. @@ -31,6 +32,7 @@
  5677.  struct pwm_fan_ctx {
  5678.     struct mutex lock;
  5679.     struct pwm_device *pwm;
  5680. +   struct gpio_desc *enable_gpio;
  5681.     unsigned int pwm_value;
  5682.     unsigned int pwm_fan_state;
  5683.     unsigned int pwm_fan_max_state;
  5684. @@ -56,6 +58,10 @@ static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)
  5685.     ret = pwm_apply_state(ctx->pwm, &state);
  5686.     if (!ret)
  5687.         ctx->pwm_value = pwm;
  5688. +
  5689. +   if (ctx->enable_gpio)
  5690. +       gpiod_set_value(ctx->enable_gpio, !!pwm);
  5691. +
  5692.  exit_set_pwm_err:
  5693.     mutex_unlock(&ctx->lock);
  5694.     return ret;
  5695. @@ -240,6 +246,13 @@ static int pwm_fan_probe(struct platform_device *pdev)
  5696.         return ret;
  5697.     }
  5698.  
  5699. +   ctx->enable_gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_HIGH);
  5700. +   if (IS_ERR(ctx->enable_gpio)) {
  5701. +       ctx->enable_gpio = NULL;
  5702. +   } else {
  5703. +       gpiod_set_value(ctx->enable_gpio, 1);
  5704. +   }
  5705. +
  5706.     hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwmfan",
  5707.                                ctx, pwm_fan_groups);
  5708.     if (IS_ERR(hwmon)) {
  5709. diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
  5710. index 074e506..c1f181e 100644
  5711. --- a/drivers/iio/light/Kconfig
  5712. +++ b/drivers/iio/light/Kconfig
  5713. @@ -63,6 +63,16 @@ config APDS9960
  5714.       To compile this driver as a module, choose M here: the
  5715.       module will be called apds9960
  5716.  
  5717. +config BH1730
  5718. +   tristate "ROHM BH1730 ambient light sensor"
  5719. +   depends on I2C
  5720. +   help
  5721. +    Say Y here to build support for the ROHM BH1730FVC ambient
  5722. +    light sensor.
  5723. +
  5724. +    To compile this driver as a module, choose M here: the module will
  5725. +    be called bh1730.
  5726. +
  5727.  config BH1750
  5728.     tristate "ROHM BH1750 ambient light sensor"
  5729.     depends on I2C
  5730. diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
  5731. index f177703..ee04d37 100644
  5732. --- a/drivers/iio/light/Makefile
  5733. +++ b/drivers/iio/light/Makefile
  5734. @@ -9,6 +9,7 @@ obj-$(CONFIG_ADJD_S311)     += adjd_s311.o
  5735.  obj-$(CONFIG_AL3320A)      += al3320a.o
  5736.  obj-$(CONFIG_APDS9300)     += apds9300.o
  5737.  obj-$(CONFIG_APDS9960)     += apds9960.o
  5738. +obj-$(CONFIG_BH1730)       += bh1730.o
  5739.  obj-$(CONFIG_BH1750)       += bh1750.o
  5740.  obj-$(CONFIG_BH1780)       += bh1780.o
  5741.  obj-$(CONFIG_CM32181)      += cm32181.o
  5742. diff --git a/drivers/iio/light/bh1730.c b/drivers/iio/light/bh1730.c
  5743. new file mode 100644
  5744. index 0000000..e79e055
  5745. --- /dev/null
  5746. +++ b/drivers/iio/light/bh1730.c
  5747. @@ -0,0 +1,435 @@
  5748. +// SPDX-License-Identifier: GPL-2.0
  5749. +/*
  5750. + * ROHM BH1730 ambient light sensor driver
  5751. + *
  5752. + * Copyright (c) 2018 Google, Inc.
  5753. + * Author: Pierre Bourdon <delroth@google.com>
  5754. + *
  5755. + * Based on a previous non-iio BH1730FVC driver:
  5756. + * Copyright (C) 2012 Samsung Electronics. All rights reserved.
  5757. + * Author: Won Huh <won.huh@samsung.com>
  5758. + *
  5759. + * Data sheets:
  5760. + *  http://www.rohm.com/web/global/datasheet/BH1730FVC/bh1730fvc-e
  5761. + */
  5762. +
  5763. +#include <linux/delay.h>
  5764. +#include <linux/i2c.h>
  5765. +#include <linux/iio/iio.h>
  5766. +#include <linux/module.h>
  5767. +#include <linux/of.h>
  5768. +#include <linux/time.h>
  5769. +
  5770. +#define BH1730_CMD_BIT BIT(7)
  5771. +
  5772. +#define BH1730_REG_CONTROL 0x00
  5773. +#define BH1730_REG_TIMING  0x01
  5774. +#define BH1730_REG_INTERRUPT   0x02
  5775. +#define BH1730_REG_THLLOW  0x03
  5776. +#define BH1730_REG_THLHIGH 0x04
  5777. +#define BH1730_REG_THHLOW  0x05
  5778. +#define BH1730_REG_THHHIGH 0x06
  5779. +#define BH1730_REG_GAIN        0x07
  5780. +#define BH1730_REG_ID      0x12
  5781. +#define BH1730_REG_DATA0LOW    0x14
  5782. +#define BH1730_REG_DATA0HIGH   0x15
  5783. +#define BH1730_REG_DATA1LOW    0x16
  5784. +#define BH1730_REG_DATA1HIGH   0x17
  5785. +
  5786. +#define BH1730_CONTROL_POWER_ON        BIT(0)
  5787. +#define BH1730_CONTROL_MEASURE     BIT(1)
  5788. +
  5789. +#define BH1730_INTERNAL_CLOCK_NS   2800
  5790. +
  5791. +#define BH1730_DEFAULT_INTEG_MS        150
  5792. +
  5793. +enum bh1730_gain {
  5794. +   BH1730_GAIN_1X = 0,
  5795. +   BH1730_GAIN_2X,
  5796. +   BH1730_GAIN_64X,
  5797. +   BH1730_GAIN_128X,
  5798. +};
  5799. +#define BH1730_MAX_GAIN_MULTIPLIER 128
  5800. +
  5801. +struct bh1730_data {
  5802. +   struct i2c_client *client;
  5803. +   enum bh1730_gain gain;
  5804. +   int itime;
  5805. +};
  5806. +
  5807. +static int bh1730_read_word(struct bh1730_data *bh1730, u8 reg)
  5808. +{
  5809. +   int ret = i2c_smbus_read_word_data(bh1730->client,
  5810. +                      BH1730_CMD_BIT | reg);
  5811. +   if (ret < 0)
  5812. +       dev_err(&bh1730->client->dev,
  5813. +           "i2c read failed error %d, register %01x\n",
  5814. +           ret, reg);
  5815. +
  5816. +   return ret;
  5817. +}
  5818. +
  5819. +static int bh1730_write(struct bh1730_data *bh1730, u8 reg, u8 val)
  5820. +{
  5821. +   int ret = i2c_smbus_write_byte_data(bh1730->client,
  5822. +                       BH1730_CMD_BIT | reg,
  5823. +                       val);
  5824. +   if (ret < 0)
  5825. +       dev_err(&bh1730->client->dev,
  5826. +           "i2c write failed error %d, register %01x\n",
  5827. +           ret, reg);
  5828. +
  5829. +   return ret;
  5830. +}
  5831. +
  5832. +static int gain_setting_to_multiplier(enum bh1730_gain gain)
  5833. +{
  5834. +   switch (gain) {
  5835. +   case BH1730_GAIN_1X:
  5836. +       return 1;
  5837. +   case BH1730_GAIN_2X:
  5838. +       return 2;
  5839. +   case BH1730_GAIN_64X:
  5840. +       return 64;
  5841. +   case BH1730_GAIN_128X:
  5842. +       return 128;
  5843. +   default:
  5844. +       return -EINVAL;
  5845. +   }
  5846. +}
  5847. +
  5848. +static int bh1730_gain_multiplier(struct bh1730_data *bh1730)
  5849. +{
  5850. +   int multiplier = gain_setting_to_multiplier(bh1730->gain);
  5851. +
  5852. +   if (multiplier < 0) {
  5853. +       dev_warn(&bh1730->client->dev,
  5854. +            "invalid gain multiplier settings: %d\n",
  5855. +            bh1730->gain);
  5856. +       bh1730->gain = BH1730_GAIN_1X;
  5857. +       multiplier = 1;
  5858. +   }
  5859. +
  5860. +   return multiplier;
  5861. +}
  5862. +
  5863. +static int bh1730_itime_us(struct bh1730_data *bh1730)
  5864. +{
  5865. +   return (BH1730_INTERNAL_CLOCK_NS * 964 * (256 - bh1730->itime))
  5866. +           / NSEC_PER_USEC;
  5867. +}
  5868. +
  5869. +static int bh1730_set_gain(struct bh1730_data *bh1730, enum bh1730_gain gain)
  5870. +{
  5871. +   int ret = bh1730_write(bh1730, BH1730_REG_GAIN, gain);
  5872. +
  5873. +   if (ret < 0)
  5874. +       return ret;
  5875. +
  5876. +   bh1730->gain = gain;
  5877. +
  5878. +   return 0;
  5879. +}
  5880. +
  5881. +static int bh1730_set_integration_time_ms(struct bh1730_data *bh1730,
  5882. +                     int time_ms)
  5883. +{
  5884. +   int ret, time_ns, itime;
  5885. +
  5886. +   /* Prefilter obviously invalid time_ms values that would overflow. */
  5887. +   if (time_ms <= 0 || time_ms > 1000) {
  5888. +       goto out_of_range;
  5889. +   }
  5890. +
  5891. +   time_ns = time_ms * (u64)NSEC_PER_MSEC;
  5892. +   itime = 256 - DIV_ROUND_CLOSEST(time_ns,
  5893. +                   BH1730_INTERNAL_CLOCK_NS * 964);
  5894. +
  5895. +   /* ITIME == 0 is reserved for manual integration mode. */
  5896. +   if (itime <= 0 || itime > 255) {
  5897. +       goto out_of_range;
  5898. +   }
  5899. +
  5900. +   ret = bh1730_write(bh1730, BH1730_REG_TIMING, itime);
  5901. +   if (ret < 0)
  5902. +       return ret;
  5903. +
  5904. +   bh1730->itime = itime;
  5905. +
  5906. +   return 0;
  5907. +
  5908. +out_of_range:
  5909. +   dev_warn(&bh1730->client->dev, "integration time out of range: %dms\n",
  5910. +        time_ms);
  5911. +
  5912. +   return -ERANGE;
  5913. +}
  5914. +
  5915. +static void bh1730_wait_for_next_measurement(struct bh1730_data *bh1730)
  5916. +{
  5917. +   udelay(bh1730_itime_us(bh1730) +
  5918. +       DIV_ROUND_UP(BH1730_INTERNAL_CLOCK_NS * 714, NSEC_PER_USEC));
  5919. +}
  5920. +
  5921. +static int bh1730_adjust_gain(struct bh1730_data *bh1730)
  5922. +{
  5923. +   int visible, ir, highest, gain, ret, i;
  5924. +
  5925. +   visible = bh1730_read_word(bh1730, BH1730_REG_DATA0LOW);
  5926. +   if (visible < 0)
  5927. +       return visible;
  5928. +
  5929. +   ir = bh1730_read_word(bh1730, BH1730_REG_DATA1LOW);
  5930. +   if (ir < 0)
  5931. +       return ir;
  5932. +
  5933. +   highest = max(visible, ir);
  5934. +
  5935. +   /*
  5936. +    * If the read value is being clamped, assume the worst and go to the
  5937. +    * lowest possible gain. The alternative is doing multiple
  5938. +    * recalibrations, which would be slower and have the same effect.
  5939. +    */
  5940. +   if (highest == USHRT_MAX)
  5941. +       gain = 1;
  5942. +   else
  5943. +       gain = bh1730_gain_multiplier(bh1730);
  5944. +
  5945. +   highest = (highest * BH1730_MAX_GAIN_MULTIPLIER) / gain;
  5946. +
  5947. +   /*
  5948. +    * Find the lowest gain multiplier which puts the measured values
  5949. +    * above 1024. This threshold is chosen to match the gap between 2X
  5950. +    * multiplier and 64X (next available) while keeping some margin.
  5951. +    */
  5952. +   for (i = BH1730_GAIN_1X; i < BH1730_GAIN_128X; ++i) {
  5953. +       int adj = highest * gain_setting_to_multiplier(i) /
  5954. +               BH1730_MAX_GAIN_MULTIPLIER;
  5955. +
  5956. +       if (adj >= 1024)
  5957. +           break;
  5958. +   }
  5959. +
  5960. +   if (i != bh1730->gain) {
  5961. +       ret = bh1730_set_gain(bh1730, i);
  5962. +       if (ret < 0)
  5963. +           return ret;
  5964. +
  5965. +       bh1730_wait_for_next_measurement(bh1730);
  5966. +   }
  5967. +
  5968. +   return 0;
  5969. +}
  5970. +
  5971. +static int bh1730_get_millilux(struct bh1730_data *bh1730)
  5972. +{
  5973. +   int visible, ir, visible_coef, ir_coef;
  5974. +   u64 millilux;
  5975. +
  5976. +   visible = bh1730_read_word(bh1730, BH1730_REG_DATA0LOW);
  5977. +   if (visible < 0)
  5978. +       return visible;
  5979. +
  5980. +   ir = bh1730_read_word(bh1730, BH1730_REG_DATA1LOW);
  5981. +   if (ir < 0)
  5982. +       return ir;
  5983. +
  5984. +   if (ir * 1000 / visible < 500) {
  5985. +       visible_coef = 5002;
  5986. +       ir_coef = 7502;
  5987. +   } else if (ir * 1000 / visible < 754) {
  5988. +       visible_coef = 2250;
  5989. +       ir_coef = 2000;
  5990. +   } else if (ir * 1000 / visible < 1029) {
  5991. +       visible_coef = 1999;
  5992. +       ir_coef = 1667;
  5993. +   } else if (ir * 1000 / visible < 1373) {
  5994. +       visible_coef = 885;
  5995. +       ir_coef = 583;
  5996. +   } else if (ir * 1000 / visible < 1879) {
  5997. +       visible_coef = 309;
  5998. +       ir_coef = 165;
  5999. +   } else {
  6000. +       return 0;
  6001. +   }
  6002. +
  6003. +   millilux = 103ULL * (visible_coef * visible - ir_coef * ir);
  6004. +   millilux *= USEC_PER_MSEC;
  6005. +   do_div(millilux, bh1730_itime_us(bh1730));
  6006. +   do_div(millilux, bh1730_gain_multiplier(bh1730));
  6007. +
  6008. +   /*
  6009. +    * Overflow here can only happen in extreme conditions:
  6010. +    * - Completely saturated visible light sensor and no measured IR.
  6011. +    * - Integration time < 16ms (driver currently defaults to 150ms).
  6012. +    */
  6013. +   if (millilux > INT_MAX)
  6014. +       return -ERANGE;
  6015. +
  6016. +   return (int)millilux;
  6017. +}
  6018. +
  6019. +static int bh1730_power_on(struct bh1730_data *bh1730)
  6020. +{
  6021. +   return bh1730_write(bh1730, BH1730_REG_CONTROL,
  6022. +               BH1730_CONTROL_POWER_ON | BH1730_CONTROL_MEASURE);
  6023. +}
  6024. +
  6025. +static int bh1730_set_defaults(struct bh1730_data *bh1730)
  6026. +{
  6027. +   int ret;
  6028. +
  6029. +   ret = bh1730_set_gain(bh1730, BH1730_GAIN_1X);
  6030. +   if (ret < 0)
  6031. +       return ret;
  6032. +
  6033. +   ret = bh1730_set_integration_time_ms(bh1730, BH1730_DEFAULT_INTEG_MS);
  6034. +   if (ret < 0)
  6035. +       return ret;
  6036. +
  6037. +   bh1730_wait_for_next_measurement(bh1730);
  6038. +
  6039. +   return 0;
  6040. +}
  6041. +
  6042. +static int bh1730_power_off(struct bh1730_data *bh1730)
  6043. +{
  6044. +   return bh1730_write(bh1730, BH1730_REG_CONTROL, 0);
  6045. +}
  6046. +
  6047. +static int bh1730_read_raw(struct iio_dev *indio_dev,
  6048. +              struct iio_chan_spec const *chan,
  6049. +              int *val, int *val2, long mask)
  6050. +{
  6051. +   struct bh1730_data *bh1730 = iio_priv(indio_dev);
  6052. +   int data_reg, ret;
  6053. +
  6054. +   ret = bh1730_adjust_gain(bh1730);
  6055. +   if (ret < 0)
  6056. +       return ret;
  6057. +
  6058. +   switch (mask) {
  6059. +   case IIO_CHAN_INFO_PROCESSED:
  6060. +       ret = bh1730_get_millilux(bh1730);
  6061. +       if (ret < 0)
  6062. +           return ret;
  6063. +       *val = ret / 1000;
  6064. +       *val2 = (ret % 1000) * 1000;
  6065. +       return IIO_VAL_INT_PLUS_MICRO;
  6066. +   case IIO_CHAN_INFO_RAW:
  6067. +       switch (chan->channel2) {
  6068. +       case IIO_MOD_LIGHT_CLEAR:
  6069. +           data_reg = BH1730_REG_DATA0LOW;
  6070. +           break;
  6071. +       case IIO_MOD_LIGHT_IR:
  6072. +           data_reg = BH1730_REG_DATA1LOW;
  6073. +           break;
  6074. +       default:
  6075. +           return -EINVAL;
  6076. +       }
  6077. +       ret = bh1730_read_word(bh1730, data_reg);
  6078. +       if (ret < 0)
  6079. +           return ret;
  6080. +       ret = ret * 1000 / bh1730_gain_multiplier(bh1730);
  6081. +       *val = ret / 1000;
  6082. +       *val2 = (ret % 1000) * 1000;
  6083. +       return IIO_VAL_INT_PLUS_MICRO;
  6084. +   default:
  6085. +       return -EINVAL;
  6086. +   }
  6087. +}
  6088. +
  6089. +static const struct iio_info bh1730_info = {
  6090. +   .read_raw = bh1730_read_raw,
  6091. +};
  6092. +
  6093. +static const struct iio_chan_spec bh1730_channels[] = {
  6094. +   {
  6095. +       .type = IIO_LIGHT,
  6096. +       .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  6097. +   },
  6098. +   {
  6099. +       .type = IIO_INTENSITY,
  6100. +       .modified = 1,
  6101. +       .channel2 = IIO_MOD_LIGHT_CLEAR,
  6102. +       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  6103. +   },
  6104. +   {
  6105. +       .type = IIO_INTENSITY,
  6106. +       .modified = 1,
  6107. +       .channel2 = IIO_MOD_LIGHT_IR,
  6108. +       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  6109. +   },
  6110. +};
  6111. +
  6112. +static int bh1730_probe(struct i2c_client *client)
  6113. +{
  6114. +   struct bh1730_data *bh1730;
  6115. +   struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
  6116. +   struct iio_dev *indio_dev;
  6117. +   int ret;
  6118. +
  6119. +   if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
  6120. +       return -EIO;
  6121. +
  6122. +   indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*bh1730));
  6123. +   if (!indio_dev)
  6124. +       return -ENOMEM;
  6125. +
  6126. +   bh1730 = iio_priv(indio_dev);
  6127. +   bh1730->client = client;
  6128. +   i2c_set_clientdata(client, indio_dev);
  6129. +
  6130. +   ret = bh1730_power_on(bh1730);
  6131. +   if (ret < 0)
  6132. +       return ret;
  6133. +
  6134. +   ret = bh1730_set_defaults(bh1730);
  6135. +   if (ret < 0)
  6136. +       return ret;
  6137. +
  6138. +   indio_dev->dev.parent = &client->dev;
  6139. +   indio_dev->info = &bh1730_info;
  6140. +   indio_dev->name = "bh1730";
  6141. +   indio_dev->channels = bh1730_channels;
  6142. +   indio_dev->num_channels = ARRAY_SIZE(bh1730_channels);
  6143. +   indio_dev->modes = INDIO_DIRECT_MODE;
  6144. +
  6145. +   ret = iio_device_register(indio_dev);
  6146. +   if (ret)
  6147. +       goto out_power_off;
  6148. +   return 0;
  6149. +
  6150. +out_power_off:
  6151. +   bh1730_power_off(bh1730);
  6152. +   return ret;
  6153. +}
  6154. +
  6155. +static int bh1730_remove(struct i2c_client *client)
  6156. +{
  6157. +   struct iio_dev *indio_dev = i2c_get_clientdata(client);
  6158. +   struct bh1730_data *bh1730 = iio_priv(indio_dev);
  6159. +
  6160. +   iio_device_unregister(indio_dev);
  6161. +   return bh1730_power_off(bh1730);
  6162. +}
  6163. +
  6164. +static const struct of_device_id of_bh1730_match[] = {
  6165. +   { .compatible = "rohm,bh1730fvc" },
  6166. +   {},
  6167. +};
  6168. +MODULE_DEVICE_TABLE(of, of_bh1730_match);
  6169. +
  6170. +static struct i2c_driver bh1730_driver = {
  6171. +   .probe_new = bh1730_probe,
  6172. +   .remove = bh1730_remove,
  6173. +   .driver = {
  6174. +       .name = "bh1730",
  6175. +       .of_match_table = of_bh1730_match,
  6176. +   },
  6177. +};
  6178. +module_i2c_driver(bh1730_driver);
  6179. +
  6180. +MODULE_AUTHOR("Pierre Bourdon <delroth@google.com>");
  6181. +MODULE_DESCRIPTION("ROHM BH1730FVC driver");
  6182. +MODULE_LICENSE("GPL v2");
  6183. diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
  6184. index 9591fc0..bac9188 100644
  6185. --- a/drivers/input/joystick/Kconfig
  6186. +++ b/drivers/input/joystick/Kconfig
  6187. @@ -277,6 +277,18 @@ config JOYSTICK_JOYDUMP
  6188.       To compile this driver as a module, choose M here: the
  6189.       module will be called joydump.
  6190.  
  6191. +config JOYSTICK_JOYCON
  6192. +   tristate "Joy-Con Rails"
  6193. +   select SERIAL_DEV_BUS
  6194. +   select POWER_SUPPLY
  6195. +   select CRC8
  6196. +   help
  6197. +     Say Y here if you have a one or more Joy-Con connected over UART
  6198. +
  6199. +     To compile this driver as a module, choose M here: the
  6200. +     module will be called joycon.
  6201. +
  6202. +
  6203.  config JOYSTICK_XPAD
  6204.     tristate "X-Box gamepad support"
  6205.     depends on USB_ARCH_HAS_HCD
  6206. diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile
  6207. index dd0492e..6a45ee9 100644
  6208. --- a/drivers/input/joystick/Makefile
  6209. +++ b/drivers/input/joystick/Makefile
  6210. @@ -19,6 +19,7 @@ obj-$(CONFIG_JOYSTICK_GRIP_MP)        += grip_mp.o
  6211.  obj-$(CONFIG_JOYSTICK_GUILLEMOT)   += guillemot.o
  6212.  obj-$(CONFIG_JOYSTICK_IFORCE)      += iforce/
  6213.  obj-$(CONFIG_JOYSTICK_INTERACT)        += interact.o
  6214. +obj-$(CONFIG_JOYSTICK_JOYCON)      += joycon.o
  6215.  obj-$(CONFIG_JOYSTICK_JOYDUMP)     += joydump.o
  6216.  obj-$(CONFIG_JOYSTICK_MAGELLAN)        += magellan.o
  6217.  obj-$(CONFIG_JOYSTICK_MAPLE)       += maplecontrol.o
  6218. diff --git a/drivers/input/joystick/joycon.c b/drivers/input/joystick/joycon.c
  6219. new file mode 100644
  6220. index 000000000000..3179926b19c3
  6221. --- /dev/null
  6222. +++ b/drivers/input/joystick/joycon.c
  6223. @@ -0,0 +1,950 @@
  6224. +/*
  6225. + *  Copyright (c) 2018 Max Thomas
  6226. + */
  6227. +
  6228. +/*
  6229. + * Nintendo Joy-Con serial gamepad driver for Linux
  6230. + */
  6231. +
  6232. +/*
  6233. + * This program is free warftware; you can redistribute it and/or modify
  6234. + * it under the terms of the GNU General Public License as published by
  6235. + * the Free Software Foundation; either version 2 of the License, or
  6236. + * (at your option) any later version.
  6237. + *
  6238. + * This program is distributed in the hope that it will be useful,
  6239. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6240. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  6241. + * GNU General Public License for more details.
  6242. + *
  6243. + * You should have received a copy of the GNU General Public License
  6244. + * along with this program; if not, write to the Free Software
  6245. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  6246. + *
  6247. + *  Should you need to contact me, the author, you can do so either by
  6248. + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  6249. + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  6250. + */
  6251. +
  6252. +#include <linux/kernel.h>
  6253. +#include <linux/module.h>
  6254. +#include <linux/slab.h>
  6255. +#include <linux/input.h>
  6256. +#include <linux/of.h>
  6257. +#include <linux/tty.h>
  6258. +#include <linux/serdev.h>
  6259. +#include <linux/platform_device.h>
  6260. +#include <linux/jiffies.h>
  6261. +#include <linux/workqueue.h>
  6262. +#include <linux/crc8.h>
  6263. +#include <linux/power_supply.h>
  6264. +#include <linux/gpio/consumer.h>
  6265. +
  6266. +#define DRIVER_DESC    "Nintendo Joy-Con serial gamepad driver"
  6267. +
  6268. +MODULE_AUTHOR("Max Thomas <mtinc2@gmail.com>");
  6269. +MODULE_DESCRIPTION(DRIVER_DESC);
  6270. +MODULE_LICENSE("GPL");
  6271. +
  6272. +
  6273. +/*
  6274. + * Constants.
  6275. + */
  6276. +
  6277. +
  6278. +static const u8 switch_baud[0x14] = {0x19, 0x01, 0x03, 0x0F, 0x00, 0x91, 0x20, 0x08, 0x00, 0x00, 0xBD, 0xB1, 0xC0, 0xC6, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00};
  6279. +static const u8 controller_status[0xD] = {0x19, 0x01, 0x03, 0x08, 0x00, 0x92, 0x00, 0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F};
  6280. +static const u8 unk_3[0x10] = {0x19, 0x01, 0x03, 0x0B, 0x00, 0x91, 0x12, 0x04, 0x00, 0x00, 0x12, 0xA6, 0x0F, 0x00, 0x00, 0x00};
  6281. +
  6282. +#define JOYCON_COMMAND_EXTSEND   (0x91)
  6283. +#define JOYCON_COMMAND_EXTRET    (0x92)
  6284. +#define JOYCON_COMMAND_INITRET   (0x94)
  6285. +#define JOYCON_COMMAND_HANDSHAKE (0xA5)
  6286. +
  6287. +#define JOYCON_INIT_MAC      (0x1)
  6288. +#define JOYCON_INIT_BAUDRATE (0x20)
  6289. +#define JOYCON_INIT_UNK1     (0x11)
  6290. +#define JOYCON_INIT_UNK2     (0x10)
  6291. +#define JOYCON_INIT_UNK3     (0x12)
  6292. +
  6293. +#define JOYCON_EXT_ACK        (0x1F)
  6294. +#define JOYCON_EXT_INPUT      (0x30)
  6295. +#define JOYCON_EXT_HIDCOMMAND (0x21)
  6296. +
  6297. +#define JOYCON_HID_DEVICE_INFO (0x2)
  6298. +#define JOYCON_HID_SPI_READ    (0x10)
  6299. +#define JOYCON_HID_GET_REGVOLT (0x50)
  6300. +
  6301. +#define JOYCON_SPI_FACTORY_CAL_2 (0x603D)
  6302. +#define JOYCON_SPI_FACTORY_CAL_3 (0x6080)
  6303. +#define JOYCON_SPI_STICK_USERCAL (0x8010)
  6304. +
  6305. +#define JOYCON_BATT_MV_MIN (3300)
  6306. +#define JOYCON_BATT_MV_MAX (4200)
  6307. +
  6308. +#define JOYCON_BUTTONS_LEFT  (0xFFE900)
  6309. +#define JOYCON_BUTTONS_RIGHT (0x76FF)
  6310. +#define JOYCON_BUTTONS_ALL (JOYCON_BUTTONS_LEFT | JOYCON_BUTTONS_RIGHT)
  6311. +
  6312. +#define JOYCON_BUTTONSET_LEFT  BIT(0)
  6313. +#define JOYCON_BUTTONSET_RIGHT BIT(1)
  6314. +
  6315. +#define JOYCON_CRC8_POLY (0x8D)
  6316. +#define JOYCON_CRC8_INIT (0x00)
  6317. +
  6318. +typedef struct joycon_uart_initial
  6319. +{
  6320. +   u8 magic[3];
  6321. +   u8 total_size;
  6322. +   u8 pad;
  6323. +} joycon_uart_initial;
  6324. +
  6325. +typedef struct joycon_uart_header
  6326. +{
  6327. +   joycon_uart_initial initial;
  6328. +   u8 command;
  6329. +   u8 data[5];
  6330. +   u8 crc;
  6331. +} joycon_uart_header;
  6332. +
  6333. +typedef struct joycon_subcmd_packet
  6334. +{
  6335. +   joycon_uart_header pre;
  6336. +   u8 command;
  6337. +   u8 data[];
  6338. +} joycon_subcmd_packet;
  6339. +
  6340. +struct joycon_stick_calib
  6341. +{
  6342. +   u16 x_max;
  6343. +   u16 y_max;
  6344. +   u16 x_cent;
  6345. +   u16 y_cent;
  6346. +   u16 x_min;
  6347. +   u16 y_min; 
  6348. +};
  6349. +
  6350. +/* Joy-Con button mappings */
  6351. +static const signed short joycon_common_btn[] = {
  6352. +   BTN_Y, BTN_X, BTN_B, BTN_A,
  6353. +   BTN_0, BTN_1, BTN_TR, BTN_TR2,
  6354. +   BTN_SELECT, BTN_START,
  6355. +   BTN_THUMBR, BTN_THUMBL,
  6356. +   BTN_MODE, BTN_Z,
  6357. +   BTN_4, BTN_5, /* These two buttons do not exist on retail controllers. */
  6358. +   BTN_DPAD_DOWN, BTN_DPAD_UP, BTN_DPAD_RIGHT, BTN_DPAD_LEFT,
  6359. +   BTN_2, BTN_3, BTN_TL, BTN_TL2,
  6360. +   -1 /* terminating entry */
  6361. +};
  6362. +
  6363. +/* Driver data */
  6364. +struct joycon_device {
  6365. +   struct list_head    list;
  6366. +
  6367. +   struct device       *dev;
  6368. +
  6369. +   const char      *name;
  6370. +   int         irq;
  6371. +};
  6372. +
  6373. +/*
  6374. + * Per-Joy-Con data.
  6375. + */
  6376. +
  6377. +struct joycon {
  6378. +   struct serdev_device *serdev;
  6379. +   struct input_dev *input_dev;
  6380. +   struct power_supply *batt_dev;
  6381. +   struct device *dev;
  6382. +   struct power_supply_desc batt_desc;
  6383. +   struct gpio_desc *charge_gpio;
  6384. +  
  6385. +   bool handshaken;
  6386. +   bool initialized;
  6387. +   bool factory_cal_2_parsed;
  6388. +   bool factory_cal_3_parsed;
  6389. +   bool usercal_parsed;
  6390. +  
  6391. +   int timeout_samples;
  6392. +   int num_samples;
  6393. +   int reconnect_threshold;
  6394. +  
  6395. +   u8 button_set;
  6396. +   struct joycon_stick_calib l_calib;
  6397. +   struct joycon_stick_calib r_calib;
  6398. +  
  6399. +   struct workqueue_struct *wq;
  6400. +  
  6401. +   int idx;
  6402. +   u16 regvolt;
  6403. +   u32 buttons;
  6404. +   u8 mac[6];
  6405. +};
  6406. +
  6407. +/*
  6408. + * Globals
  6409. + */
  6410. +static DEFINE_MUTEX(joycon_device_lock);
  6411. +static DEFINE_MUTEX(joycon_input_lock);
  6412. +static LIST_HEAD(joycon_device_list);
  6413. +
  6414. +static u8 crc_table[CRC8_TABLE_SIZE];
  6415. +
  6416. +static struct serdev_device_ops joycon_ops;
  6417. +static struct input_dev *input_dev;
  6418. +static u32 buttons;
  6419. +static int stick_lx, stick_ly, stick_rx, stick_ry;
  6420. +static int joycon_increment;
  6421. +
  6422. +
  6423. +struct work_timeout_poll {
  6424. +   struct delayed_work work;
  6425. +   struct joycon* joycon;
  6426. +};
  6427. +
  6428. +struct work_input_poll {
  6429. +   struct delayed_work work;
  6430. +   struct joycon* joycon;
  6431. +};
  6432. +
  6433. +struct work_sync_poll {
  6434. +   struct delayed_work work;
  6435. +   struct joycon* joycon;
  6436. +};
  6437. +
  6438. +u8 joycon_crc8(u8* data, size_t len)
  6439. +{
  6440. +   return crc8(crc_table, data, len, JOYCON_CRC8_INIT);
  6441. +}
  6442. +
  6443. +/*
  6444. + * Battery stuff
  6445. + */
  6446. +
  6447. +static enum power_supply_property joycon_battery_props[] = {
  6448. +   POWER_SUPPLY_PROP_TECHNOLOGY,
  6449. +   POWER_SUPPLY_PROP_SCOPE,
  6450. +   POWER_SUPPLY_PROP_CAPACITY,
  6451. +   POWER_SUPPLY_PROP_VOLTAGE_NOW,
  6452. +   POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
  6453. +   POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
  6454. +};
  6455. +
  6456. +static int joycon_battery_get_property(struct power_supply *psy,
  6457. +                      enum power_supply_property psp,
  6458. +                      union power_supply_propval *val)
  6459. +{
  6460. +   struct joycon *joycon = power_supply_get_drvdata(psy);
  6461. +   u32 regvolt_scaled, total_scaled;
  6462. +
  6463. +   switch (psp)
  6464. +   {
  6465. +   case POWER_SUPPLY_PROP_TECHNOLOGY:
  6466. +       val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
  6467. +       break;
  6468. +   case POWER_SUPPLY_PROP_SCOPE:
  6469. +       val->intval = POWER_SUPPLY_SCOPE_DEVICE;
  6470. +       break;
  6471. +   case POWER_SUPPLY_PROP_CAPACITY:
  6472. +       regvolt_scaled = ((joycon->regvolt - JOYCON_BATT_MV_MIN) * 100);
  6473. +       total_scaled = (JOYCON_BATT_MV_MAX - JOYCON_BATT_MV_MIN);
  6474. +       val->intval = regvolt_scaled / total_scaled;
  6475. +       break;
  6476. +   case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  6477. +       val->intval = joycon->regvolt * 1000;
  6478. +       break;
  6479. +   case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
  6480. +       val->intval = JOYCON_BATT_MV_MAX * 1000;
  6481. +       break;
  6482. +   case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
  6483. +       val->intval = JOYCON_BATT_MV_MIN * 1000;
  6484. +       break;
  6485. +   default:
  6486. +       return -EINVAL;
  6487. +   }
  6488. +  
  6489. +   return 0;
  6490. +}
  6491. +
  6492. +
  6493. +/*
  6494. + * Packet crafting
  6495. + */
  6496. +
  6497. +u16 joycon_packet_craft(u8 *out, u8 command, u8 *data, u16 size)
  6498. +{
  6499. +   u16 packet_size = sizeof(joycon_uart_header);
  6500. +   joycon_uart_header *pre = (joycon_uart_header*)out;
  6501. +
  6502. +   pre->initial.magic[0] = 0x19;
  6503. +   pre->initial.magic[1] = 0x01;
  6504. +   pre->initial.magic[2] = 0x3;
  6505. +
  6506. +   pre->initial.total_size = 7;
  6507. +   pre->command = command;
  6508. +
  6509. +   if (data)
  6510. +       memcpy(pre->data, data, size);
  6511. +
  6512. +   pre->crc = joycon_crc8((void*)pre + 0x4, 0x7);
  6513. +
  6514. +   return packet_size;
  6515. +}
  6516. +
  6517. +u16 joycon_extcommand_craft(u8 *out, u8 command, u8 *data, u16 size)
  6518. +{
  6519. +   u16 packet_size;
  6520. +   struct
  6521. +   {
  6522. +       u8 size[2];
  6523. +   } subcmd_data;
  6524. +
  6525. +   joycon_subcmd_packet* subcmd_packet = (joycon_subcmd_packet*)out;
  6526. +
  6527. +   subcmd_data.size[0] = (size + sizeof(u8)) >> 8;
  6528. +   subcmd_data.size[1] = (size + sizeof(u8)) & 0xFF;
  6529. +   packet_size = joycon_packet_craft(out, 0x92, (u8*)&subcmd_data, sizeof(subcmd_data));
  6530. +
  6531. +   subcmd_packet->pre.initial.total_size += size;
  6532. +   subcmd_packet->command = command;
  6533. +   if (data)
  6534. +       memcpy(subcmd_packet->data, data, size);
  6535. +
  6536. +   packet_size += size + sizeof(u8);
  6537. +   return packet_size;
  6538. +}
  6539. +
  6540. +void joycon_send_command(struct serdev_device *serdev, u8 command, u8 *data, u16 size)
  6541. +{
  6542. +   //TODO: memory corruption somewhere
  6543. +   u8 temp[0x1000]; //TODO: why did I make this static again
  6544. +   memset(temp, 0, sizeof(temp));
  6545. +
  6546. +   size = joycon_packet_craft(temp, command, data, size);
  6547. +
  6548. +   //print_bytes(temp, size);
  6549. +   serdev_device_write(serdev, temp, size, msecs_to_jiffies(200));
  6550. +}
  6551. +
  6552. +void joycon_send_extcommand(struct serdev_device *serdev, u8 command, u8 *data, u16 size)
  6553. +{
  6554. +   //u8 *temp = devm_kzalloc(&serdev->dev, size+0x1000, GFP_KERNEL);
  6555. +   u8 temp[0x1000];
  6556. +   memset(temp, 0, sizeof(temp));
  6557. +
  6558. +   //TODO: memory corruption somewhere
  6559. +   size = joycon_extcommand_craft(temp, command, data, size);
  6560. +
  6561. +   //print_bytes(temp, size);
  6562. +   serdev_device_write(serdev, temp, size, msecs_to_jiffies(200));
  6563. +   //kfree(temp);
  6564. +}
  6565. +
  6566. +void joycon_send_hidcommand(struct serdev_device *serdev, u8 command, u8 *data, u16 size)
  6567. +{
  6568. +   u8 data_gen[0x1000];
  6569. +   u8 rumble[8] = {0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40};
  6570. +
  6571. +   memset(data_gen, 0, sizeof(data_gen));
  6572. +
  6573. +   //TODO: memory corruption somewhere
  6574. +   //u8 *data_gen = devm_kzalloc(&serdev->dev, size+10+0x1000, GFP_KERNEL);
  6575. +   data_gen[0] = 0; //inc
  6576. +   memcpy(&data_gen[1], rumble, sizeof(rumble));
  6577. +   data_gen[9] = command;
  6578. +  
  6579. +   if (data)
  6580. +       memcpy(&data_gen[10], data, size);
  6581. +
  6582. +   joycon_send_extcommand(serdev, 1, data_gen, 0x30);
  6583. +   //kfree(data_gen);
  6584. +}
  6585. +
  6586. +/*
  6587. + * Handlers
  6588. + */
  6589. +
  6590. +static void timeout_handler(struct work_struct *work)
  6591. +{
  6592. +   struct work_timeout_poll * data = (struct work_timeout_poll *)work;
  6593. +   struct joycon *joycon = data->joycon;
  6594. +   struct serdev_device *serdev = joycon->serdev;
  6595. +   int err;
  6596. +  
  6597. +   // Inactive for 600ms, try handshaking again
  6598. +   if (joycon->num_samples - joycon->timeout_samples == 0)
  6599. +       joycon->reconnect_threshold++;
  6600. +   else
  6601. +       joycon->reconnect_threshold = 0;
  6602. +  
  6603. +   // We haven't gotten any samples within 600ms, we've probably been disconnected.
  6604. +   if (joycon->reconnect_threshold > 3)
  6605. +   {
  6606. +       joycon->handshaken = false;
  6607. +       joycon->initialized = false;
  6608. +       joycon->regvolt = 0;
  6609. +       gpiod_set_value(joycon->charge_gpio, 0);
  6610. +
  6611. +       err = serdev_device_write(serdev, (u8[]){0xA1, 0xA2, 0xA3, 0xA4}, 4, msecs_to_jiffies(200));
  6612. +       if (err) goto done;
  6613. +
  6614. +       joycon_send_command(serdev, JOYCON_COMMAND_HANDSHAKE, (u8[]){0x02, 0x01, 0x7E}, 3); //TODO: error passing
  6615. +      
  6616. +       serdev_device_write_flush(serdev);
  6617. +
  6618. +       joycon->reconnect_threshold = 0;
  6619. +       printk("Sent handshake\n");
  6620. +   }
  6621. +  
  6622. +   if (!joycon->initialized) goto done;
  6623. +  
  6624. +   joycon_send_hidcommand(serdev, JOYCON_HID_GET_REGVOLT, NULL, 0);
  6625. +
  6626. +done:
  6627. +   joycon->timeout_samples = joycon->num_samples;
  6628. +   INIT_DELAYED_WORK(&data->work,timeout_handler);
  6629. +   queue_delayed_work(joycon->wq, &data->work, msecs_to_jiffies(200));
  6630. +}
  6631. +
  6632. +static void input_handler(struct work_struct *work)
  6633. +{
  6634. +   struct work_input_poll * data = (struct work_input_poll *)work;
  6635. +   struct joycon *joycon = data->joycon;
  6636. +  
  6637. +   if (!joycon->initialized) goto done;
  6638. +   serdev_device_write(joycon->serdev, controller_status, sizeof(controller_status), msecs_to_jiffies(200));
  6639. +
  6640. +   if (!joycon->button_set)
  6641. +       joycon_send_hidcommand(joycon->serdev, JOYCON_HID_DEVICE_INFO, NULL, 0);
  6642. +
  6643. +   if (joycon->button_set && !joycon->factory_cal_2_parsed)
  6644. +       joycon_send_hidcommand(joycon->serdev, JOYCON_HID_SPI_READ, (u8[]){0x3D, 0x60, 0x00, 0x00, 0x1E}, 5); //TODO nicer
  6645. +
  6646. +   if (joycon->factory_cal_2_parsed && !joycon->usercal_parsed)
  6647. +       joycon_send_hidcommand(joycon->serdev, JOYCON_HID_SPI_READ, (u8[]){0x10, 0x80, 0x00, 0x00, 0x2F}, 5); //TODO nicer
  6648. +
  6649. +   if (joycon->factory_cal_2_parsed && !joycon->factory_cal_3_parsed)
  6650. +       joycon_send_hidcommand(joycon->serdev, JOYCON_HID_SPI_READ, (u8[]){0x80, 0x60, 0x00, 0x00, 0x17}, 5); //TODO nicer
  6651. +
  6652. +done:
  6653. +   INIT_DELAYED_WORK(&data->work, input_handler);
  6654. +   queue_delayed_work(joycon->wq, &data->work, msecs_to_jiffies(16));
  6655. +}
  6656. +
  6657. +static void sync_handler(struct work_struct *work)
  6658. +{
  6659. +   struct work_sync_poll * data = (struct work_sync_poll *)work;
  6660. +   struct joycon *joycon = data->joycon;
  6661. +   int i;
  6662. +  
  6663. +   mutex_lock(&joycon_input_lock);
  6664. +   for (i = 0; joycon_common_btn[i] >= 0; i++)
  6665. +   {
  6666. +       input_report_key(input_dev, joycon_common_btn[i], buttons & BIT(i));
  6667. +   }
  6668. +  
  6669. +   input_report_abs(input_dev, ABS_X, stick_lx);
  6670. +   input_report_abs(input_dev, ABS_Y, stick_ly);
  6671. +   input_report_abs(input_dev, ABS_RX, stick_rx);
  6672. +   input_report_abs(input_dev, ABS_RY, stick_ry);
  6673. +   input_sync(input_dev);
  6674. +   mutex_unlock(&joycon_input_lock);
  6675. +  
  6676. +   INIT_DELAYED_WORK(&data->work, sync_handler);
  6677. +   queue_delayed_work(joycon->wq, &data->work, msecs_to_jiffies(10));
  6678. +}
  6679. +
  6680. +/*
  6681. + * Packet parsing
  6682. + */
  6683. +
  6684. +static void joycon_parse_stick_cal(struct joycon_stick_calib *calib, const u8* packed)
  6685. +{
  6686. +   //min->max cent->min max->cent
  6687. +
  6688. +   calib->x_cent = ((packed[1] << 8) & 0xF00) | packed[0];
  6689. +   calib->y_cent = (packed[2] << 4) | (packed[1] >> 4);
  6690. +   calib->x_min = ((packed[4] << 8) & 0xF00) | packed[3];
  6691. +   calib->y_min = (packed[5] << 4) | (packed[4] >> 4);
  6692. +   calib->x_max = ((packed[7] << 8) & 0xF00) | packed[6];
  6693. +   calib->y_max = (packed[8] << 4) | (packed[7] >> 4);
  6694. +}
  6695. +
  6696. +static void joycon_calib_absinfo(struct input_absinfo *absinfo, unsigned int ax,
  6697. +                unsigned int ay, struct joycon_stick_calib *calib)
  6698. +{
  6699. +   absinfo[ax].minimum = calib->x_cent - calib->x_min;
  6700. +   absinfo[ax].maximum = calib->x_cent + calib->x_max;
  6701. +   absinfo[ay].minimum = calib->y_cent - calib->y_min;
  6702. +   absinfo[ay].maximum = calib->y_cent + calib->y_max;
  6703. +}
  6704. +
  6705. +static void joycon_parse_spi_read(struct serdev_device *serdev, const u8* packet, u32 size)
  6706. +{
  6707. +   struct joycon *joycon = serdev_device_get_drvdata(serdev);
  6708. +   u32 addr = (packet[4] << 24) | (packet[3] << 16) | (packet[2] << 8)
  6709. +              | packet[1];
  6710. +   u8 bytes_read = packet[5];
  6711. +  
  6712. +   if (addr == JOYCON_SPI_FACTORY_CAL_2 && bytes_read >= 0x1E)
  6713. +   {
  6714. +       joycon_parse_stick_cal(&joycon->l_calib, packet + 5);
  6715. +       joycon_parse_stick_cal(&joycon->r_calib, packet + 14);
  6716. +      
  6717. +       //TODO: Colors
  6718. +      
  6719. +       if (joycon->button_set & JOYCON_BUTTONSET_LEFT)
  6720. +       {
  6721. +           joycon_calib_absinfo(input_dev->absinfo, ABS_X, ABS_Y,
  6722. +                        &joycon->l_calib);
  6723. +           printk("Parsed left joystick configs\n");
  6724. +       }
  6725. +      
  6726. +       if (joycon->button_set & JOYCON_BUTTONSET_RIGHT)
  6727. +       {
  6728. +           joycon_calib_absinfo(input_dev->absinfo, ABS_RX, ABS_RY,
  6729. +                        &joycon->r_calib);
  6730. +           printk("Parsed right joystick configs\n");
  6731. +       }
  6732. +      
  6733. +       joycon->factory_cal_2_parsed = true;
  6734. +   }
  6735. +   else if (addr == JOYCON_SPI_STICK_USERCAL)
  6736. +   {
  6737. +       if (packet[6] == 0xB2 && packet[7] == 0xA1
  6738. +           && joycon->button_set & JOYCON_BUTTONSET_LEFT)
  6739. +       {
  6740. +           joycon_parse_stick_cal(&joycon->l_calib, packet + 7);
  6741. +           joycon_calib_absinfo(input_dev->absinfo, ABS_X, ABS_Y,
  6742. +                        &joycon->l_calib);
  6743. +           printk("Parsed left joystick user configs\n");
  6744. +       }
  6745. +          
  6746. +       if (packet[16] == 0xB2 && packet[17] == 0xA1
  6747. +           && joycon->button_set & JOYCON_BUTTONSET_RIGHT)
  6748. +       {
  6749. +           joycon_parse_stick_cal(&joycon->r_calib, packet + 17);
  6750. +           joycon_calib_absinfo(input_dev->absinfo, ABS_RX, ABS_RY,
  6751. +                        &joycon->r_calib);
  6752. +           printk("Parsed right joystick user configs\n");
  6753. +       }
  6754. +
  6755. +       //TODO: six-axis
  6756. +
  6757. +       joycon->usercal_parsed = true; 
  6758. +   }
  6759. +   else if (addr == JOYCON_SPI_FACTORY_CAL_3)
  6760. +   {
  6761. +       u16 dead_zone = packet[6+4] | (packet[6+5] << 8);
  6762. +       printk("Dead zone %x\n", dead_zone);
  6763. +      
  6764. +       /*if (joycon->button_set & JOYCON_BUTTONSET_LEFT)
  6765. +       {
  6766. +           input_dev->absinfo[ABS_X].flat = dead_zone;
  6767. +           input_dev->absinfo[ABS_Y].flat = dead_zone;
  6768. +       }
  6769. +      
  6770. +       if (joycon->button_set & JOYCON_BUTTONSET_RIGHT)
  6771. +       {
  6772. +           input_dev->absinfo[ABS_RX].flat = dead_zone;
  6773. +           input_dev->absinfo[ABS_RY].flat = dead_zone;
  6774. +       }*/
  6775. +      
  6776. +       joycon->factory_cal_3_parsed = true;
  6777. +   }
  6778. +}
  6779. +
  6780. +static void joycon_hidret_parse(struct serdev_device *serdev, const u8* packet, u32 size)
  6781. +{
  6782. +   struct joycon *joycon = serdev_device_get_drvdata(serdev);
  6783. +   switch (packet[0])
  6784. +   {
  6785. +   case JOYCON_HID_DEVICE_INFO:
  6786. +       printk("Joy-Con firmware version %u.%u\n", packet[1], packet[2]);
  6787. +       joycon->button_set = packet[3];
  6788. +       if (packet[3] == 1)
  6789. +           printk("Joy-Con is a left controller\n");
  6790. +       else if (packet[3] == 2)
  6791. +           printk("Joy-Con is a right controller\n");
  6792. +       else if (packet[3] == 3)
  6793. +           printk("Joy-Con is a pro controller\n");
  6794. +       else
  6795. +           printk("Joy-Con is unknown\n");
  6796. +       break;
  6797. +   case JOYCON_HID_SPI_READ:
  6798. +       joycon_parse_spi_read(serdev, packet, size);
  6799. +       break;
  6800. +   case JOYCON_HID_GET_REGVOLT:
  6801. +       // The actual regulated battery voltage is the raw * 2.5
  6802. +       joycon->regvolt = packet[1] | packet[2] << 8;
  6803. +       joycon->regvolt *= 5;
  6804. +       joycon->regvolt /= 2;
  6805. +       break;
  6806. +   default:
  6807. +       printk("Unknown hidret %x\n", packet[0]);
  6808. +       break;
  6809. +   }
  6810. +  
  6811. +   //print_bytes(packet, size);
  6812. +}
  6813. +
  6814. +static void joycon_extret_parse(struct serdev_device *serdev, const u8* packet, u32 size)
  6815. +{
  6816. +   struct joycon *joycon = serdev_device_get_drvdata(serdev);
  6817. +
  6818. +   switch (packet[0])
  6819. +   {
  6820. +   case JOYCON_EXT_INPUT:
  6821. +       joycon->buttons = packet[3] | packet[4] << 8 | packet[5] << 16;
  6822. +      
  6823. +       mutex_lock(&joycon_input_lock);
  6824. +       if (joycon->button_set & JOYCON_BUTTONSET_LEFT)
  6825. +       {
  6826. +           buttons &= ~JOYCON_BUTTONS_LEFT;;
  6827. +           buttons |= (joycon->buttons & JOYCON_BUTTONS_LEFT);
  6828. +       }
  6829. +       if (joycon->button_set & JOYCON_BUTTONSET_RIGHT)
  6830. +       {
  6831. +           buttons &= ~JOYCON_BUTTONS_RIGHT;
  6832. +           buttons |= (joycon->buttons & JOYCON_BUTTONS_RIGHT);
  6833. +       }
  6834. +
  6835. +       if (joycon->button_set & JOYCON_BUTTONSET_LEFT)
  6836. +       {
  6837. +           stick_lx = packet[6+0] | ((packet[6+1] & 0xF) << 8);
  6838. +           stick_ly = (packet[6+1] >> 4) | (packet[6+2] << 4);
  6839. +       }
  6840. +      
  6841. +       if (joycon->button_set & JOYCON_BUTTONSET_RIGHT)
  6842. +       {
  6843. +           stick_rx = packet[9+0] | ((packet[9+1] & 0xF) << 8);
  6844. +           stick_ry = (packet[9+1] >> 4) | (packet[9+2] << 4);
  6845. +       }
  6846. +       mutex_unlock(&joycon_input_lock);
  6847. +          
  6848. +
  6849. +       joycon->num_samples++;
  6850. +       break;
  6851. +   case JOYCON_EXT_HIDCOMMAND:
  6852. +       joycon_hidret_parse(serdev, packet+14, size-14);
  6853. +       break;
  6854. +   default:
  6855. +       printk("Unknown extret %x\n", packet[0]);
  6856. +       break;
  6857. +   }
  6858. +}
  6859. +
  6860. +static void joycon_initret_parse(struct serdev_device *serdev, const u8* packet, u32 size)
  6861. +{
  6862. +   struct joycon *joycon = serdev_device_get_drvdata(serdev);
  6863. +   int i, j;
  6864. +
  6865. +   switch (packet[0])
  6866. +   {
  6867. +   case JOYCON_INIT_MAC:
  6868. +       for (i = 0xC, j = 0; i >= 0x6; i--)
  6869. +           joycon->mac[j++] = packet[i];
  6870. +       printk("Joy-Con with MAC %02X::%02X::%02X::%02X::%02X::%02X\n",
  6871. +           joycon->mac[0], joycon->mac[1], joycon->mac[2],
  6872. +           joycon->mac[3], joycon->mac[4], joycon->mac[5]);
  6873. +          
  6874. +       // Next init command
  6875. +       //serdev_device_write(serdev, switch_baud, sizeof(switch_baud), msecs_to_jiffies(200));
  6876. +       joycon_send_command(serdev, JOYCON_COMMAND_EXTSEND, (u8[]){JOYCON_INIT_UNK1}, 1);
  6877. +       break;
  6878. +   case JOYCON_INIT_UNK1:
  6879. +       joycon_send_command(serdev, JOYCON_COMMAND_EXTSEND, (u8[]){JOYCON_INIT_UNK2}, 1);
  6880. +       break;
  6881. +   case JOYCON_INIT_UNK2:
  6882. +       serdev_device_write(serdev, unk_3, sizeof(unk_3), msecs_to_jiffies(200));
  6883. +       break;
  6884. +   case JOYCON_INIT_UNK3:
  6885. +       joycon->button_set = 0;
  6886. +       joycon->num_samples = 0;
  6887. +       joycon->factory_cal_2_parsed = false;
  6888. +       joycon->factory_cal_3_parsed = false;
  6889. +       joycon->usercal_parsed = false;
  6890. +       joycon->initialized = true;
  6891. +      
  6892. +       gpiod_set_value(joycon->charge_gpio, 1);
  6893. +       break;
  6894. +   case JOYCON_INIT_BAUDRATE:
  6895. +       serdev_device_set_baudrate(serdev, 3000000);
  6896. +       printk("High-speed baudrate shifted...\n");
  6897. +       break;
  6898. +   default:
  6899. +       printk("Unknown initret %x\n", packet[0]);
  6900. +       break;
  6901. +   }
  6902. +}
  6903. +
  6904. +static void joycon_packet_parse(struct serdev_device *serdev, const u8* packet, size_t size)
  6905. +{
  6906. +   struct joycon *joycon = serdev_device_get_drvdata(serdev);
  6907. +   joycon_uart_header* header = (joycon_uart_header*) packet;
  6908. +
  6909. +   switch (header->command)
  6910. +   {
  6911. +   case JOYCON_COMMAND_EXTRET:
  6912. +       joycon_extret_parse(serdev, packet + sizeof(joycon_uart_header), (header->data[0] << 8) | header->data[1]);
  6913. +       break;
  6914. +   case JOYCON_COMMAND_INITRET:
  6915. +       joycon_initret_parse(serdev, packet + sizeof(joycon_uart_initial) + 1, size - sizeof(joycon_uart_initial) - 1);
  6916. +       break;
  6917. +   case JOYCON_COMMAND_HANDSHAKE:
  6918. +       printk("Got handshake response\n");
  6919. +       joycon->handshaken = true;
  6920. +      
  6921. +       // Get MAC
  6922. +       joycon_send_command(serdev, JOYCON_COMMAND_EXTSEND, (u8[]){JOYCON_INIT_MAC}, 1);
  6923. +       break;
  6924. +   default:
  6925. +       printk("Unknown command %x\n", header->command);
  6926. +       break;
  6927. +   }
  6928. +}
  6929. +
  6930. +static int joycon_serdev_receive_buf(struct serdev_device *serdev, const unsigned char *buf, size_t len)
  6931. +{
  6932. +   struct joycon *joycon = serdev_device_get_drvdata(serdev);
  6933. +
  6934. +   if (!joycon || serdev != joycon->serdev) {
  6935. +       WARN_ON(1);
  6936. +       return 0;
  6937. +   }
  6938. +  
  6939. +   joycon_packet_parse(serdev, buf, len);
  6940. +
  6941. +   return len;
  6942. +}
  6943. +
  6944. +static void joycon_serdev_write_wakeup(struct serdev_device *serdev)
  6945. +{
  6946. +   //printk("Wakeup\n");
  6947. +}
  6948. +
  6949. +/*
  6950. + * Serdev driver
  6951. + */
  6952. +
  6953. +static int joycon_serdev_probe(struct serdev_device *serdev)
  6954. +{
  6955. +   struct joycon *joycon;
  6956. +  
  6957. +   struct work_timeout_poll *work_timeout;
  6958. +   struct work_input_poll *work_input;
  6959. +   struct work_sync_poll *work_sync;
  6960. +   struct power_supply_config psy_cfg = {};
  6961. +   int i;
  6962. +   int err = -ENOMEM;
  6963. +
  6964. +   printk("Joy-Con probe!\n");
  6965. +
  6966. +   joycon = devm_kzalloc(&serdev->dev, sizeof(*joycon), GFP_KERNEL);
  6967. +   if (!joycon)
  6968. +       goto fail2;
  6969. +
  6970. +   joycon->wq = create_workqueue("joycon_wq");
  6971. +
  6972. +   if (input_dev) goto input_exists;
  6973. +
  6974. +   // TODO: For USB/BT this should be an array w/ Joy-Con
  6975. +   //       being matched to input devices by halves
  6976. +   input_dev = input_allocate_device();
  6977. +   if (!input_dev) goto fail2;
  6978. +  
  6979. +   input_dev->name = "Joy-Con Rails";
  6980. +   input_dev->id.bustype = BUS_VIRTUAL;
  6981. +   input_dev->id.vendor = 0x057E;
  6982. +   input_dev->id.product = 0x2008;
  6983. +   input_dev->id.version = 0x0100;
  6984. +   input_dev->dev.parent = &serdev->dev;
  6985. +
  6986. +   input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  6987. +  
  6988. +   /* set up standard buttons */
  6989. +   for (i = 0; joycon_common_btn[i] >= 0; i++)
  6990. +       __set_bit(joycon_common_btn[i], input_dev->keybit);
  6991. +
  6992. +   //TODO: dead zones
  6993. +   input_set_abs_params(input_dev, ABS_X, 0x400, 0xC00, 0, 180);
  6994. +   input_set_abs_params(input_dev, ABS_Y, 0x400, 0xC00, 0, 180);
  6995. +   input_set_abs_params(input_dev, ABS_RX, 0x400, 0xC00, 0, 180);
  6996. +   input_set_abs_params(input_dev, ABS_RY, 0x400, 0xC00, 0, 180);
  6997. +  
  6998. +   err = input_register_device(input_dev);
  6999. +   if (err) goto fail1;
  7000. +  
  7001. +   // Start input sync polling
  7002. +   work_sync = kmalloc(sizeof(struct work_sync_poll), GFP_KERNEL);
  7003. +   INIT_DELAYED_WORK(&work_sync->work, sync_handler);
  7004. +   work_sync->joycon = joycon;
  7005. +   queue_delayed_work(joycon->wq, &work_sync->work, msecs_to_jiffies(10));
  7006. +
  7007. +input_exists:
  7008. +
  7009. +   psy_cfg.of_node = serdev->dev.of_node;
  7010. +   psy_cfg.drv_data = joycon;
  7011. +  
  7012. +   joycon->batt_desc.name = kasprintf(GFP_KERNEL, "joycon_battery_%u", joycon_increment++);
  7013. +   joycon->batt_desc.type = POWER_SUPPLY_TYPE_BATTERY;
  7014. +   joycon->batt_desc.properties = joycon_battery_props;
  7015. +   joycon->batt_desc.num_properties = ARRAY_SIZE(joycon_battery_props);
  7016. +   joycon->batt_desc.get_property = joycon_battery_get_property;
  7017. +  
  7018. +   joycon->batt_dev = devm_power_supply_register(&serdev->dev, &joycon->batt_desc,
  7019. +                                 &psy_cfg);
  7020. +
  7021. +   err = PTR_ERR_OR_ZERO(joycon->batt_dev);
  7022. +   if (err) {
  7023. +       dev_err(&serdev->dev, "failed to register power supply\n");
  7024. +       goto fail1;
  7025. +   }
  7026. +
  7027. +   joycon->serdev = serdev;
  7028. +   joycon->dev = &serdev->dev;
  7029. +   joycon->input_dev = input_dev;
  7030. +
  7031. +   serdev_device_set_drvdata(serdev, joycon);
  7032. +
  7033. +   //TODO: error checking 
  7034. +   serdev_device_open(serdev);
  7035. +   serdev_device_set_flow_control(serdev, true);
  7036. +   serdev_device_set_baudrate(serdev, 1000000);
  7037. +  
  7038. +   serdev_device_set_client_ops(serdev, &joycon_ops);
  7039. +  
  7040. +   // Get charging GPIO
  7041. +   joycon->charge_gpio = devm_gpiod_get(&serdev->dev, "charge", GPIOD_OUT_LOW);
  7042. +   if (IS_ERR(joycon->charge_gpio)) {
  7043. +       err = PTR_ERR(joycon->charge_gpio);
  7044. +       dev_err(&serdev->dev, "cannot get charge-gpio %d\n", err);
  7045. +       goto fail3;
  7046. +   }
  7047. +  
  7048. +   // Set up work polling
  7049. +   work_timeout = kmalloc(sizeof(struct work_timeout_poll), GFP_KERNEL);
  7050. +   INIT_DELAYED_WORK(&work_timeout->work, timeout_handler);
  7051. +   work_timeout->joycon = joycon;
  7052. +   queue_delayed_work(joycon->wq, &work_timeout->work, msecs_to_jiffies(200));
  7053. +  
  7054. +   work_input = kmalloc(sizeof(struct work_input_poll), GFP_KERNEL);
  7055. +   work_input->joycon = joycon;
  7056. +   INIT_DELAYED_WORK(&work_input->work, input_handler);
  7057. +   queue_delayed_work(joycon->wq, &work_input->work, msecs_to_jiffies(200));
  7058. +
  7059. +   return 0;
  7060. +
  7061. + fail3: serdev_device_set_drvdata(serdev, NULL);
  7062. + fail1:    input_free_device(input_dev);
  7063. + fail2:
  7064. +   kfree(joycon);
  7065. +   return err;
  7066. +}
  7067. +
  7068. +static void joycon_serdev_remove(struct serdev_device *serdev)
  7069. +{
  7070. +   struct joycon *joycon = serdev_device_get_drvdata(serdev);
  7071. +   printk("Joy-Con remove!\n");
  7072. +  
  7073. +   input_unregister_device(joycon->input_dev);
  7074. +  
  7075. +   flush_workqueue(joycon->wq);
  7076. +   destroy_workqueue(joycon->wq);
  7077. +  
  7078. +   kfree(joycon->batt_desc.name);
  7079. +   kfree(joycon);
  7080. +}
  7081. +
  7082. +/*
  7083. + * The serdev driver structure.
  7084. + */
  7085. +#ifdef CONFIG_OF
  7086. +static const struct of_device_id joycon_uart_of_match[] = {
  7087. +   { .compatible = "nintendo,joycon-uart" },
  7088. +   { },
  7089. +};
  7090. +MODULE_DEVICE_TABLE(of, joycon_uart_of_match);
  7091. +#endif
  7092. +
  7093. +static struct serdev_device_driver joycon_serdev_driver = {
  7094. +   .probe = joycon_serdev_probe,
  7095. +   .remove = joycon_serdev_remove,
  7096. +   .driver = {
  7097. +       .name = "joycon-uart",
  7098. +       .of_match_table = of_match_ptr(joycon_uart_of_match),
  7099. +   },
  7100. +};
  7101. +
  7102. +static struct serdev_device_ops joycon_ops = {
  7103. +   .receive_buf = joycon_serdev_receive_buf,
  7104. +   .write_wakeup = joycon_serdev_write_wakeup,
  7105. +};
  7106. +
  7107. +/*
  7108. + * Joy-Con base driver
  7109. + */
  7110. +
  7111. +static int joycon_probe(struct platform_device *pdev)
  7112. +{
  7113. +   struct joycon_device *dev;
  7114. +
  7115. +   dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
  7116. +   if (!dev)
  7117. +       return -ENOMEM;
  7118. +
  7119. +   dev->dev = &pdev->dev;
  7120. +   dev->irq = platform_get_irq(pdev, 0);
  7121. +
  7122. +   platform_set_drvdata(pdev, dev);
  7123. +
  7124. +   dev_info(&pdev->dev, "%s device registered.\n", dev->name);
  7125. +
  7126. +   /* Place this instance on the device list */
  7127. +   mutex_lock(&joycon_device_lock);
  7128. +   list_add_tail(&dev->list, &joycon_device_list);
  7129. +   mutex_unlock(&joycon_device_lock);
  7130. +
  7131. +   return 0;
  7132. +}
  7133. +
  7134. +static int joycon_remove(struct platform_device *pdev)
  7135. +{
  7136. +   struct joycon_device *dev = platform_get_drvdata(pdev);
  7137. +
  7138. +   mutex_lock(&joycon_device_lock);
  7139. +   list_del(&dev->list);
  7140. +   mutex_unlock(&joycon_device_lock);
  7141. +
  7142. +   dev_info(&pdev->dev, "%s device unregistered.\n", dev->name);
  7143. +
  7144. +   return 0;
  7145. +}
  7146. +
  7147. +static struct platform_driver joycon_driver = {
  7148. +   .probe = joycon_probe,
  7149. +   .remove = joycon_remove,
  7150. +   .driver = {
  7151. +       .name = "joycon",
  7152. +   },
  7153. +};
  7154. +
  7155. +int __init joycon_init(void)
  7156. +{
  7157. +   platform_driver_register(&joycon_driver);
  7158. +   serdev_device_driver_register(&joycon_serdev_driver);
  7159. +  
  7160. +   joycon_increment = 0;
  7161. +   crc8_populate_lsb(crc_table, JOYCON_CRC8_POLY);
  7162. +
  7163. +   return 0;
  7164. +}
  7165. +
  7166. +void __exit joycon_exit(void)
  7167. +{
  7168. +   platform_driver_unregister(&joycon_driver);
  7169. +   serdev_device_driver_unregister(&joycon_serdev_driver);
  7170. +}
  7171. +
  7172. +module_init(joycon_init);
  7173. +module_exit(joycon_exit);
  7174. diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
  7175. index 704e990..3e026ab 100644
  7176. --- a/drivers/input/touchscreen/stmfts.c
  7177. +++ b/drivers/input/touchscreen/stmfts.c
  7178. @@ -14,6 +14,7 @@
  7179.  #include <linux/module.h>
  7180.  #include <linux/pm_runtime.h>
  7181.  #include <linux/regulator/consumer.h>
  7182. +#include <linux/kthread.h>
  7183.  
  7184.  /* I2C commands */
  7185.  #define STMFTS_READ_INFO           0x80
  7186. @@ -34,6 +35,7 @@
  7187.  #define STMFTS_FULL_FORCE_CALIBRATION      0xa2
  7188.  #define STMFTS_MS_CX_TUNING            0xa3
  7189.  #define STMFTS_SS_CX_TUNING            0xa4
  7190. +#define STMFTS_WRITE_REGISTER          0xb6
  7191.  
  7192.  /* events */
  7193.  #define STMFTS_EV_NO_EVENT         0x00
  7194. @@ -104,6 +106,11 @@ struct stmfts_data {
  7195.     bool led_status;
  7196.     bool hover_enabled;
  7197.     bool running;
  7198. +   bool no_sleep_support;
  7199. +   int irq_enable_reg;
  7200. +   u8 irq_enable_data;
  7201. +
  7202. +   struct task_struct *poll_thread;
  7203.  };
  7204.  
  7205.  static void stmfts_brightness_set(struct led_classdev *led_cdev,
  7206. @@ -169,6 +176,7 @@ static int stmfts_read_events(struct stmfts_data *sdata)
  7207.  static void stmfts_report_contact_event(struct stmfts_data *sdata,
  7208.                     const u8 event[])
  7209.  {
  7210. +#if 0
  7211.     u8 slot_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
  7212.     u16 x = event[1] | ((event[2] & STMFTS_MASK_X_MSB) << 8);
  7213.     u16 y = (event[2] >> 4) | (event[3] << 4);
  7214. @@ -176,7 +184,17 @@ static void stmfts_report_contact_event(struct stmfts_data *sdata,
  7215.     u8 min = event[5];
  7216.     u8 orientation = event[6];
  7217.     u8 area = event[7];
  7218. +#else
  7219. +   u8 slot_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
  7220. +   u16 x = (event[1] << 4) | ((event[3] & 0xf0) >> 4);
  7221. +   u16 y = (event[2] << 4) | (event[3] & 0x0f);
  7222.  
  7223. +   u8 maj = event[4] | (event[5] << 8);
  7224. +   u8 min = maj;
  7225. +   // these two are not quite right but meh
  7226. +   u8 orientation = event[6];
  7227. +   u8 area = event[7];
  7228. +#endif
  7229.     input_mt_slot(sdata->input, slot_id);
  7230.  
  7231.     input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, true);
  7232. @@ -313,6 +331,16 @@ static irqreturn_t stmfts_irq_handler(int irq, void *dev)
  7233.     return IRQ_HANDLED;
  7234.  }
  7235.  
  7236. +static int stmfts_poll_thread(void *data)
  7237. +{
  7238. +   while (!kthread_should_stop()) {
  7239. +       stmfts_irq_handler(0, data);
  7240. +       msleep(2);
  7241. +   }
  7242. +   return 0;
  7243. +}
  7244. +
  7245. +
  7246.  static int stmfts_command(struct stmfts_data *sdata, const u8 cmd)
  7247.  {
  7248.     int err;
  7249. @@ -330,6 +358,18 @@ static int stmfts_command(struct stmfts_data *sdata, const u8 cmd)
  7250.     return 0;
  7251.  }
  7252.  
  7253. +static int stmfts_write_register(struct stmfts_data *sdata, const u16 reg, const u8 value)
  7254. +{
  7255. +   u8 buf[3];
  7256. +
  7257. +   buf[0] = reg >> 8;
  7258. +   buf[1] = reg & 0xff;
  7259. +   buf[2] = value;
  7260. +
  7261. +   return i2c_smbus_write_i2c_block_data(sdata->client,
  7262. +                         STMFTS_WRITE_REGISTER, 3, buf);
  7263. +}
  7264. +
  7265.  static int stmfts_input_open(struct input_dev *dev)
  7266.  {
  7267.     struct stmfts_data *sdata = input_get_drvdata(dev);
  7268. @@ -546,18 +586,52 @@ static int stmfts_power_on(struct stmfts_data *sdata)
  7269.     sdata->fw_ver = be16_to_cpup((__be16 *)&reg[2]);
  7270.     sdata->config_id = reg[4];
  7271.     sdata->config_ver = reg[5];
  7272. -
  7273. -   enable_irq(sdata->client->irq);
  7274. +  
  7275. +   if (sdata->client->irq)
  7276. +       enable_irq(sdata->client->irq);
  7277.  
  7278.     msleep(50);
  7279.  
  7280. -   err = stmfts_command(sdata, STMFTS_SYSTEM_RESET);
  7281. +   if (!sdata->client->irq) {
  7282. +       sdata->poll_thread = kthread_run(stmfts_poll_thread, sdata, "stmfts_poll");
  7283. +       if (IS_ERR(sdata->poll_thread))
  7284. +           return -EIO;
  7285. +   }
  7286. +
  7287. +   /*
  7288. +    * IRQs may be disabled on startup, so we need to reset the chip, then
  7289. +    * immediately issue the command to enable IRQs. This will trigger
  7290. +    * the completion for the reset command's queued status message.
  7291. +    */
  7292. +   reinit_completion(&sdata->cmd_done);
  7293. +
  7294. +   err = i2c_smbus_write_byte(sdata->client, STMFTS_SYSTEM_RESET);
  7295.     if (err)
  7296. -       return err;
  7297. +       goto cleanup_irq;
  7298. +
  7299. +   msleep(10);
  7300. +
  7301. +   if (sdata->client->irq && sdata->irq_enable_reg != -1) {
  7302. +       err = stmfts_write_register(sdata, sdata->irq_enable_reg,
  7303. +                       sdata->irq_enable_data);
  7304. +       if (err)
  7305. +           goto cleanup_irq;
  7306. +   }
  7307. +
  7308. +   if (!wait_for_completion_timeout(&sdata->cmd_done,
  7309. +                    msecs_to_jiffies(1000))) {
  7310. +       err = -ETIMEDOUT;
  7311. +       dev_err(&sdata->client->dev,
  7312. +            "reset did not complete: %d\n", err);
  7313. +       goto cleanup_irq;
  7314. +   }
  7315.  
  7316.     err = stmfts_command(sdata, STMFTS_SLEEP_OUT);
  7317. -   if (err)
  7318. -       return err;
  7319. +   if (err) {
  7320. +       dev_warn(&sdata->client->dev,
  7321. +            "failed to perform sleep_out: %d\n", err);
  7322. +       sdata->no_sleep_support = true;
  7323. +   }
  7324.  
  7325.     /* optional tuning */
  7326.     err = stmfts_command(sdata, STMFTS_MS_CX_TUNING);
  7327. @@ -572,23 +646,37 @@ static int stmfts_power_on(struct stmfts_data *sdata)
  7328.              "failed to perform self auto tune: %d\n", err);
  7329.  
  7330.     err = stmfts_command(sdata, STMFTS_FULL_FORCE_CALIBRATION);
  7331. -   if (err)
  7332. -       return err;
  7333. +   if (err) {
  7334. +       dev_err(&sdata->client->dev,
  7335. +            "failed to perform calibration: %d\n", err);
  7336. +       goto cleanup_irq;
  7337. +   }
  7338.  
  7339.     /*
  7340.      * At this point no one is using the touchscreen
  7341.      * and I don't really care about the return value
  7342.      */
  7343. -   (void) i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
  7344. +   if (!sdata->no_sleep_support)
  7345. +       (void) i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
  7346.  
  7347.     return 0;
  7348. +
  7349. +cleanup_irq:
  7350. +   if (!sdata->client->irq)
  7351. +       kthread_stop(sdata->poll_thread);
  7352. +   else
  7353. +       disable_irq(sdata->client->irq);
  7354. +   return err;
  7355.  }
  7356.  
  7357.  static void stmfts_power_off(void *data)
  7358.  {
  7359.     struct stmfts_data *sdata = data;
  7360.  
  7361. -   disable_irq(sdata->client->irq);
  7362. +   if (!sdata->client->irq)
  7363. +       kthread_stop(sdata->poll_thread);
  7364. +   else
  7365. +       disable_irq(sdata->client->irq);
  7366.     regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
  7367.                         sdata->regulators);
  7368.  }
  7369. @@ -625,6 +713,7 @@ static int stmfts_probe(struct i2c_client *client,
  7370.  {
  7371.     int err;
  7372.     struct stmfts_data *sdata;
  7373. +   u32 prop[2];
  7374.  
  7375.     if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
  7376.                         I2C_FUNC_SMBUS_BYTE_DATA |
  7377. @@ -670,6 +759,15 @@ static int stmfts_probe(struct i2c_client *client,
  7378.  
  7379.     sdata->use_key = device_property_read_bool(&client->dev,
  7380.                            "touch-key-connected");
  7381. +  
  7382. +   if (!device_property_read_u32_array(&client->dev,
  7383. +       "interrupt-enable-reg", prop, 2)) {
  7384. +       sdata->irq_enable_reg = prop[0] & 0xffff;
  7385. +       sdata->irq_enable_data = prop[1] & 0xff;
  7386. +   } else {
  7387. +       sdata->irq_enable_reg = -1;
  7388. +   }
  7389. +  
  7390.     if (sdata->use_key) {
  7391.         input_set_capability(sdata->input, EV_KEY, KEY_MENU);
  7392.         input_set_capability(sdata->input, EV_KEY, KEY_BACK);
  7393. @@ -689,13 +787,15 @@ static int stmfts_probe(struct i2c_client *client,
  7394.      * interrupts. To be on the safe side it's better to not enable
  7395.      * the interrupts during their request.
  7396.      */
  7397. -   irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
  7398. -   err = devm_request_threaded_irq(&client->dev, client->irq,
  7399. -                   NULL, stmfts_irq_handler,
  7400. -                   IRQF_ONESHOT,
  7401. -                   "stmfts_irq", sdata);
  7402. -   if (err)
  7403. -       return err;
  7404. +   if (client->irq) {
  7405. +       irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
  7406. +       err = devm_request_threaded_irq(&client->dev, client->irq,
  7407. +                       NULL, stmfts_irq_handler,
  7408. +                       IRQF_ONESHOT,
  7409. +                       "stmfts_irq", sdata);
  7410. +       if (err)
  7411. +           return err;
  7412. +   }
  7413.  
  7414.     dev_dbg(&client->dev, "initializing ST-Microelectronics FTS...\n");
  7415.  
  7416. @@ -747,6 +847,9 @@ static int __maybe_unused stmfts_runtime_suspend(struct device *dev)
  7417.     struct stmfts_data *sdata = dev_get_drvdata(dev);
  7418.     int ret;
  7419.  
  7420. +   if (sdata->no_sleep_support)
  7421. +       return 0;
  7422. +
  7423.     ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
  7424.     if (ret)
  7425.         dev_warn(dev, "failed to suspend device: %d\n", ret);
  7426. @@ -759,6 +862,9 @@ static int __maybe_unused stmfts_runtime_resume(struct device *dev)
  7427.     struct stmfts_data *sdata = dev_get_drvdata(dev);
  7428.     int ret;
  7429.  
  7430. +   if (sdata->no_sleep_support)
  7431. +       return 0;
  7432. +
  7433.     ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
  7434.     if (ret)
  7435.         dev_err(dev, "failed to resume device: %d\n", ret);
  7436. diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
  7437. index b877c13..db438ce 100644
  7438. --- a/drivers/mmc/host/sdhci-tegra.c
  7439. +++ b/drivers/mmc/host/sdhci-tegra.c
  7440. @@ -27,6 +27,7 @@
  7441.  #include <linux/mmc/mmc.h>
  7442.  #include <linux/mmc/slot-gpio.h>
  7443.  #include <linux/gpio/consumer.h>
  7444. +#include <soc/tegra/pmc.h>
  7445.  
  7446.  #include "sdhci-pltfm.h"
  7447.  
  7448. @@ -55,6 +56,7 @@
  7449.  #define NVQUIRK_ENABLE_SDR104      BIT(4)
  7450.  #define NVQUIRK_ENABLE_DDR50       BIT(5)
  7451.  #define NVQUIRK_HAS_PADCALIB       BIT(6)
  7452. +#define NVQUIRK_NEEDS_PAD_CONTROL  BIT(7)
  7453.  
  7454.  struct sdhci_tegra_soc_data {
  7455.     const struct sdhci_pltfm_data *pdata;
  7456. @@ -66,6 +68,8 @@ struct sdhci_tegra {
  7457.     struct gpio_desc *power_gpio;
  7458.     bool ddr_signaling;
  7459.     bool pad_calib_required;
  7460. +   bool pad_control;
  7461. +   unsigned int pad_id;
  7462.  
  7463.     struct reset_control *rst;
  7464.  };
  7465. @@ -166,7 +170,9 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
  7466.      * even if the device supports it because the IO voltage
  7467.      * cannot be configured.
  7468.      */
  7469. -   if (!IS_ERR(host->mmc->supply.vqmmc)) {
  7470. +   if (!IS_ERR(host->mmc->supply.vqmmc) &&
  7471. +       (!(soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL) ||
  7472. +        tegra_host->pad_control)) {
  7473.         /* Erratum: Enable SDHCI spec v3.00 support */
  7474.         if (soc_data->nvquirks & NVQUIRK_ENABLE_SDHCI_SPEC_300)
  7475.             misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300;
  7476. @@ -289,7 +295,7 @@ static int tegra_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
  7477.     return mmc_send_tuning(host->mmc, opcode, NULL);
  7478.  }
  7479.  
  7480. -static void tegra_sdhci_voltage_switch(struct sdhci_host *host)
  7481. +static void tegra_sdhci_voltage_switch(struct sdhci_host *host, struct mmc_ios *ios)
  7482.  {
  7483.     struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  7484.     struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
  7485. @@ -297,6 +303,24 @@ static void tegra_sdhci_voltage_switch(struct sdhci_host *host)
  7486.  
  7487.     if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
  7488.         tegra_host->pad_calib_required = true;
  7489. +
  7490. +   if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
  7491. +       if (tegra_host->pad_control) {
  7492. +           tegra_io_pad_set_voltage(tegra_host->pad_id, TEGRA_IO_PAD_1800000UV);
  7493. +       }
  7494. +   }
  7495. +}
  7496. +
  7497. +static void tegra_sdhci_pre_voltage_switch(struct sdhci_host *host, struct mmc_ios *ios)
  7498. +{
  7499. +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  7500. +   struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
  7501. +
  7502. +   if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
  7503. +       if (tegra_host->pad_control) {
  7504. +           tegra_io_pad_set_voltage(tegra_host->pad_id, TEGRA_IO_PAD_3300000UV);
  7505. +       }
  7506. +   }
  7507.  }
  7508.  
  7509.  static const struct sdhci_ops tegra_sdhci_ops = {
  7510. @@ -308,6 +332,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
  7511.     .reset      = tegra_sdhci_reset,
  7512.     .platform_execute_tuning = tegra_sdhci_execute_tuning,
  7513.     .set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
  7514. +   .pre_voltage_switch = tegra_sdhci_pre_voltage_switch,
  7515.     .voltage_switch = tegra_sdhci_voltage_switch,
  7516.     .get_max_clock = tegra_sdhci_get_max_clock,
  7517.  };
  7518. @@ -413,6 +438,11 @@ static const struct sdhci_pltfm_data sdhci_tegra210_pdata = {
  7519.  
  7520.  static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
  7521.     .pdata = &sdhci_tegra210_pdata,
  7522. +   .nvquirks = NVQUIRK_ENABLE_SDR50 |
  7523. +           NVQUIRK_ENABLE_DDR50 |
  7524. +           NVQUIRK_ENABLE_SDR104 |
  7525. +           NVQUIRK_HAS_PADCALIB |
  7526. +           NVQUIRK_NEEDS_PAD_CONTROL,
  7527.  };
  7528.  
  7529.  static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
  7530. @@ -458,6 +488,8 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
  7531.     struct sdhci_tegra *tegra_host;
  7532.     struct clk *clk;
  7533.     int rc;
  7534. +   struct device_node *np = pdev->dev.of_node;
  7535. +   u32 prop;
  7536.  
  7537.     match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
  7538.     if (!match)
  7539. @@ -472,8 +504,14 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
  7540.     tegra_host = sdhci_pltfm_priv(pltfm_host);
  7541.     tegra_host->ddr_signaling = false;
  7542.     tegra_host->pad_calib_required = false;
  7543. +   tegra_host->pad_control = false;
  7544.     tegra_host->soc_data = soc_data;
  7545.  
  7546. +   if (!of_property_read_u32(np, "nvidia,pad", &prop)) {
  7547. +       tegra_host->pad_control = true;
  7548. +       tegra_host->pad_id = prop;
  7549. +   }
  7550. +
  7551.     rc = mmc_of_parse(host->mmc);
  7552.     if (rc)
  7553.         goto err_parse_dt;
  7554. diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
  7555. index 2ededa7..ff44ecb 100644
  7556. --- a/drivers/mmc/host/sdhci.c
  7557. +++ b/drivers/mmc/host/sdhci.c
  7558. @@ -1929,6 +1929,10 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
  7559.     case MMC_SIGNAL_VOLTAGE_330:
  7560.         if (!(host->flags & SDHCI_SIGNALING_330))
  7561.             return -EINVAL;
  7562. +
  7563. +       if (host->ops->pre_voltage_switch)
  7564. +           host->ops->pre_voltage_switch(host, ios);
  7565. +
  7566.         /* Set 1.8V Signal Enable in the Host Control2 register to 0 */
  7567.         ctrl &= ~SDHCI_CTRL_VDD_180;
  7568.         sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  7569. @@ -1941,6 +1945,11 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
  7570.                 return -EIO;
  7571.             }
  7572.         }
  7573. +
  7574. +       /* Some controller need to do more when switching */
  7575. +       if (host->ops->voltage_switch)
  7576. +           host->ops->voltage_switch(host, ios);
  7577. +
  7578.         /* Wait for 5ms */
  7579.         usleep_range(5000, 5500);
  7580.  
  7581. @@ -1956,6 +1965,11 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
  7582.     case MMC_SIGNAL_VOLTAGE_180:
  7583.         if (!(host->flags & SDHCI_SIGNALING_180))
  7584.             return -EINVAL;
  7585. +
  7586. +       /* Some controller need to do more when switching */
  7587. +       if (host->ops->pre_voltage_switch)
  7588. +           host->ops->pre_voltage_switch(host, ios);
  7589. +
  7590.         if (!IS_ERR(mmc->supply.vqmmc)) {
  7591.             ret = mmc_regulator_set_vqmmc(mmc, ios);
  7592.             if (ret) {
  7593. @@ -1974,7 +1988,7 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
  7594.  
  7595.         /* Some controller need to do more when switching */
  7596.         if (host->ops->voltage_switch)
  7597. -           host->ops->voltage_switch(host);
  7598. +           host->ops->voltage_switch(host, ios);
  7599.  
  7600.         /* 1.8V regulator output should be stable within 5 ms */
  7601.         ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  7602. diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
  7603. index c95b0a4..57a0ea8 100644
  7604. --- a/drivers/mmc/host/sdhci.h
  7605. +++ b/drivers/mmc/host/sdhci.h
  7606. @@ -587,7 +587,9 @@ struct sdhci_ops {
  7607.     void    (*hw_reset)(struct sdhci_host *host);
  7608.     void    (*adma_workaround)(struct sdhci_host *host, u32 intmask);
  7609.     void    (*card_event)(struct sdhci_host *host);
  7610. -   void    (*voltage_switch)(struct sdhci_host *host);
  7611. +   void    (*pre_voltage_switch)(struct sdhci_host *host,
  7612. +                     struct mmc_ios *ios);
  7613. +   void    (*voltage_switch)(struct sdhci_host *host, struct mmc_ios *ios);
  7614.  };
  7615.  
  7616.  #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
  7617. diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
  7618. index 485f759..d902b1f 100644
  7619. --- a/drivers/mmc/host/sdhci_f_sdh30.c
  7620. +++ b/drivers/mmc/host/sdhci_f_sdh30.c
  7621. @@ -53,11 +53,16 @@ struct f_sdhost_priv {
  7622.     bool enable_cmd_dat_delay;
  7623.  };
  7624.  
  7625. -static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
  7626. +static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host,
  7627. +                         struct mmc_ios *ios)
  7628.  {
  7629.     struct f_sdhost_priv *priv = sdhci_priv(host);
  7630.     u32 ctrl = 0;
  7631.  
  7632. +   // FIXME: do something when switching back to 3.3V?
  7633. +   if (ios->signal_voltage != MMC_SIGNAL_VOLTAGE_180)
  7634. +       return;
  7635. +
  7636.     usleep_range(2500, 3000);
  7637.     ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2);
  7638.     ctrl |= F_SDH30_CRES_O_DN;
  7639. diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
  7640. index 0d0177c..ba2b273 100644
  7641. --- a/drivers/pci/host/Kconfig
  7642. +++ b/drivers/pci/host/Kconfig
  7643. @@ -36,7 +36,7 @@ config PCI_FTPCI100
  7644.     default ARCH_GEMINI
  7645.  
  7646.  config PCI_TEGRA
  7647. -   bool "NVIDIA Tegra PCIe controller"
  7648. +   tristate "NVIDIA Tegra PCIe controller"
  7649.     depends on ARCH_TEGRA
  7650.     depends on PCI_MSI_IRQ_DOMAIN
  7651.     help
  7652. diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c
  7653. index b58df04..ea31de8 100644
  7654. --- a/drivers/power/supply/bq24190_charger.c
  7655. +++ b/drivers/power/supply/bq24190_charger.c
  7656. @@ -1638,6 +1638,7 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi)
  7657.         return ret;
  7658.  
  7659.     if (v != BQ24190_REG_VPRS_PN_24190 &&
  7660. +       v != BQ24190_REG_VPRS_PN_24192 &&
  7661.         v != BQ24190_REG_VPRS_PN_24192I) {
  7662.         dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
  7663.         return -ENODEV;
  7664. diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c
  7665. index 1a568df..9c85f95 100644
  7666. --- a/drivers/power/supply/max17042_battery.c
  7667. +++ b/drivers/power/supply/max17042_battery.c
  7668. @@ -190,7 +190,7 @@ static int max17042_get_battery_health(struct max17042_chip *chip, int *health)
  7669.  
  7670.     ret = regmap_read(chip->regmap, MAX17042_AvgVCELL, &val);
  7671.     if (ret < 0)
  7672. -       goto health_error;
  7673. +       return ret;
  7674.  
  7675.     /* bits [0-3] unused */
  7676.     vavg = val * 625 / 8;
  7677. @@ -199,7 +199,7 @@ static int max17042_get_battery_health(struct max17042_chip *chip, int *health)
  7678.  
  7679.     ret = regmap_read(chip->regmap, MAX17042_VCELL, &val);
  7680.     if (ret < 0)
  7681. -       goto health_error;
  7682. +       return ret;
  7683.  
  7684.     /* bits [0-3] unused */
  7685.     vbatt = val * 625 / 8;
  7686. @@ -208,35 +208,31 @@ static int max17042_get_battery_health(struct max17042_chip *chip, int *health)
  7687.  
  7688.     if (vavg < chip->pdata->vmin) {
  7689.         *health = POWER_SUPPLY_HEALTH_DEAD;
  7690. -       goto out;
  7691. +       return 0;
  7692.     }
  7693.  
  7694.     if (vbatt > chip->pdata->vmax + MAX17042_VMAX_TOLERANCE) {
  7695.         *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
  7696. -       goto out;
  7697. +       return 0;
  7698.     }
  7699.  
  7700.     ret = max17042_get_temperature(chip, &temp);
  7701.     if (ret < 0)
  7702. -       goto health_error;
  7703. +       return ret;
  7704.  
  7705.     if (temp < chip->pdata->temp_min) {
  7706.         *health = POWER_SUPPLY_HEALTH_COLD;
  7707. -       goto out;
  7708. +       return 0;
  7709.     }
  7710.  
  7711.     if (temp > chip->pdata->temp_max) {
  7712.         *health = POWER_SUPPLY_HEALTH_OVERHEAT;
  7713. -       goto out;
  7714. +       return 0;
  7715.     }
  7716.  
  7717.     *health = POWER_SUPPLY_HEALTH_GOOD;
  7718.  
  7719. -out:
  7720.     return 0;
  7721. -
  7722. -health_error:
  7723. -   return ret;
  7724.  }
  7725.  
  7726.  static int max17042_get_property(struct power_supply *psy,
  7727. diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
  7728. index f8ebbec..ec4fcc7 100644
  7729. --- a/drivers/pwm/pwm-tegra.c
  7730. +++ b/drivers/pwm/pwm-tegra.c
  7731. @@ -93,6 +93,9 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
  7732.     c *= (1 << PWM_DUTY_WIDTH);
  7733.     c = DIV_ROUND_CLOSEST_ULL(c, period_ns);
  7734.  
  7735. +   if (pwm->state.polarity == PWM_POLARITY_INVERSED)
  7736. +       c = (1 << PWM_DUTY_WIDTH) - c;
  7737. +
  7738.     val = (u32)c << PWM_DUTY_SHIFT;
  7739.  
  7740.     /*
  7741. @@ -144,6 +147,35 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
  7742.     return 0;
  7743.  }
  7744.  
  7745. +static int tegra_pwm_set_polarity(struct pwm_chip *chip,
  7746. +               struct pwm_device *pwm,
  7747. +               enum pwm_polarity polarity)
  7748. +{
  7749. +   struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
  7750. +   u32 val, duty;
  7751. +   int err;
  7752. +
  7753. +   if (pwm->state.polarity != polarity) {
  7754. +       if (!pwm_is_enabled(pwm)) {
  7755. +           err = clk_prepare_enable(pc->clk);
  7756. +           if (err < 0)
  7757. +               return err;
  7758. +       }
  7759. +
  7760. +       val = pwm_readl(pc, pwm->hwpwm);
  7761. +       duty = (val >> PWM_DUTY_SHIFT) & ((1 << (PWM_DUTY_WIDTH + 1)) - 1);
  7762. +       val &= ~(((1 << (PWM_DUTY_WIDTH + 1)) - 1) << PWM_DUTY_SHIFT);
  7763. +       duty = (1 << PWM_DUTY_SHIFT) - duty;
  7764. +       val |= duty << PWM_DUTY_SHIFT;
  7765. +       pwm_writel(pc, pwm->hwpwm, val);
  7766. +
  7767. +       if (!pwm_is_enabled(pwm))
  7768. +           clk_disable_unprepare(pc->clk);
  7769. +   }
  7770. +
  7771. +   return 0;
  7772. +}
  7773. +
  7774.  static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
  7775.  {
  7776.     struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
  7777. @@ -177,6 +209,7 @@ static const struct pwm_ops tegra_pwm_ops = {
  7778.     .config = tegra_pwm_config,
  7779.     .enable = tegra_pwm_enable,
  7780.     .disable = tegra_pwm_disable,
  7781. +   .set_polarity = tegra_pwm_set_polarity,
  7782.     .owner = THIS_MODULE,
  7783.  };
  7784.  
  7785. @@ -229,6 +262,8 @@ static int tegra_pwm_probe(struct platform_device *pdev)
  7786.  
  7787.     pwm->chip.dev = &pdev->dev;
  7788.     pwm->chip.ops = &tegra_pwm_ops;
  7789. +   pwm->chip.of_xlate = of_pwm_xlate_with_flags;
  7790. +   pwm->chip.of_pwm_n_cells = 3;
  7791.     pwm->chip.base = -1;
  7792.     pwm->chip.npwm = pwm->soc->num_channels;
  7793.  
  7794. diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
  7795. index d480346..e7de0c6 100644
  7796. --- a/drivers/regulator/core.c
  7797. +++ b/drivers/regulator/core.c
  7798. @@ -3352,6 +3352,37 @@ int regulator_get_voltage(struct regulator *regulator)
  7799.  }
  7800.  EXPORT_SYMBOL_GPL(regulator_get_voltage);
  7801.  
  7802. +/**
  7803. + * regulator_get_constraint_voltages - get platform specific constraint voltage,
  7804. + * @regulator: regulator source
  7805. + * @min_uV: Minimum microvolts.
  7806. + * @max_uV: Maximum microvolts.
  7807. + *
  7808. + * This returns the current regulator voltage in uV.
  7809. + *
  7810. + * NOTE: If the regulator is disabled it will return the voltage value. This
  7811. + * function should not be used to determine regulator state.
  7812. + */
  7813. +
  7814. +int regulator_get_constraint_voltages(struct regulator *regulator,
  7815. +   int *min_uV, int *max_uV)
  7816. +{
  7817. +   struct regulator_dev *rdev = regulator->rdev;
  7818. +
  7819. +   if (rdev->desc && rdev->desc->fixed_uV && rdev->desc->n_voltages == 1) {
  7820. +       *min_uV = rdev->desc->fixed_uV;
  7821. +       *max_uV = rdev->desc->fixed_uV;
  7822. +       return 0;
  7823. +   }
  7824. +   if (rdev->constraints) {
  7825. +       *min_uV = rdev->constraints->min_uV;
  7826. +       *max_uV = rdev->constraints->max_uV;
  7827. +       return 0;
  7828. +   }
  7829. +   return -EINVAL;
  7830. +}
  7831. +EXPORT_SYMBOL_GPL(regulator_get_constraint_voltages);
  7832. +
  7833.  /**
  7834.   * regulator_set_current_limit - set regulator output current limit
  7835.   * @regulator: regulator source
  7836. diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c
  7837. index 5373f4c..e8a08a0 100644
  7838. --- a/drivers/soc/tegra/fuse/speedo-tegra210.c
  7839. +++ b/drivers/soc/tegra/fuse/speedo-tegra210.c
  7840. @@ -69,6 +69,7 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
  7841.                      u8 speedo_rev, int *threshold)
  7842.  {
  7843.     int sku = sku_info->sku_id;
  7844. +   int rev = sku_info->revision;
  7845.  
  7846.     /* Assign to default */
  7847.     sku_info->cpu_speedo_id = 0;
  7848. @@ -77,27 +78,38 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
  7849.     *threshold = THRESHOLD_INDEX_0;
  7850.  
  7851.     switch (sku) {
  7852. -   case 0x00: /* Engineering SKU */
  7853.     case 0x01: /* Engineering SKU */
  7854. +   case 0x13: /* Engineering SKU */
  7855. +       if (rev == TEGRA_REVISION_A02) {
  7856. +           sku_info->cpu_speedo_id = 1;
  7857. +           sku_info->gpu_speedo_id = 2;
  7858. +       }
  7859. +       /* fall through for a01 */
  7860. +   case 0x00: /* Engineering SKU */
  7861.     case 0x07:
  7862.     case 0x17:
  7863.     case 0x27:
  7864. -       if (speedo_rev >= 2)
  7865. -           sku_info->gpu_speedo_id = 1;
  7866. +       sku_info->gpu_speedo_id = 1;
  7867.         break;
  7868. -
  7869. -   case 0x13:
  7870. -       if (speedo_rev >= 2)
  7871. -           sku_info->gpu_speedo_id = 1;
  7872. -
  7873. -       sku_info->cpu_speedo_id = 1;
  7874. +   case 0x83:
  7875. +       if (rev == TEGRA_REVISION_A02) {
  7876. +           sku_info->cpu_speedo_id = 1;
  7877. +           sku_info->gpu_speedo_id = 4;
  7878. +           break;
  7879. +       }
  7880. +       /* fall through for a01 */
  7881. +   case 0x87:
  7882. +       sku_info->gpu_speedo_id = 3;
  7883.         break;
  7884. -
  7885.     default:
  7886.         pr_err("Tegra210: unknown SKU %#04x\n", sku);
  7887.         /* Using the default for the error case */
  7888.         break;
  7889.     }
  7890. +
  7891. +   /* Overwrite GPU speedo selection for speedo revision 0, 1 */
  7892. +   if (speedo_rev < 2)
  7893. +       sku_info->gpu_speedo_id = 0;
  7894.  }
  7895.  
  7896.  static int get_process_id(int value, const u32 *speedos, unsigned int num)
  7897. diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
  7898. index 3e3d12c..8f361cc 100644
  7899. --- a/drivers/soc/tegra/pmc.c
  7900. +++ b/drivers/soc/tegra/pmc.c
  7901. @@ -131,7 +131,7 @@ struct tegra_powergate {
  7902.  };
  7903.  
  7904.  struct tegra_io_pad_soc {
  7905. -   enum tegra_io_pad id;
  7906. +   unsigned int id;
  7907.     unsigned int dpd;
  7908.     unsigned int voltage;
  7909.  };
  7910. @@ -408,6 +408,11 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
  7911.  
  7912.     usleep_range(10, 20);
  7913.  
  7914. +   if (pg->pmc->soc->needs_mbist_war)
  7915. +       err = tegra210_clk_handle_mbist_war(pg->id);
  7916. +   if (err)
  7917. +       goto disable_clks;
  7918. +
  7919.     if (pg->pmc->soc->needs_mbist_war)
  7920.         err = tegra210_clk_handle_mbist_war(pg->id);
  7921.     if (err)
  7922. @@ -907,7 +912,7 @@ static void tegra_powergate_init(struct tegra_pmc *pmc,
  7923.  }
  7924.  
  7925.  static const struct tegra_io_pad_soc *
  7926. -tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
  7927. +tegra_io_pad_find(struct tegra_pmc *pmc, unsigned int id)
  7928.  {
  7929.     unsigned int i;
  7930.  
  7931. @@ -918,7 +923,7 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
  7932.     return NULL;
  7933.  }
  7934.  
  7935. -static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
  7936. +static int tegra_io_pad_prepare(unsigned int id, unsigned long *request,
  7937.                 unsigned long *status, u32 *mask)
  7938.  {
  7939.     const struct tegra_io_pad_soc *pad;
  7940. @@ -991,7 +996,7 @@ static void tegra_io_pad_unprepare(void)
  7941.   *
  7942.   * Returns: 0 on success or a negative error code on failure.
  7943.   */
  7944. -int tegra_io_pad_power_enable(enum tegra_io_pad id)
  7945. +int tegra_io_pad_power_enable(unsigned int id)
  7946.  {
  7947.     unsigned long request, status;
  7948.     u32 mask;
  7949. @@ -1027,7 +1032,7 @@ EXPORT_SYMBOL(tegra_io_pad_power_enable);
  7950.   *
  7951.   * Returns: 0 on success or a negative error code on failure.
  7952.   */
  7953. -int tegra_io_pad_power_disable(enum tegra_io_pad id)
  7954. +int tegra_io_pad_power_disable(unsigned int id)
  7955.  {
  7956.     unsigned long request, status;
  7957.     u32 mask;
  7958. @@ -1057,7 +1062,7 @@ unlock:
  7959.  }
  7960.  EXPORT_SYMBOL(tegra_io_pad_power_disable);
  7961.  
  7962. -int tegra_io_pad_set_voltage(enum tegra_io_pad id,
  7963. +int tegra_io_pad_set_voltage(unsigned int id,
  7964.                  enum tegra_io_pad_voltage voltage)
  7965.  {
  7966.     const struct tegra_io_pad_soc *pad;
  7967. @@ -1095,7 +1100,7 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id,
  7968.  }
  7969.  EXPORT_SYMBOL(tegra_io_pad_set_voltage);
  7970.  
  7971. -int tegra_io_pad_get_voltage(enum tegra_io_pad id)
  7972. +int tegra_io_pad_get_voltage(unsigned int id)
  7973.  {
  7974.     const struct tegra_io_pad_soc *pad;
  7975.     u32 value;
  7976. diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
  7977. index e09f035..11f5d87 100644
  7978. --- a/drivers/thermal/of-thermal.c
  7979. +++ b/drivers/thermal/of-thermal.c
  7980. @@ -993,8 +993,7 @@ int __init of_parse_thermal_zones(void)
  7981.             goto exit_free;
  7982.         }
  7983.  
  7984. -       /* No hwmon because there might be hwmon drivers registering */
  7985. -       tzp->no_hwmon = true;
  7986. +       tzp->no_hwmon = !of_property_read_bool(child, "hwmon");
  7987.  
  7988.         if (!of_property_read_u32(child, "sustainable-power", &prop))
  7989.             tzp->sustainable_power = prop;
  7990. diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
  7991. index af2a29c..aecb97d 100644
  7992. --- a/drivers/tty/serial/serial-tegra.c
  7993. +++ b/drivers/tty/serial/serial-tegra.c
  7994. @@ -46,6 +46,10 @@
  7995.  #define TEGRA_UART_LSR_ANY         (UART_LSR_OE | UART_LSR_BI | \
  7996.                         UART_LSR_PE | UART_LSR_FE)
  7997.  #define TEGRA_UART_IRDA_CSR            0x08
  7998. +#define TEGRA_UART_INVERT_RXD          0x01
  7999. +#define TEGRA_UART_INVERT_TXD          0x02
  8000. +#define TEGRA_UART_INVERT_CTS          0x04
  8001. +#define TEGRA_UART_INVERT_RTS          0x08
  8002.  #define TEGRA_UART_SIR_ENABLED         0x80
  8003.  
  8004.  #define TEGRA_UART_TX_PIO          1
  8005. @@ -99,12 +103,17 @@ struct tegra_uart_port {
  8006.     unsigned long               mcr_shadow;
  8007.     unsigned long               lcr_shadow;
  8008.     unsigned long               ier_shadow;
  8009. +   unsigned long               irda_csr_shadow;
  8010.     bool                    rts_active;
  8011.  
  8012.     int                 tx_in_progress;
  8013.     unsigned int                tx_bytes;
  8014.  
  8015.     bool                    enable_modem_interrupt;
  8016. +   bool                    invert_rxd;
  8017. +   bool                    invert_txd;
  8018. +   bool                    invert_cts;
  8019. +   bool                    invert_rts;
  8020.  
  8021.     bool                    rx_timeout;
  8022.     int                 rx_in_progress;
  8023. @@ -1148,6 +1157,17 @@ static void tegra_uart_set_termios(struct uart_port *u,
  8024.         tty_termios_encode_baud_rate(termios, baud, baud);
  8025.     spin_lock_irqsave(&u->lock, flags);
  8026.  
  8027. +   /* Line inversions */
  8028. +   if (tup->invert_rxd)
  8029. +       tup->irda_csr_shadow |= TEGRA_UART_INVERT_RXD;
  8030. +   if (tup->invert_txd)
  8031. +       tup->irda_csr_shadow |= TEGRA_UART_INVERT_TXD;
  8032. +   if (tup->invert_cts)
  8033. +       tup->irda_csr_shadow |= TEGRA_UART_INVERT_CTS;
  8034. +   if (tup->invert_rts)
  8035. +       tup->irda_csr_shadow |= TEGRA_UART_INVERT_RTS;
  8036. +   tegra_uart_write(tup, tup->irda_csr_shadow, TEGRA_UART_IRDA_CSR);
  8037. +
  8038.     /* Flow control */
  8039.     if (termios->c_cflag & CRTSCTS) {
  8040.         tup->mcr_shadow |= TEGRA_UART_MCR_CTS_EN;
  8041. @@ -1221,6 +1241,14 @@ static int tegra_uart_parse_dt(struct platform_device *pdev,
  8042.  
  8043.     tup->enable_modem_interrupt = of_property_read_bool(np,
  8044.                     "nvidia,enable-modem-interrupt");
  8045. +   tup->invert_rxd = of_property_read_bool(np,
  8046. +                   "nvidia,invert-rxd");
  8047. +   tup->invert_txd = of_property_read_bool(np,
  8048. +                   "nvidia,invert-txd");
  8049. +   tup->invert_cts = of_property_read_bool(np,
  8050. +                   "nvidia,invert-cts");
  8051. +   tup->invert_rts = of_property_read_bool(np,
  8052. +                   "nvidia,invert-rts");
  8053.     return 0;
  8054.  }
  8055.  
  8056. diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
  8057. index 4d5f5d6..0797a04 100644
  8058. --- a/include/drm/drm_prime.h
  8059. +++ b/include/drm/drm_prime.h
  8060. @@ -50,8 +50,10 @@ struct drm_prime_file_private {
  8061.     struct rb_root handles;
  8062.  };
  8063.  
  8064. +enum dma_data_direction;
  8065.  struct device;
  8066.  
  8067. +struct dma_buf_attachment;
  8068.  struct dma_buf_export_info;
  8069.  struct dma_buf;
  8070.  struct dma_buf_attachment;
  8071. @@ -62,7 +64,15 @@ struct drm_device;
  8072.  struct drm_gem_object;
  8073.  struct drm_file;
  8074.  
  8075. -struct device;
  8076. +int drm_gem_map_attach(struct dma_buf *dma_buf, struct device *target_dev,
  8077. +              struct dma_buf_attachment *attach);
  8078. +void drm_gem_map_detach(struct dma_buf *dma_buf,
  8079. +           struct dma_buf_attachment *attach);
  8080. +struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
  8081. +                    enum dma_data_direction dir);
  8082. +void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
  8083. +              struct sg_table *sgt,
  8084. +              enum dma_data_direction dir);
  8085.  
  8086.  struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
  8087.                      struct drm_gem_object *obj,
  8088. diff --git a/include/dt-bindings/soc/tegra/pmc.h b/include/dt-bindings/soc/tegra/pmc.h
  8089. new file mode 100644
  8090. index 0000000..65bddda
  8091. --- /dev/null
  8092. +++ b/include/dt-bindings/soc/tegra/pmc.h
  8093. @@ -0,0 +1,79 @@
  8094. +/*
  8095. + * Copyright (c) 2010 Google, Inc
  8096. + * Copyright (c) 2014 NVIDIA Corporation
  8097. + *
  8098. + * Author:
  8099. + * Colin Cross <ccross@google.com>
  8100. + *
  8101. + * This software is licensed under the terms of the GNU General Public
  8102. + * License version 2, as published by the Free Software Foundation, and
  8103. + * may be copied, distributed, and modified under those terms.
  8104. + *
  8105. + * This program is distributed in the hope that it will be useful
  8106. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8107. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  8108. + * GNU General Public License for more details.
  8109. + *
  8110. + */
  8111. +
  8112. +#ifndef _DT_BINDINGS_SOC_TEGRA_PMC_H
  8113. +#define _DT_BINDINGS_SOC_TEGRA_PMC_H
  8114. +
  8115. +#define TEGRA_IO_PAD_AUDIO     0
  8116. +#define TEGRA_IO_PAD_AUDIO_HV      1
  8117. +#define TEGRA_IO_PAD_BB            2
  8118. +#define TEGRA_IO_PAD_CAM       3
  8119. +#define TEGRA_IO_PAD_COMP      4
  8120. +#define TEGRA_IO_PAD_CONN      5
  8121. +#define TEGRA_IO_PAD_CSIA      6
  8122. +#define TEGRA_IO_PAD_CSIB      7
  8123. +#define TEGRA_IO_PAD_CSIC      8
  8124. +#define TEGRA_IO_PAD_CSID      9
  8125. +#define TEGRA_IO_PAD_CSIE      10
  8126. +#define TEGRA_IO_PAD_CSIF      11
  8127. +#define TEGRA_IO_PAD_DBG       12
  8128. +#define TEGRA_IO_PAD_DEBUG_NONAO   13
  8129. +#define TEGRA_IO_PAD_DMIC      14
  8130. +#define TEGRA_IO_PAD_DMIC_HV       15
  8131. +#define TEGRA_IO_PAD_DP            16
  8132. +#define TEGRA_IO_PAD_DSI       17
  8133. +#define TEGRA_IO_PAD_DSIB      18
  8134. +#define TEGRA_IO_PAD_DSIC      19
  8135. +#define TEGRA_IO_PAD_DSID      20
  8136. +#define TEGRA_IO_PAD_EDP       21
  8137. +#define TEGRA_IO_PAD_EMMC      22
  8138. +#define TEGRA_IO_PAD_EMMC2     23
  8139. +#define TEGRA_IO_PAD_GPIO      24
  8140. +#define TEGRA_IO_PAD_HDMI      25
  8141. +#define TEGRA_IO_PAD_HDMI_DP0      26
  8142. +#define TEGRA_IO_PAD_HDMI_DP1      27
  8143. +#define TEGRA_IO_PAD_HSIC      28
  8144. +#define TEGRA_IO_PAD_HV            29
  8145. +#define TEGRA_IO_PAD_LVDS      30
  8146. +#define TEGRA_IO_PAD_MIPI_BIAS     31
  8147. +#define TEGRA_IO_PAD_NAND      32
  8148. +#define TEGRA_IO_PAD_PEX_BIAS      33
  8149. +#define TEGRA_IO_PAD_PEX_CLK_BIAS  34
  8150. +#define TEGRA_IO_PAD_PEX_CLK1      35
  8151. +#define TEGRA_IO_PAD_PEX_CLK2      36
  8152. +#define TEGRA_IO_PAD_PEX_CLK3      37
  8153. +#define TEGRA_IO_PAD_PEX_CNTRL     38
  8154. +#define TEGRA_IO_PAD_SDMMC1        39
  8155. +#define TEGRA_IO_PAD_SDMMC1_HV     40
  8156. +#define TEGRA_IO_PAD_SDMMC2        41
  8157. +#define TEGRA_IO_PAD_SDMMC2_HV     42
  8158. +#define TEGRA_IO_PAD_SDMMC3        43
  8159. +#define TEGRA_IO_PAD_SDMMC3_HV     44
  8160. +#define TEGRA_IO_PAD_SDMMC4        45
  8161. +#define TEGRA_IO_PAD_SPI       46
  8162. +#define TEGRA_IO_PAD_SPI_HV        47
  8163. +#define TEGRA_IO_PAD_SYS_DDC       48
  8164. +#define TEGRA_IO_PAD_UART      49
  8165. +#define TEGRA_IO_PAD_UFS       50
  8166. +#define TEGRA_IO_PAD_USB0      51
  8167. +#define TEGRA_IO_PAD_USB1      52
  8168. +#define TEGRA_IO_PAD_USB2      53
  8169. +#define TEGRA_IO_PAD_USB3      54
  8170. +#define TEGRA_IO_PAD_USB_BIAS      55
  8171. +
  8172. +#endif /* _DT_BINDINGS_SOC_TEGRA_PMC_H */
  8173. diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
  8174. index afb9edf..79809de 100644
  8175. --- a/include/linux/clk/tegra.h
  8176. +++ b/include/linux/clk/tegra.h
  8177. @@ -128,6 +128,11 @@ extern void tegra210_sata_pll_hw_sequence_start(void);
  8178.  extern void tegra210_set_sata_pll_seq_sw(bool state);
  8179.  extern void tegra210_put_utmipll_in_iddq(void);
  8180.  extern void tegra210_put_utmipll_out_iddq(void);
  8181. +#ifndef CONFIG_ARCH_TEGRA_210_SOC
  8182. +static inline int tegra210_clk_handle_mbist_war(unsigned int id)
  8183. +{ return -ENODEV; }
  8184. +#else
  8185.  extern int tegra210_clk_handle_mbist_war(unsigned int id);
  8186. +#endif
  8187.  
  8188.  #endif /* __LINUX_CLK_TEGRA_H_ */
  8189. diff --git a/include/linux/host1x.h b/include/linux/host1x.h
  8190. index ddf7f9c..fd4daa7 100644
  8191. --- a/include/linux/host1x.h
  8192. +++ b/include/linux/host1x.h
  8193. @@ -1,5 +1,5 @@
  8194.  /*
  8195. - * Copyright (c) 2009-2013, NVIDIA Corporation. All rights reserved.
  8196. + * Copyright (C) 2009-2016 NVIDIA CORPORATION.  All rights reserved.
  8197.   *
  8198.   * This program is free software; you can redistribute it and/or modify
  8199.   * it under the terms of the GNU General Public License as published by
  8200. @@ -71,6 +71,7 @@ struct host1x_client {
  8201.   * host1x buffer objects
  8202.   */
  8203.  
  8204. +struct dma_fence;
  8205.  struct host1x_bo;
  8206.  struct sg_table;
  8207.  
  8208. @@ -258,6 +259,9 @@ struct host1x_job {
  8209.  
  8210.     /* Add a channel wait for previous ops to complete */
  8211.     bool serialize;
  8212. +
  8213. +   /* Wait for prefence to complete before submitting */
  8214. +   struct dma_fence *prefence;
  8215.  };
  8216.  
  8217.  struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,
  8218. @@ -343,4 +347,10 @@ int tegra_mipi_enable(struct tegra_mipi_device *device);
  8219.  int tegra_mipi_disable(struct tegra_mipi_device *device);
  8220.  int tegra_mipi_calibrate(struct tegra_mipi_device *device);
  8221.  
  8222. +struct host1x_fence;
  8223. +
  8224. +struct dma_fence *host1x_fence_create(struct host1x *host,
  8225. +                     struct host1x_syncpt *syncpt,
  8226. +                     u32 threshold);
  8227. +
  8228.  #endif
  8229. diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
  8230. index 25602af..1b212aa 100644
  8231. --- a/include/linux/regulator/consumer.h
  8232. +++ b/include/linux/regulator/consumer.h
  8233. @@ -251,6 +251,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
  8234.  int regulator_set_voltage_time(struct regulator *regulator,
  8235.                    int old_uV, int new_uV);
  8236.  int regulator_get_voltage(struct regulator *regulator);
  8237. +int regulator_get_constraint_voltages(struct regulator *regulator,
  8238. +   int *min_uV, int *max_uV);
  8239.  int regulator_sync_voltage(struct regulator *regulator);
  8240.  int regulator_set_current_limit(struct regulator *regulator,
  8241.                    int min_uA, int max_uA);
  8242. diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h
  8243. index c32bf91..14bac22 100644
  8244. --- a/include/soc/tegra/pmc.h
  8245. +++ b/include/soc/tegra/pmc.h
  8246. @@ -22,6 +22,7 @@
  8247.  #include <linux/reboot.h>
  8248.  
  8249.  #include <soc/tegra/pm.h>
  8250. +#include <dt-bindings/soc/tegra/pmc.h>
  8251.  
  8252.  struct clk;
  8253.  struct reset_control;
  8254. @@ -70,72 +71,6 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid);
  8255.  
  8256.  #define TEGRA_POWERGATE_3D0    TEGRA_POWERGATE_3D
  8257.  
  8258. -/**
  8259. - * enum tegra_io_pad - I/O pad group identifier
  8260. - *
  8261. - * I/O pins on Tegra SoCs are grouped into so-called I/O pads. Each such pad
  8262. - * can be used to control the common voltage signal level and power state of
  8263. - * the pins of the given pad.
  8264. - */
  8265. -enum tegra_io_pad {
  8266. -   TEGRA_IO_PAD_AUDIO,
  8267. -   TEGRA_IO_PAD_AUDIO_HV,
  8268. -   TEGRA_IO_PAD_BB,
  8269. -   TEGRA_IO_PAD_CAM,
  8270. -   TEGRA_IO_PAD_COMP,
  8271. -   TEGRA_IO_PAD_CONN,
  8272. -   TEGRA_IO_PAD_CSIA,
  8273. -   TEGRA_IO_PAD_CSIB,
  8274. -   TEGRA_IO_PAD_CSIC,
  8275. -   TEGRA_IO_PAD_CSID,
  8276. -   TEGRA_IO_PAD_CSIE,
  8277. -   TEGRA_IO_PAD_CSIF,
  8278. -   TEGRA_IO_PAD_DBG,
  8279. -   TEGRA_IO_PAD_DEBUG_NONAO,
  8280. -   TEGRA_IO_PAD_DMIC,
  8281. -   TEGRA_IO_PAD_DMIC_HV,
  8282. -   TEGRA_IO_PAD_DP,
  8283. -   TEGRA_IO_PAD_DSI,
  8284. -   TEGRA_IO_PAD_DSIB,
  8285. -   TEGRA_IO_PAD_DSIC,
  8286. -   TEGRA_IO_PAD_DSID,
  8287. -   TEGRA_IO_PAD_EDP,
  8288. -   TEGRA_IO_PAD_EMMC,
  8289. -   TEGRA_IO_PAD_EMMC2,
  8290. -   TEGRA_IO_PAD_GPIO,
  8291. -   TEGRA_IO_PAD_HDMI,
  8292. -   TEGRA_IO_PAD_HDMI_DP0,
  8293. -   TEGRA_IO_PAD_HDMI_DP1,
  8294. -   TEGRA_IO_PAD_HSIC,
  8295. -   TEGRA_IO_PAD_HV,
  8296. -   TEGRA_IO_PAD_LVDS,
  8297. -   TEGRA_IO_PAD_MIPI_BIAS,
  8298. -   TEGRA_IO_PAD_NAND,
  8299. -   TEGRA_IO_PAD_PEX_BIAS,
  8300. -   TEGRA_IO_PAD_PEX_CLK_BIAS,
  8301. -   TEGRA_IO_PAD_PEX_CLK1,
  8302. -   TEGRA_IO_PAD_PEX_CLK2,
  8303. -   TEGRA_IO_PAD_PEX_CLK3,
  8304. -   TEGRA_IO_PAD_PEX_CNTRL,
  8305. -   TEGRA_IO_PAD_SDMMC1,
  8306. -   TEGRA_IO_PAD_SDMMC1_HV,
  8307. -   TEGRA_IO_PAD_SDMMC2,
  8308. -   TEGRA_IO_PAD_SDMMC2_HV,
  8309. -   TEGRA_IO_PAD_SDMMC3,
  8310. -   TEGRA_IO_PAD_SDMMC3_HV,
  8311. -   TEGRA_IO_PAD_SDMMC4,
  8312. -   TEGRA_IO_PAD_SPI,
  8313. -   TEGRA_IO_PAD_SPI_HV,
  8314. -   TEGRA_IO_PAD_SYS_DDC,
  8315. -   TEGRA_IO_PAD_UART,
  8316. -   TEGRA_IO_PAD_UFS,
  8317. -   TEGRA_IO_PAD_USB0,
  8318. -   TEGRA_IO_PAD_USB1,
  8319. -   TEGRA_IO_PAD_USB2,
  8320. -   TEGRA_IO_PAD_USB3,
  8321. -   TEGRA_IO_PAD_USB_BIAS,
  8322. -};
  8323. -
  8324.  /* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */
  8325.  #define TEGRA_IO_RAIL_HDMI TEGRA_IO_PAD_HDMI
  8326.  #define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS
  8327. @@ -160,11 +95,11 @@ int tegra_powergate_remove_clamping(unsigned int id);
  8328.  int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
  8329.                       struct reset_control *rst);
  8330.  
  8331. -int tegra_io_pad_power_enable(enum tegra_io_pad id);
  8332. -int tegra_io_pad_power_disable(enum tegra_io_pad id);
  8333. -int tegra_io_pad_set_voltage(enum tegra_io_pad id,
  8334. +int tegra_io_pad_power_enable(unsigned int id);
  8335. +int tegra_io_pad_power_disable(unsigned int id);
  8336. +int tegra_io_pad_set_voltage(unsigned int id,
  8337.                  enum tegra_io_pad_voltage voltage);
  8338. -int tegra_io_pad_get_voltage(enum tegra_io_pad id);
  8339. +int tegra_io_pad_get_voltage(unsigned int id);
  8340.  
  8341.  /* deprecated, use tegra_io_pad_power_{enable,disable}() instead */
  8342.  int tegra_io_rail_power_on(unsigned int id);
  8343. @@ -202,23 +137,23 @@ static inline int tegra_powergate_sequence_power_up(unsigned int id,
  8344.     return -ENOSYS;
  8345.  }
  8346.  
  8347. -static inline int tegra_io_pad_power_enable(enum tegra_io_pad id)
  8348. +static inline int tegra_io_pad_power_enable(unsigned int id)
  8349.  {
  8350.     return -ENOSYS;
  8351.  }
  8352.  
  8353. -static inline int tegra_io_pad_power_disable(enum tegra_io_pad id)
  8354. +static inline int tegra_io_pad_power_disable(unsigned int id)
  8355.  {
  8356.     return -ENOSYS;
  8357.  }
  8358.  
  8359. -static inline int tegra_io_pad_set_voltage(enum tegra_io_pad id,
  8360. +static inline int tegra_io_pad_set_voltage(unsigned int id,
  8361.                        enum tegra_io_pad_voltage voltage)
  8362.  {
  8363.     return -ENOSYS;
  8364.  }
  8365.  
  8366. -static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id)
  8367. +static inline int tegra_io_pad_get_voltage(unsigned int id)
  8368.  {
  8369.     return -ENOSYS;
  8370.  }
  8371. diff --git a/include/uapi/drm/nouveau_drm.h b/include/uapi/drm/nouveau_drm.h
  8372. index 259588a..e50e655 100644
  8373. --- a/include/uapi/drm/nouveau_drm.h
  8374. +++ b/include/uapi/drm/nouveau_drm.h
  8375. @@ -114,6 +114,18 @@ struct drm_nouveau_gem_pushbuf {
  8376.     __u64 gart_available;
  8377.  };
  8378.  
  8379. +#define NOUVEAU_GEM_PUSHBUF_FENCE_WAIT (1 << 0)
  8380. +#define NOUVEAU_GEM_PUSHBUF_FENCE_EMIT (1 << 1)
  8381. +#define NOUVEAU_GEM_PUSHBUF_FLAGS (NOUVEAU_GEM_PUSHBUF_FENCE_WAIT | \
  8382. +                  NOUVEAU_GEM_PUSHBUF_FENCE_EMIT)
  8383. +
  8384. +struct drm_nouveau_gem_pushbuf2 {
  8385. +   struct drm_nouveau_gem_pushbuf base;
  8386. +   __u32 flags;
  8387. +   __s32 fence;
  8388. +   __u64 reserved;
  8389. +};
  8390. +
  8391.  #define NOUVEAU_GEM_CPU_PREP_NOWAIT                                  0x00000001
  8392.  #define NOUVEAU_GEM_CPU_PREP_WRITE                                   0x00000004
  8393.  struct drm_nouveau_gem_cpu_prep {
  8394. @@ -138,12 +150,14 @@ struct drm_nouveau_gem_cpu_fini {
  8395.  #define DRM_NOUVEAU_GEM_CPU_PREP       0x42
  8396.  #define DRM_NOUVEAU_GEM_CPU_FINI       0x43
  8397.  #define DRM_NOUVEAU_GEM_INFO           0x44
  8398. +#define DRM_NOUVEAU_GEM_PUSHBUF2       0x45
  8399.  
  8400.  #define DRM_IOCTL_NOUVEAU_GEM_NEW            DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
  8401.  #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF        DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
  8402.  #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP       DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)
  8403.  #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI       DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini)
  8404.  #define DRM_IOCTL_NOUVEAU_GEM_INFO           DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info)
  8405. +#define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF2       DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF2, struct drm_nouveau_gem_pushbuf2)
  8406.  
  8407.  #if defined(__cplusplus)
  8408.  }
  8409. diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h
  8410. index d954f8c..03492d6 100644
  8411. --- a/include/uapi/drm/tegra_drm.h
  8412. +++ b/include/uapi/drm/tegra_drm.h
  8413. @@ -117,6 +117,11 @@ struct drm_tegra_waitchk {
  8414.     __u32 thresh;
  8415.  };
  8416.  
  8417. +#define DRM_TEGRA_SUBMIT_WAIT_FENCE_FD     (1 << 0)
  8418. +#define DRM_TEGRA_SUBMIT_CREATE_FENCE_FD   (1 << 1)
  8419. +#define DRM_TEGRA_SUBMIT_FLAGS (DRM_TEGRA_SUBMIT_WAIT_FENCE_FD | \
  8420. +               DRM_TEGRA_SUBMIT_CREATE_FENCE_FD)
  8421. +
  8422.  struct drm_tegra_submit {
  8423.     __u64 context;
  8424.     __u32 num_syncpts;
  8425. @@ -129,9 +134,10 @@ struct drm_tegra_submit {
  8426.     __u64 cmdbufs;
  8427.     __u64 relocs;
  8428.     __u64 waitchks;
  8429. -   __u32 fence;        /* Return value */
  8430. +   __u32 fence;
  8431. +   __u32 flags;
  8432.  
  8433. -   __u32 reserved[5];  /* future expansion */
  8434. +   __u32 reserved[4];  /* future expansion */
  8435.  };
  8436.  
  8437.  #define DRM_TEGRA_GEM_TILING_MODE_PITCH 0
Add Comment
Please, Sign In to add comment