Lines Matching +full:dsp +full:- +full:uart1 +full:- +full:tx
6 Change-Id: I9825adaa8537a316db8a1831e759a74223b9e428
7 ---
9 drivers/block/nbd.c | 6 -
12 drivers/clk/clk.c | 2 +-
13 drivers/clk/rockchip/Kconfig | 42 +-
15 drivers/clk/rockchip/clk-cpu.c | 92 +-
16 drivers/clk/rockchip/clk-ddr.c | 171 +-
17 drivers/clk/rockchip/clk-half-divider.c | 35 +-
18 drivers/clk/rockchip/clk-pll.c | 779 ++-
19 drivers/clk/rockchip/clk-rk3399.c | 589 +-
20 drivers/clk/rockchip/clk.c | 200 +-
21 drivers/clk/rockchip/clk.h | 358 +-
22 drivers/clocksource/Kconfig | 4 +-
23 drivers/clocksource/timer-rockchip.c | 33 +
25 drivers/cpufreq/Makefile | 3 +-
26 drivers/cpufreq/cpufreq-dt-platdev.c | 37 +-
27 drivers/cpufreq/cpufreq-dt.c | 168 +-
28 drivers/cpufreq/cpufreq.c | 7 +-
29 drivers/cpufreq/cpufreq_userspace.c | 6 +-
32 drivers/devfreq/Kconfig | 13 +-
33 drivers/devfreq/Makefile | 5 +-
37 drivers/devfreq/event/rockchip-dfi.c | 563 +-
38 drivers/dma-buf/Kconfig | 3 +-
39 drivers/dma-buf/dma-buf-sysfs-stats.h | 27 +
40 drivers/dma-buf/dma-buf.c | 144 +-
41 drivers/dma-buf/dma-fence.c | 70 +-
42 drivers/dma-buf/dma-heap.c | 221 +-
43 drivers/dma-buf/heaps/Kconfig | 16 +-
44 drivers/dma-buf/heaps/Makefile | 3 +-
45 drivers/dma-buf/heaps/cma_heap.c | 336 +-
46 drivers/dma-buf/heaps/system_heap.c | 575 +-
47 drivers/dma-buf/sw_sync.c | 12 +
48 drivers/dma-buf/sync_debug.c | 2 +
49 drivers/dma-buf/sync_debug.h | 7 +
50 drivers/firmware/Kconfig | 9 +-
54 drivers/gpio/gpiolib-of.c | 11 +
55 drivers/gpio/gpiolib-of.h | 5 +
56 drivers/gpu/Makefile | 2 +-
57 drivers/gpu/drm/Kconfig | 24 +-
58 drivers/gpu/drm/Makefile | 11 +-
59 drivers/gpu/drm/amd/display/Kconfig | 2 -
62 .../drm/bridge/analogix/analogix_dp_core.c | 953 ++--
63 .../drm/bridge/analogix/analogix_dp_core.h | 61 +-
64 .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 1054 ++--
65 .../gpu/drm/bridge/analogix/analogix_dp_reg.h | 99 +-
66 drivers/gpu/drm/bridge/display-connector.c | 132 +-
67 drivers/gpu/drm/bridge/lontium-lt9611.c | 8 +-
68 drivers/gpu/drm/bridge/nwl-dsi.c | 2 +-
69 drivers/gpu/drm/bridge/sii902x.c | 280 +-
70 drivers/gpu/drm/bridge/synopsys/Makefile | 7 +-
71 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 3 +
72 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1747 +++++-
73 drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 55 +
74 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 111 +-
75 drivers/gpu/drm/drm_atomic_helper.c | 12 +-
78 drivers/gpu/drm/drm_auth.c | 42 +-
79 drivers/gpu/drm/drm_color_mgmt.c | 41 +-
81 drivers/gpu/drm/drm_debugfs.c | 3 +-
82 drivers/gpu/drm/drm_edid.c | 122 +-
83 drivers/gpu/drm/drm_file.c | 69 +-
85 drivers/gpu/drm/drm_ioctl.c | 8 +-
86 drivers/gpu/drm/drm_lease.c | 81 +-
91 drivers/gpu/drm/drm_vblank.c | 9 +-
92 .../gpu/drm/hisilicon/kirin/kirin_ade_reg.h | 4 +-
93 drivers/gpu/drm/panel/Kconfig | 1 -
95 drivers/gpu/drm/panel/panel-simple.c | 511 +-
96 drivers/gpu/drm/panfrost/panfrost_device.h | 8 +-
97 drivers/gpu/drm/panfrost/panfrost_drv.c | 50 +-
98 drivers/gpu/drm/panfrost/panfrost_gem.c | 20 +-
99 drivers/gpu/drm/panfrost/panfrost_job.c | 4 +-
100 drivers/gpu/drm/panfrost/panfrost_mmu.c | 198 +-
101 drivers/gpu/drm/panfrost/panfrost_mmu.h | 5 +-
102 drivers/gpu/drm/panfrost/panfrost_regs.h | 2 -
103 drivers/gpu/drm/rockchip/Kconfig | 73 +-
104 drivers/gpu/drm/rockchip/Makefile | 18 +-
105 .../gpu/drm/rockchip/analogix_dp-rockchip.c | 422 +-
106 drivers/gpu/drm/rockchip/cdn-dp-core.c | 109 +-
107 drivers/gpu/drm/rockchip/cdn-dp-core.h | 5 +-
108 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 596 ++-
109 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 3202 ++++++++++-
110 drivers/gpu/drm/rockchip/inno_hdmi.c | 2 +-
111 drivers/gpu/drm/rockchip/rk3066_hdmi.c | 2 +-
112 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1454 ++++-
113 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 430 +-
114 drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 153 +-
116 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 18 +-
117 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 637 ++-
118 drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 47 +-
119 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4724 +++++++++++++----
120 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1156 +++-
121 drivers/gpu/drm/rockchip/rockchip_lvds.c | 964 ++--
122 drivers/gpu/drm/rockchip/rockchip_rgb.c | 557 +-
123 drivers/gpu/drm/rockchip/rockchip_rgb.h | 6 +-
124 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2524 ++++++---
125 drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 818 ++-
126 drivers/i2c/busses/i2c-rk3x.c | 383 +-
127 drivers/i2c/i2c-core-base.c | 51 +-
129 drivers/iio/adc/rockchip_saradc.c | 143 +-
134 drivers/iommu/Kconfig | 3 +-
135 drivers/iommu/dma-iommu.c | 50 +
136 drivers/iommu/iommu.c | 155 +-
137 drivers/iommu/rockchip-iommu.c | 690 ++-
138 drivers/irqchip/Kconfig | 5 +-
139 drivers/irqchip/irq-gic-v3-its.c | 60 +-
140 drivers/irqchip/irq-gic-v3.c | 26 +
141 drivers/irqchip/irq-gic-v4.c | 19 +
142 drivers/irqchip/irq-meson-gpio.c | 89 +-
143 drivers/mailbox/rockchip-mailbox.c | 135 +-
148 drivers/media/usb/uvc/uvc_driver.c | 7 +-
149 drivers/media/v4l2-core/v4l2-async.c | 54 +
150 drivers/mfd/rk808.c | 928 +++-
155 drivers/mmc/core/sdio.c | 424 +-
157 drivers/mmc/host/dw_mmc-rockchip.c | 95 +-
159 drivers/mmc/host/sdhci-of-dwcmshc.c | 260 +-
160 drivers/net/ethernet/stmicro/stmmac/Makefile | 3 +-
161 .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 932 +++-
165 drivers/nvmem/rockchip-efuse.c | 348 +-
166 drivers/nvmem/rockchip-otp.c | 22 +-
168 drivers/opp/of.c | 2 +-
169 drivers/pci/controller/Makefile | 6 +-
172 drivers/pci/controller/dwc/pcie-designware.h | 1 +
173 drivers/pci/controller/pcie-rockchip.c | 5 +
175 drivers/phy/rockchip/Makefile | 12 +-
176 .../phy/rockchip/phy-rockchip-inno-dsidphy.c | 434 +-
177 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2597 +++++++--
178 drivers/phy/rockchip/phy-rockchip-pcie.c | 12 +-
179 drivers/phy/rockchip/phy-rockchip-typec.c | 733 ++-
180 drivers/phy/rockchip/phy-rockchip-usb.c | 628 ++-
181 drivers/pinctrl/Kconfig | 7 +-
183 drivers/pinctrl/pinctrl-rk805.c | 350 +-
184 drivers/pinctrl/pinctrl-rockchip.c | 2862 +++++-----
185 drivers/power/reset/gpio-poweroff.c | 1 -
186 drivers/power/supply/Kconfig | 17 +-
189 drivers/pwm/pwm-rockchip.c | 109 +-
191 drivers/regulator/Kconfig | 10 +-
193 drivers/regulator/core.c | 346 +-
194 drivers/regulator/fan53555.c | 399 +-
195 drivers/regulator/of_regulator.c | 8 +-
196 drivers/regulator/rk808-regulator.c | 534 +-
197 drivers/rtc/rtc-hym8563.c | 64 +-
198 drivers/soc/rockchip/Kconfig | 119 +-
201 drivers/soc/rockchip/io-domain.c | 95 +-
202 drivers/soc/rockchip/pm_domains.c | 870 ++-
203 drivers/spi/spi-rockchip.c | 172 +-
207 drivers/thermal/rockchip_thermal.c | 584 +-
209 drivers/thermal/thermal_core.h | 2 -
211 drivers/tty/serial/8250/8250_core.c | 10 +-
212 drivers/tty/serial/8250/8250_dma.c | 205 +-
213 drivers/tty/serial/8250/8250_dw.c | 92 +-
215 drivers/tty/serial/8250/8250_port.c | 103 +-
217 drivers/usb/core/hub.c | 3 +-
220 drivers/usb/gadget/composite.c | 104 +-
221 drivers/usb/gadget/configfs.c | 281 +-
223 drivers/usb/gadget/function/f_fs.c | 14 +-
224 drivers/usb/gadget/function/f_uvc.c | 448 +-
225 drivers/usb/gadget/function/u_uvc.h | 9 +-
226 drivers/usb/gadget/function/uvc.h | 9 +-
228 drivers/usb/gadget/function/uvc_v4l2.c | 24 +-
229 drivers/usb/gadget/function/uvc_video.c | 40 +-
230 drivers/usb/gadget/udc/core.c | 2 +-
237 229 files changed, 37333 insertions(+), 8857 deletions(-)
239 diff --git a/drivers/Makefile b/drivers/Makefile
241 --- a/drivers/Makefile
243 @@ -6,6 +6,8 @@
244 # Rewritten to use lists instead of if-statements.
249 obj-y += irqchip/
250 obj-y += bus/
252 diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
254 --- a/drivers/block/nbd.c
256 @@ -2386,12 +2386,6 @@ static int nbd_genl_status(struct sk_buff *skb, struct genl_info *info)
260 - if (!dev_list) {
261 - nlmsg_free(reply);
262 - ret = -EMSGSIZE;
263 - goto out;
264 - }
265 -
266 if (index == -1) {
269 diff --git a/drivers/char/Makefile b/drivers/char/Makefile
271 --- a/drivers/char/Makefile
273 @@ -3,6 +3,8 @@
277 +obj-y += jy.o
278 +obj-y += mcu.o
279 obj-y += mem.o random.o
280 obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o
281 obj-y += misc.o
282 diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
284 --- a/drivers/clk/Kconfig
286 @@ -38,6 +38,13 @@ menuconfig COMMON_CLK
300 diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
302 --- a/drivers/clk/clk.c
304 @@ -1296,7 +1296,7 @@ static int __init clk_disable_unused(void)
308 -late_initcall_sync(clk_disable_unused);
313 diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
315 --- a/drivers/clk/rockchip/Kconfig
317 @@ -2,7 +2,7 @@
321 - bool "Rockchip clock controller common support"
326 @@ -11,68 +11,88 @@ config COMMON_CLK_ROCKCHIP
330 - default y
337 - default y
344 - default y
351 - default y
358 - default y
365 - default y
373 - default y
380 - default y
387 - default y
394 - default y
410 + Say y here to enable clk compensation(+/- 1000 ppm).
425 diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
427 --- a/drivers/clk/rockchip/Makefile
429 @@ -13,6 +13,8 @@ clk-rockchip-y += clk-inverter.o
430 clk-rockchip-y += clk-mmc-phase.o
431 clk-rockchip-y += clk-muxgrf.o
432 clk-rockchip-y += clk-ddr.o
433 +clk-rockchip-y += clk-dclk-divider.o
434 +clk-rockchip-y += clk-pvtm.o
435 clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
437 obj-$(CONFIG_CLK_PX30) += clk-px30.o
438 diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
440 --- a/drivers/clk/rockchip/clk-cpu.c
441 +++ b/drivers/clk/rockchip/clk-cpu.c
442 @@ -51,6 +51,7 @@
450 @@ -88,10 +89,10 @@ static unsigned long rockchip_cpuclk_recalc_rate(struct clk_hw *hw,
453 const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
454 - u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg);
455 + u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg[0]);
457 - clksel0 >>= reg_data->div_core_shift;
458 - clksel0 &= reg_data->div_core_mask;
459 + clksel0 >>= reg_data->div_core_shift[0];
460 + clksel0 &= reg_data->div_core_mask[0];
464 @@ -124,6 +125,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
471 rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
472 @@ -133,6 +135,8 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
473 return -EINVAL;
476 + rockchip_boost_enable_recovery_sw_low(cpuclk->pll_hw);
478 alt_prate = clk_get_rate(cpuclk->alt_parent);
480 spin_lock_irqsave(cpuclk->lock, flags);
481 @@ -146,10 +150,10 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
482 if (alt_prate > ndata->old_rate) {
484 alt_div = DIV_ROUND_UP(alt_prate, ndata->old_rate) - 1;
485 - if (alt_div > reg_data->div_core_mask) {
486 + if (alt_div > reg_data->div_core_mask[0]) {
487 pr_warn("%s: limiting alt-divider %lu to %d\n",
488 - __func__, alt_div, reg_data->div_core_mask);
489 - alt_div = reg_data->div_core_mask;
490 + __func__, alt_div, reg_data->div_core_mask[0]);
491 + alt_div = reg_data->div_core_mask[0];
495 @@ -162,20 +166,21 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
496 pr_debug("%s: setting div %lu as alt-rate %lu > old-rate %lu\n",
497 __func__, alt_div, alt_prate, ndata->old_rate);
499 - writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask,
500 - reg_data->div_core_shift) |
501 - HIWORD_UPDATE(reg_data->mux_core_alt,
502 - reg_data->mux_core_mask,
503 - reg_data->mux_core_shift),
504 - cpuclk->reg_base + reg_data->core_reg);
505 - } else {
506 - /* select alternate parent */
507 - writel(HIWORD_UPDATE(reg_data->mux_core_alt,
508 - reg_data->mux_core_mask,
509 - reg_data->mux_core_shift),
510 - cpuclk->reg_base + reg_data->core_reg);
511 + for (i = 0; i < reg_data->num_cores; i++) {
512 + writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask[i],
513 + reg_data->div_core_shift[i]),
514 + cpuclk->reg_base + reg_data->core_reg[i]);
518 + rockchip_boost_add_core_div(cpuclk->pll_hw, alt_prate);
521 + writel(HIWORD_UPDATE(reg_data->mux_core_alt,
522 + reg_data->mux_core_mask,
523 + reg_data->mux_core_shift),
524 + cpuclk->reg_base + reg_data->core_reg[0]);
526 spin_unlock_irqrestore(cpuclk->lock, flags);
529 @@ -186,6 +191,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
530 const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
535 rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
537 @@ -206,16 +212,23 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
541 - writel(HIWORD_UPDATE(0, reg_data->div_core_mask,
542 - reg_data->div_core_shift) |
543 - HIWORD_UPDATE(reg_data->mux_core_main,
544 - reg_data->mux_core_mask,
545 - reg_data->mux_core_shift),
546 - cpuclk->reg_base + reg_data->core_reg);
547 + writel(HIWORD_UPDATE(reg_data->mux_core_main,
548 + reg_data->mux_core_mask,
549 + reg_data->mux_core_shift),
550 + cpuclk->reg_base + reg_data->core_reg[0]);
553 + for (i = 0; i < reg_data->num_cores; i++) {
554 + writel(HIWORD_UPDATE(0, reg_data->div_core_mask[i],
555 + reg_data->div_core_shift[i]),
556 + cpuclk->reg_base + reg_data->core_reg[i]);
559 if (ndata->old_rate > ndata->new_rate)
562 + rockchip_boost_disable_recovery_sw(cpuclk->pll_hw);
564 spin_unlock_irqrestore(cpuclk->lock, flags);
567 @@ -244,14 +257,16 @@ static int rockchip_cpuclk_notifier_cb(struct notifier_block *nb,
571 - const char *const *parent_names, u8 num_parents,
580 - struct clk *clk, *cclk;
586 @@ -259,12 +274,18 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
587 return ERR_PTR(-EINVAL);
592 + return ERR_PTR(-EINVAL);
597 return ERR_PTR(-ENOMEM);
601 - init.parent_names = &parent_names[reg_data->mux_core_main];
606 @@ -281,8 +302,19 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
607 cpuclk->reg_data = reg_data;
608 cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb;
609 cpuclk->hw.init = &init;
610 + if (reg_data->pll_name) {
614 + __func__, reg_data->pll_name);
615 + ret = -EINVAL;
618 + cpuclk->pll_hw = __clk_get_hw(pll_clk);
619 + rockchip_boost_init(cpuclk->pll_hw);
622 - cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]);
623 + cpuclk->alt_parent = alt_parent;
624 if (!cpuclk->alt_parent) {
626 __func__, reg_data->mux_core_alt);
627 @@ -297,11 +329,11 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
631 - clk = __clk_lookup(parent_names[reg_data->mux_core_main]);
635 __func__, reg_data->mux_core_main,
636 - parent_names[reg_data->mux_core_main]);
638 ret = -EINVAL;
641 diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
643 --- a/drivers/clk/rockchip/clk-ddr.c
644 +++ b/drivers/clk/rockchip/clk-ddr.c
645 @@ -8,10 +8,20 @@
647 #include <linux/clk-provider.h>
666 @@ -21,25 +31,47 @@ struct rockchip_ddrclk {
670 - spinlock_t *lock;
702 - struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
703 - unsigned long flags;
706 - spin_lock_irqsave(ddrclk->lock, flags);
710 - spin_unlock_irqrestore(ddrclk->lock, flags);
712 - return res.a0;
716 + return -EPERM;
720 @@ -87,18 +119,134 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = {
735 + lcdc_type = p->lcdc_type;
743 + ret = -1;
784 + p->hz = drate;
819 + p->hz = rate;
841 - int ddr_flag, void __iomem *reg_base,
842 - spinlock_t *lock)
856 return ERR_PTR(-ENOMEM);
857 @@ -114,6 +262,12 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
870 @@ -121,7 +275,6 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
873 ddrclk->reg_base = reg_base;
874 - ddrclk->lock = lock;
875 ddrclk->hw.init = &init;
876 ddrclk->mux_offset = mux_offset;
877 ddrclk->mux_shift = mux_shift;
878 diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c
880 --- a/drivers/clk/rockchip/clk-half-divider.c
881 +++ b/drivers/clk/rockchip/clk-half-divider.c
882 @@ -14,9 +14,9 @@ static bool _is_best_half_div(unsigned long rate, unsigned long now,
886 - return abs(rate - now) < abs(rate - best);
887 + return abs(rate - now) <= abs(rate - best);
889 - return now <= rate && now > best;
894 @@ -38,7 +38,7 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
898 - unsigned long parent_rate_saved = *best_parent_rate;
903 @@ -51,7 +51,7 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
907 - bestdiv = (bestdiv - 3) / 2;
908 + bestdiv = DIV_ROUND_UP(bestdiv - 3, 2);
912 @@ -63,28 +63,20 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
916 - if (((u64)rate * (i * 2 + 3)) == ((u64)parent_rate_saved * 2)) {
917 - /*
918 - * It's the most ideal case if the requested rate can be
919 - * divided from parent clock without needing to change
920 - * parent rate, so return the divider immediately.
921 - */
922 - *best_parent_rate = parent_rate_saved;
923 - return i;
924 - }
938 - if (!bestdiv) {
943 @@ -114,7 +106,7 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate,
947 - value = (value - 3) / 2;
948 + value = DIV_ROUND_UP(value - 3, 2);
949 value = min_t(unsigned int, value, div_mask(divider->width));
951 if (divider->lock)
952 @@ -160,10 +152,10 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
956 - u8 div_shift, u8 div_width,
957 - u8 div_flags, int gate_offset,
958 - u8 gate_shift, u8 gate_flags,
959 - unsigned long flags,
966 struct clk_hw *hw = ERR_PTR(-ENOMEM);
967 @@ -205,7 +197,10 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
970 div->flags = div_flags;
971 - div->reg = base + muxdiv_offset;
973 + div->reg = base + div_offset;
975 + div->reg = base + muxdiv_offset;
976 div->shift = div_shift;
977 div->width = div_width;
978 div->lock = lock;
979 diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
981 --- a/drivers/clk/rockchip/clk-pll.c
982 +++ b/drivers/clk/rockchip/clk-pll.c
983 @@ -15,6 +15,9 @@
993 @@ -38,15 +41,291 @@ struct rockchip_clk_pll {
1053 + return -EINVAL;
1057 + return -EINVAL;
1059 + pll->sel = sel;
1073 + return -EINVAL;
1077 + return -EINVAL;
1079 + rate_table = pll->rate_table;
1080 + for (i = 0; i < pll->rate_count; i++) {
1085 + return -EINVAL;
1097 + return -EINVAL;
1101 + return -EINVAL;
1103 + rate_table = pll->rate_table;
1104 + for (i = 0; i < pll->rate_count; i++) {
1109 + return -EINVAL;
1161 + rate_table->postdiv1 = postdiv1;
1162 + rate_table->postdiv2 = postdiv2;
1163 + rate_table->dsmpd = 1;
1169 + rate_table->refdiv = fin_hz / clk_gcd;
1170 + rate_table->fbdiv = foutvco / clk_gcd;
1172 + rate_table->frac = 0;
1175 + fin_hz, fout_hz, clk_gcd, rate_table->refdiv,
1176 + rate_table->fbdiv, rate_table->postdiv1,
1177 + rate_table->postdiv2, rate_table->frac);
1184 + rate_table->postdiv1, rate_table->postdiv2, foutvco);
1186 + rate_table->refdiv = fin_hz / MHZ / clk_gcd;
1187 + rate_table->fbdiv = foutvco / MHZ / clk_gcd;
1189 + rate_table->refdiv, rate_table->fbdiv);
1191 + rate_table->frac = 0;
1195 + do_div(fin_64, (u64)rate_table->refdiv);
1198 + rate_table->frac = (u32)frac_64;
1199 + if (rate_table->frac > 0)
1200 + rate_table->dsmpd = 0;
1201 + pr_debug("frac = %x\n", rate_table->frac);
1272 + rate_table->nr = nr_out;
1273 + rate_table->nf = nf_out;
1274 + rate_table->no = no_out;
1285 @@ -54,28 +333,27 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
1288 for (i = 0; i < pll->rate_count; i++) {
1289 - if (rate == rate_table[i].rate)
1291 + if (i < pll->sel) {
1292 + pll->scaling = rate;
1293 + return &rate_table[pll->sel];
1295 + pll->scaling = 0;
1299 + pll->scaling = 0;
1301 - return NULL;
1302 + if (pll->type == pll_rk3066)
1311 - struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1312 - const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
1313 - int i;
1314 -
1315 - /* Assumming rate_table is in descending order */
1316 - for (i = 0; i < pll->rate_count; i++) {
1317 - if (drate >= rate_table[i].rate)
1318 - return rate_table[i].rate;
1319 - }
1320 -
1321 - /* return minimum supported value */
1322 - return rate_table[i - 1].rate;
1327 @@ -136,6 +414,30 @@ static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
1358 @@ -165,7 +467,10 @@ static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
1362 - u64 rate64 = prate;
1365 + if (pll->sel && pll->scaling)
1366 + return pll->scaling;
1370 @@ -174,7 +479,7 @@ static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
1374 - u64 frac_rate64 = prate * cur.frac;
1379 @@ -231,6 +536,8 @@ static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
1380 pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
1381 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
1388 @@ -412,6 +719,9 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
1392 + if (pll->sel && pll->scaling)
1393 + return pll->scaling;
1398 @@ -485,9 +795,18 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
1403 + struct regmap *grf = pll->ctx->grf;
1406 - pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
1407 - __func__, clk_hw_get_name(hw), drate, prate);
1419 @@ -497,7 +816,11 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
1420 return -EINVAL;
1423 - return rockchip_rk3066_pll_set_params(pll, rate);
1426 + pll->scaling = 0;
1432 @@ -649,6 +972,9 @@ static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
1436 + if (pll->sel && pll->scaling)
1437 + return pll->scaling;
1442 @@ -692,6 +1018,11 @@ static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
1449 + pll->reg_base + RK3399_PLLCON(3));
1452 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
1454 @@ -715,6 +1046,11 @@ static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
1456 pll->reg_base + RK3399_PLLCON(3));
1461 + pll->reg_base + RK3399_PLLCON(3));
1466 @@ -734,9 +1070,11 @@ static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drat…
1473 - pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
1474 - __func__, __clk_get_name(hw->clk), drate, prate);
1476 + __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
1480 @@ -746,7 +1084,11 @@ static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drat…
1481 return -EINVAL;
1484 - return rockchip_rk3399_pll_set_params(pll, rate);
1487 + pll->scaling = 0;
1493 @@ -842,6 +1184,80 @@ static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
1507 + if ((ppm > 1000) || (ppm < -1000))
1508 + return -EINVAL;
1511 + return -EINVAL;
1515 + return -EINVAL;
1517 + switch (pll->type) {
1527 + return -EINVAL;
1536 + return -EINVAL;
1543 + frac = readl_relaxed(pll->reg_base + pllcon2) & frac_mask;
1544 + fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
1549 + * -------------- = (fbdiv + ----------) * ---------
1556 + fracdiv = negative ? frac - (m + n) : frac + (m + n);
1559 + return -EINVAL;
1561 + pllcon = readl_relaxed(pll->reg_base + pllcon2);
1564 + writel_relaxed(pllcon, pll->reg_base + pllcon2);
1574 @@ -914,8 +1330,12 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1587 @@ -940,7 +1360,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1591 - if (!pll->rate_table)
1592 + if (!pll->rate_table || IS_ERR(ctx->grf))
1596 @@ -987,3 +1407,316 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1604 + switch (pll->type) {
1628 + np = of_parse_phandle(pll->ctx->cru_node, "rockchip,boost", 0);
1633 + pll->boost = syscon_node_to_regmap(np);
1634 + if (IS_ERR(pll->boost)) {
1639 + if (!of_property_read_u32(np, "rockchip,boost-low-con0", &con0) &&
1640 + !of_property_read_u32(np, "rockchip,boost-low-con1", &con1)) {
1641 + pr_debug("boost-low-con=0x%x 0x%x\n", con0, con1);
1642 + regmap_write(pll->boost, BOOST_PLL_L_CON(0),
1644 + regmap_write(pll->boost, BOOST_PLL_L_CON(1),
1646 + pll->boost_low_rate = rockchip_pll_con_to_rate(pll, con0,
1648 + pr_debug("boost-low-rate=%lu\n", pll->boost_low_rate);
1650 + if (!of_property_read_u32(np, "rockchip,boost-high-con0", &con0) &&
1651 + !of_property_read_u32(np, "rockchip,boost-high-con1", &con1)) {
1652 + pr_debug("boost-high-con=0x%x 0x%x\n", con0, con1);
1653 + regmap_write(pll->boost, BOOST_PLL_H_CON(0),
1655 + regmap_write(pll->boost, BOOST_PLL_H_CON(1),
1657 + pll->boost_high_rate = rockchip_pll_con_to_rate(pll, con0,
1659 + pr_debug("boost-high-rate=%lu\n", pll->boost_high_rate);
1661 + if (!of_property_read_u32(np, "rockchip,boost-backup-pll", &value)) {
1662 + pr_debug("boost-backup-pll=0x%x\n", value);
1663 + regmap_write(pll->boost, BOOST_CLK_CON,
1667 + if (!of_property_read_u32(np, "rockchip,boost-backup-pll-usage",
1668 + &pll->boost_backup_pll_usage)) {
1669 + pr_debug("boost-backup-pll-usage=0x%x\n",
1670 + pll->boost_backup_pll_usage);
1671 + regmap_write(pll->boost, BOOST_CLK_CON,
1672 + HIWORD_UPDATE(pll->boost_backup_pll_usage,
1676 + if (!of_property_read_u32(np, "rockchip,boost-switch-threshold",
1678 + pr_debug("boost-switch-threshold=0x%x\n", value);
1679 + regmap_write(pll->boost, BOOST_SWITCH_THRESHOLD, value);
1681 + if (!of_property_read_u32(np, "rockchip,boost-statis-threshold",
1683 + pr_debug("boost-statis-threshold=0x%x\n", value);
1684 + regmap_write(pll->boost, BOOST_STATIS_THRESHOLD, value);
1686 + if (!of_property_read_u32(np, "rockchip,boost-statis-enable",
1688 + pr_debug("boost-statis-enable=0x%x\n", value);
1689 + regmap_write(pll->boost, BOOST_BOOST_CON,
1693 + if (!of_property_read_u32(np, "rockchip,boost-enable", &value)) {
1694 + pr_debug("boost-enable=0x%x\n", value);
1695 + regmap_write(pll->boost, BOOST_BOOST_CON,
1699 + pll->boost_enabled = true;
1702 + if (pll->boost_enabled) {
1704 + hlist_add_head(&pll->debug_node, &clk_boost_list);
1718 + if (!pll->boost_enabled)
1721 + regmap_write(pll->boost, BOOST_BOOST_CON,
1725 + regmap_read(pll->boost, BOOST_FSM_STATUS, &val);
1728 + regmap_write(pll->boost, BOOST_BOOST_CON,
1737 + if (!pll->boost_enabled)
1740 + regmap_write(pll->boost, BOOST_BOOST_CON,
1752 + if (!pll->boost_enabled)
1755 + regmap_write(pll->boost, BOOST_BOOST_CON,
1758 + regmap_write(pll->boost, BOOST_BOOST_CON,
1771 + if (!pll->boost_enabled || pll->boost_backup_pll_rate == prate)
1775 + if (pll->boost_backup_pll_usage == BOOST_BACKUP_PLL_USAGE_TARGET)
1781 + if (pll->boost_low_rate && prate > pll->boost_low_rate) {
1782 + div = DIV_ROUND_UP(prate, pll->boost_low_rate) - 1;
1783 + regmap_write(pll->boost, BOOST_CLK_CON,
1786 + pll->boost_backup_pll_rate = prate;
1796 + struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
1804 + seq_puts(s, "------------------------------------------------------------------------------------…
1805 + seq_printf(s, " %s\n", clk_hw_get_name(&pll->hw));
1807 + regmap_read(pll->boost, BOOST_SWITCH_CNT, &boost_count);
1809 + regmap_read(pll->boost, BOOST_HIGH_PERF_CNT0, &freq_cnt0);
1810 + regmap_read(pll->boost, BOOST_HIGH_PERF_CNT1, &freq_cnt1);
1815 + regmap_read(pll->boost, BOOST_SHORT_SWITCH_CNT, &short_count);
1816 + regmap_read(pll->boost, BOOST_STATIS_THRESHOLD, &short_threshold);
1817 + regmap_read(pll->boost, BOOST_SWITCH_THRESHOLD, &interval_time);
1828 + return single_open(file, boost_summary_show, inode->i_private);
1840 + struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
1842 + seq_printf(s, "boost_enabled: %d\n", pll->boost_enabled);
1843 + seq_printf(s, "boost_low_rate: %lu\n", pll->boost_low_rate);
1844 + seq_printf(s, "boost_high_rate: %lu\n", pll->boost_high_rate);
1851 + return single_open(file, boost_config_show, inode->i_private);
1866 + pdentry = debugfs_lookup(clk_hw_get_name(&pll->hw), rootdir);
1869 + clk_hw_get_name(&pll->hw));
1870 + return -ENOMEM;
1877 + return -ENOMEM;
1884 + return -ENOMEM;
1898 + return -ENOMEM;
1913 diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
1915 --- a/drivers/clk/rockchip/clk-rk3399.c
1916 +++ b/drivers/clk/rockchip/clk-rk3399.c
1917 @@ -15,6 +15,12 @@
1918 #include <dt-bindings/clock/rk3399-cru.h>
1930 @@ -105,25 +111,95 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
1956 -PNAME(mux_armclkl_p) = { "clk_core_l_lpll_src",
1957 - "clk_core_l_bpll_src",
1958 - "clk_core_l_dpll_src",
1959 - "clk_core_l_gpll_src" };
1960 -PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src",
1961 - "clk_core_b_bpll_src",
1962 - "clk_core_b_dpll_src",
1963 - "clk_core_b_gpll_src" };
2030 - "vpll_aclk_cci_src" };
2035 @@ -148,26 +224,17 @@ PNAME(mux_pll_src_cpll_gpll_npll_upll_24m_p) = { "cpll", "gpll", "npll",
2039 -
2040 -PNAME(mux_pll_src_vpll_cpll_gpll_p) = { "vpll", "cpll", "gpll" };
2041 -PNAME(mux_pll_src_vpll_cpll_gpll_npll_p) = { "vpll", "cpll", "gpll",
2049 -PNAME(mux_pll_src_vpll_cpll_gpll_24m_p) = { "vpll", "cpll", "gpll",
2050 - "xin24m" };
2051 -
2052 -PNAME(mux_dclk_vop0_p) = { "dclk_vop0_div",
2053 - "dclk_vop0_frac" };
2054 -PNAME(mux_dclk_vop1_p) = { "dclk_vop1_div",
2055 - "dclk_vop1_frac" };
2056 -
2057 -PNAME(mux_clk_cif_p) = { "clk_cifout_src", "xin24m" };
2058 -
2059 -PNAME(mux_pll_src_24m_usbphy480m_p) = { "xin24m", "clk_usbphy_480m" };
2060 -PNAME(mux_pll_src_24m_pciephy_p) = { "xin24m", "clk_pciephy_ref100m" };
2065 -PNAME(mux_pciecore_cru_phy_p) = { "clk_pcie_core_cru",
2066 - "clk_pcie_core_phy" };
2070 @@ -180,14 +247,26 @@ PNAME(mux_fclk_cm0s_p) = { "cpll_fclk_cm0s_src",
2094 -PNAME(mux_aclk_gmac_p) = { "cpll_aclk_gmac_src",
2095 - "gpll_aclk_gmac_src" };
2099 @@ -201,20 +280,22 @@ PNAME(mux_i2sch_p) = { "clk_i2s0", "clk_i2s1",
2103 -PNAME(mux_uart0_p) = { "clk_uart0_div", "clk_uart0_frac", "xin24m" };
2104 -PNAME(mux_uart1_p) = { "clk_uart1_div", "clk_uart1_frac", "xin24m" };
2105 -PNAME(mux_uart2_p) = { "clk_uart2_div", "clk_uart2_frac", "xin24m" };
2106 -PNAME(mux_uart3_p) = { "clk_uart3_div", "clk_uart3_frac", "xin24m" };
2117 -PNAME(mux_uart4_pmu_p) = { "clk_uart4_div", "clk_uart4_frac",
2118 - "xin24m" };
2128 @@ -222,18 +303,23 @@ static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = {
2140 - RK3399_PLL_CON(35), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
2145 - RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
2150 - [ppll] = PLL(pll_rk3399, PLL_PPLL, "ppll", mux_pll_p, 0, RK3399_PMU_PLL_CON(0),
2155 @@ -259,24 +345,24 @@ static struct rockchip_clk_branch rk3399_i2s2_fracmux __initdata =
2159 - MUX(SCLK_UART0, "clk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
2160 - RK3399_CLKSEL_CON(33), 8, 2, MFLAGS);
2165 - MUX(SCLK_UART1, "clk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
2166 - RK3399_CLKSEL_CON(34), 8, 2, MFLAGS);
2171 - MUX(SCLK_UART2, "clk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
2172 - RK3399_CLKSEL_CON(35), 8, 2, MFLAGS);
2177 - MUX(SCLK_UART3, "clk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
2178 - RK3399_CLKSEL_CON(36), 8, 2, MFLAGS);
2183 - MUX(SCLK_UART4_PMU, "clk_uart4_pmu", mux_uart4_pmu_p, CLK_SET_RATE_PARENT,
2184 - RK3399_PMU_CLKSEL_CON(5), 8, 2, MFLAGS);
2190 @@ -291,9 +377,10 @@ static struct rockchip_clk_branch rk3399_pmuclk_wifi_fracmux __initdata =
2194 - .core_reg = RK3399_CLKSEL_CON(0),
2195 - .div_core_shift = 0,
2196 - .div_core_mask = 0x1f,
2204 @@ -301,9 +388,10 @@ static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = {
2208 - .core_reg = RK3399_CLKSEL_CON(2),
2209 - .div_core_shift = 0,
2210 - .div_core_mask = 0x1f,
2218 @@ -406,9 +494,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2222 - GATE(0, "clk_usbphy0_480m_src", "clk_usbphy0_480m", 0,
2225 - GATE(0, "clk_usbphy1_480m_src", "clk_usbphy1_480m", 0,
2230 @@ -423,7 +511,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2234 - GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", CLK_IGNORE_UNUSED,
2239 @@ -549,7 +637,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2243 - GATE(ACLK_GMAC_NOC, "aclk_gmac_noc", "aclk_gmac_pre", CLK_IGNORE_UNUSED,
2248 @@ -559,7 +647,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2252 - GATE(PCLK_GMAC_NOC, "pclk_gmac_noc", "pclk_gmac_pre", CLK_IGNORE_UNUSED,
2257 @@ -578,13 +666,13 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2261 - COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0,
2265 - COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", 0,
2269 - &rk3399_spdif_fracmux),
2274 @@ -592,84 +680,84 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2278 - COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
2282 - COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0,
2286 - &rk3399_i2s0_fracmux),
2291 - COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
2295 - COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0,
2299 - &rk3399_i2s1_fracmux),
2304 - COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
2308 - COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0,
2312 - &rk3399_i2s2_fracmux),
2317 - MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT,
2325 - MUX(0, "clk_uart0_src", mux_pll_src_cpll_gpll_upll_p, 0,
2331 - COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", 0,
2335 - &rk3399_uart0_fracmux),
2338 - MUX(0, "clk_uart_src", mux_pll_src_cpll_gpll_p, 0,
2344 - COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", 0,
2348 - &rk3399_uart1_fracmux),
2354 - COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", 0,
2358 - &rk3399_uart2_fracmux),
2364 - COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", 0,
2368 - &rk3399_uart3_fracmux),
2371 - COMPOSITE(PCLK_DDR, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
2376 - GATE(PCLK_CENTER_MAIN_NOC, "pclk_center_main_noc", "pclk_ddr", CLK_IGNORE_UNUSED,
2381 @@ -686,30 +774,30 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2385 - GATE(0, "cpll_aclk_cci_src", "cpll", CLK_IGNORE_UNUSED,
2388 - GATE(0, "gpll_aclk_cci_src", "gpll", CLK_IGNORE_UNUSED,
2391 - GATE(0, "npll_aclk_cci_src", "npll", CLK_IGNORE_UNUSED,
2394 - GATE(0, "vpll_aclk_cci_src", "vpll", CLK_IGNORE_UNUSED,
2398 - COMPOSITE(0, "aclk_cci_pre", mux_aclk_cci_p, CLK_IGNORE_UNUSED,
2403 - GATE(ACLK_ADB400M_PD_CORE_L, "aclk_adb400m_pd_core_l", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2406 - GATE(ACLK_ADB400M_PD_CORE_B, "aclk_adb400m_pd_core_b", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2409 - GATE(ACLK_CCI, "aclk_cci", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2412 - GATE(ACLK_CCI_NOC0, "aclk_cci_noc0", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2415 - GATE(ACLK_CCI_NOC1, "aclk_cci_noc1", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2418 - GATE(ACLK_CCI_GRF, "aclk_cci_grf", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2423 @@ -717,20 +805,20 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2427 - RK3399_CLKSEL_CON(5), 15, 2, MFLAGS, 8, 5, DFLAGS,
2431 - GATE(0, "cpll_cs", "cpll", CLK_IGNORE_UNUSED,
2434 - GATE(0, "gpll_cs", "gpll", CLK_IGNORE_UNUSED,
2437 - GATE(0, "npll_cs", "npll", CLK_IGNORE_UNUSED,
2440 - COMPOSITE_NOGATE(0, "clk_cs", mux_cs_p, CLK_IGNORE_UNUSED,
2445 - GATE(0, "clk_dbg_noc", "clk_cs", CLK_IGNORE_UNUSED,
2450 @@ -742,12 +830,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2454 - GATE(0, "hclk_vcodec_noc", "hclk_vcodec_pre", CLK_IGNORE_UNUSED,
2460 - GATE(0, "aclk_vcodec_noc", "aclk_vcodec_pre", CLK_IGNORE_UNUSED,
2465 @@ -766,12 +854,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2469 - GATE(HCLK_VDU_NOC, "hclk_vdu_noc", "hclk_vdu_pre", CLK_IGNORE_UNUSED,
2475 - GATE(ACLK_VDU_NOC, "aclk_vdu_noc", "aclk_vdu_pre", CLK_IGNORE_UNUSED,
2480 @@ -783,12 +871,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2484 - GATE(HCLK_IEP_NOC, "hclk_iep_noc", "hclk_iep_pre", CLK_IGNORE_UNUSED,
2490 - GATE(ACLK_IEP_NOC, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED,
2495 @@ -804,21 +892,21 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2499 - GATE(HCLK_RGA_NOC, "hclk_rga_noc", "hclk_rga_pre", CLK_IGNORE_UNUSED,
2505 - GATE(ACLK_RGA_NOC, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED,
2510 - COMPOSITE(0, "aclk_center", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED,
2514 - GATE(ACLK_CENTER_MAIN_NOC, "aclk_center_main_noc", "aclk_center", CLK_IGNORE_UNUSED,
2517 - GATE(ACLK_CENTER_PERI_NOC, "aclk_center_peri_noc", "aclk_center", CLK_IGNORE_UNUSED,
2522 @@ -835,25 +923,25 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2526 - GATE(0, "cpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED,
2529 - GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED,
2532 - COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED,
2536 - COMPOSITE_NOMUX(HCLK_PERIHP, "hclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
2540 - COMPOSITE_NOMUX(PCLK_PERIHP, "pclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
2541 - RK3399_CLKSEL_CON(14), 12, 2, DFLAGS,
2550 - GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED,
2555 @@ -866,16 +954,16 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2559 - GATE(0, "hclk_perihp_noc", "hclk_perihp", CLK_IGNORE_UNUSED,
2565 - GATE(PCLK_PERIHP_GRF, "pclk_perihp_grf", "pclk_perihp", CLK_IGNORE_UNUSED,
2570 - GATE(0, "pclk_perihp_noc", "pclk_perihp", CLK_IGNORE_UNUSED,
2575 @@ -886,7 +974,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2579 - GATE(0, "hclk_sdmmc_noc", "hclk_sd", CLK_IGNORE_UNUSED,
2584 @@ -933,23 +1021,23 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2588 - GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", CLK_IGNORE_UNUSED,
2595 - GATE(0, "cpll_aclk_perilp0_src", "cpll", CLK_IGNORE_UNUSED,
2598 - GATE(0, "gpll_aclk_perilp0_src", "gpll", CLK_IGNORE_UNUSED,
2601 - COMPOSITE(ACLK_PERILP0, "aclk_perilp0", mux_aclk_perilp0_p, CLK_IGNORE_UNUSED,
2605 - COMPOSITE_NOMUX(HCLK_PERILP0, "hclk_perilp0", "aclk_perilp0", CLK_IGNORE_UNUSED,
2609 - COMPOSITE_NOMUX(PCLK_PERILP0, "pclk_perilp0", "aclk_perilp0", 0,
2614 @@ -964,8 +1052,8 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2618 - GATE(ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 6, GFLAGS…
2619 - GATE(ACLK_PERILP0_NOC, "aclk_perilp0_noc", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(…
2625 @@ -973,7 +1061,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2629 - GATE(HCLK_PERILP0_NOC, "hclk_perilp0_noc", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(…
2634 @@ -1001,29 +1089,29 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2638 - GATE(HCLK_M0_PERILP_NOC, "hclk_m0_perilp_noc", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON…
2642 - GATE(0, "cpll_hclk_perilp1_src", "cpll", CLK_IGNORE_UNUSED,
2645 - GATE(0, "gpll_hclk_perilp1_src", "gpll", CLK_IGNORE_UNUSED,
2648 - COMPOSITE_NOGATE(HCLK_PERILP1, "hclk_perilp1", mux_hclk_perilp1_p, CLK_IGNORE_UNUSED,
2651 - COMPOSITE_NOMUX(PCLK_PERILP1, "pclk_perilp1", "hclk_perilp1", CLK_IGNORE_UNUSED,
2657 - GATE(0, "hclk_perilp1_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 9, GFLAGS),
2658 - GATE(0, "hclk_sdio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 12, GFLAGS),
2667 - GATE(0, "hclk_sdioaudio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 6, GFLAG…
2672 @@ -1046,7 +1134,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2676 - GATE(0, "pclk_perilp1_noc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(25), 10, GFLAGS),
2681 @@ -1075,24 +1163,23 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2685 - COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0,
2690 - GATE(ACLK_VIO_NOC, "aclk_vio_noc", "aclk_vio", CLK_IGNORE_UNUSED,
2698 - GATE(PCLK_VIO_GRF, "pclk_vio_grf", "pclk_vio", CLK_IGNORE_UNUSED,
2703 - COMPOSITE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, 0,
2704 - RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS,
2705 - RK3399_CLKGATE_CON(11), 12, GFLAGS),
2711 @@ -1100,17 +1187,17 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2715 - GATE(ACLK_HDCP_NOC, "aclk_hdcp_noc", "aclk_hdcp", CLK_IGNORE_UNUSED,
2721 - GATE(HCLK_HDCP_NOC, "hclk_hdcp_noc", "hclk_hdcp", CLK_IGNORE_UNUSED,
2727 - GATE(PCLK_HDCP_NOC, "pclk_hdcp_noc", "pclk_hdcp", CLK_IGNORE_UNUSED,
2732 @@ -1129,7 +1216,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2736 - GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED,
2741 @@ -1143,7 +1230,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2745 - COMPOSITE(ACLK_VOP0_PRE, "aclk_vop0_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
2750 @@ -1152,28 +1239,35 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2754 - GATE(ACLK_VOP0_NOC, "aclk_vop0_noc", "aclk_vop0_pre", CLK_IGNORE_UNUSED,
2760 - GATE(HCLK_VOP0_NOC, "hclk_vop0_noc", "hclk_vop0_pre", CLK_IGNORE_UNUSED,
2764 - COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, 0,
2775 - COMPOSITE_FRACMUX_NOGATE(DCLK_VOP0_FRAC, "dclk_vop0_frac", "dclk_vop0_div", 0,
2776 + /* The VOP0 is main screen, it is able to re-set parent rate. */
2779 - &rk3399_dclk_vop0_fracmux),
2782 - COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, 0,
2788 - COMPOSITE(ACLK_VOP1_PRE, "aclk_vop1_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
2793 @@ -1182,23 +1276,30 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2797 - GATE(ACLK_VOP1_NOC, "aclk_vop1_noc", "aclk_vop1_pre", CLK_IGNORE_UNUSED,
2803 - GATE(HCLK_VOP1_NOC, "hclk_vop1_noc", "hclk_vop1_pre", CLK_IGNORE_UNUSED,
2807 - COMPOSITE(DCLK_VOP1_DIV, "dclk_vop1_div", mux_pll_src_vpll_cpll_gpll_p, 0,
2808 + /* The VOP1 is sub screen, it is note able to re-set parent rate. */
2821 - &rk3399_dclk_vop1_fracmux),
2824 - COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, CLK_IGNORE_UNUSED,
2829 @@ -1210,14 +1311,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2833 - GATE(ACLK_ISP0_NOC, "aclk_isp0_noc", "aclk_isp0", CLK_IGNORE_UNUSED,
2838 - GATE(HCLK_ISP1_WRAPPER, "hclk_isp1_wrapper", "aclk_isp0", 0,
2839 - RK3399_CLKGATE_CON(27), 7, GFLAGS),
2841 - GATE(HCLK_ISP0_NOC, "hclk_isp0_noc", "hclk_isp0", CLK_IGNORE_UNUSED,
2846 @@ -1233,13 +1332,15 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2850 - GATE(ACLK_ISP1_NOC, "aclk_isp1_noc", "aclk_isp1", CLK_IGNORE_UNUSED,
2856 - GATE(HCLK_ISP1_NOC, "hclk_isp1_noc", "hclk_isp1", CLK_IGNORE_UNUSED,
2859 - GATE(ACLK_ISP1_WRAPPER, "aclk_isp1_wrapper", "hclk_isp1", 0,
2860 - RK3399_CLKGATE_CON(27), 8, GFLAGS),
2866 @@ -1257,7 +1358,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2870 - COMPOSITE_NODIV(0, "clk_cifout_src", mux_pll_src_cpll_gpll_npll_p, 0,
2875 @@ -1265,12 +1366,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2879 - COMPOSITE(ACLK_GIC_PRE, "aclk_gic_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
2884 - GATE(ACLK_GIC, "aclk_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 0, GFLAGS),
2885 - GATE(ACLK_GIC_NOC, "aclk_gic_noc", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 1, …
2891 @@ -1301,19 +1402,19 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2895 - GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21)…
2899 - GATE(SCLK_DPHY_TX0_CFG, "clk_dphy_tx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE…
2900 - GATE(SCLK_DPHY_TX1RX1_CFG, "clk_dphy_tx1rx1_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_C…
2901 - GATE(SCLK_DPHY_RX0_CFG, "clk_dphy_rx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE…
2911 - RK3399_CLKGATE_CON(13), 9, GFLAGS),
2916 @@ -1385,13 +1486,13 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2920 - GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3),
2923 - GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3),
2926 - GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3),
2929 - GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3),
2934 @@ -1402,10 +1503,10 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2935 * PMU CRU Clock-Architecture
2938 - GATE(0, "fclk_cm0s_pmu_ppll_src", "ppll", 0,
2942 - COMPOSITE_NOGATE(FCLK_CM0S_SRC_PMU, "fclk_cm0s_src_pmu", mux_fclk_cm0s_pmu_ppll_p, 0,
2947 @@ -1416,9 +1517,9 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2951 - COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", 0,
2954 - &rk3399_pmuclk_wifi_fracmux),
2959 @@ -1440,23 +1541,26 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2963 - COMPOSITE(0, "clk_uart4_div", mux_24m_ppll_p, 0,
2964 - RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS,
2972 - COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", 0,
2976 - &rk3399_uart4_pmu_fracmux),
2979 - DIV(PCLK_SRC_PMU, "pclk_pmu_src", "ppll", CLK_IGNORE_UNUSED,
2987 - GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 7, GF…
2992 @@ -1464,69 +1568,60 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2996 - GATE(PCLK_NOC_PMU, "pclk_noc_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), …
3001 - GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 10, GFLAGS),
3009 - GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
3010 - GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
3011 - GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
3012 - GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
3013 - GATE(HCLK_NOC_PMU, "hclk_noc_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON…
3021 -static const char *const rk3399_cru_critical_clocks[] __initconst = {
3022 - "aclk_cci_pre",
3023 - "aclk_gic",
3024 - "aclk_gic_noc",
3025 - "aclk_hdcp_noc",
3026 - "hclk_hdcp_noc",
3027 - "pclk_hdcp_noc",
3028 - "pclk_perilp0",
3029 - "pclk_perilp0",
3030 - "hclk_perilp0",
3031 - "hclk_perilp0_noc",
3032 - "pclk_perilp1",
3033 - "pclk_perilp1_noc",
3034 - "pclk_perihp",
3035 - "pclk_perihp_noc",
3036 - "hclk_perihp",
3037 - "aclk_perihp",
3038 - "aclk_perihp_noc",
3039 - "aclk_perilp0",
3040 - "aclk_perilp0_noc",
3041 - "hclk_perilp1",
3042 - "hclk_perilp1_noc",
3043 - "aclk_dmac0_perilp",
3044 - "aclk_emmc_noc",
3045 - "gpll_hclk_perilp1_src",
3046 - "gpll_aclk_perilp0_src",
3047 - "gpll_aclk_perihp_src",
3048 - "aclk_vio_noc",
3052 - /* ddrc */
3053 - "sclk_ddrc"
3054 -};
3079 -static const char *const rk3399_pmucru_critical_clocks[] __initconst = {
3080 - "ppll",
3081 - "pclk_pmu_src",
3082 - "fclk_cm0s_src_pmu",
3083 - "clk_timer_src_pmu",
3084 - "pclk_rkpwm_pmu",
3097 @@ -1534,12 +1629,15 @@ static void __init rk3399_clk_init(struct device_node *np)
3109 + clks = ctx->clk_data.clks;
3112 ARRAY_SIZE(rk3399_pll_clks), -1);
3113 @@ -1547,16 +1645,13 @@ static void __init rk3399_clk_init(struct device_node *np)
3117 - rockchip_clk_protect_critical(rk3399_cru_critical_clocks,
3118 - ARRAY_SIZE(rk3399_cru_critical_clocks));
3119 -
3121 - mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
3127 - mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p),
3132 @@ -1580,6 +1675,8 @@ static void __init rk3399_pmu_clk_init(struct device_node *np)
3141 @@ -1593,13 +1690,13 @@ static void __init rk3399_pmu_clk_init(struct device_node *np)
3145 - rockchip_clk_protect_critical(rk3399_pmucru_critical_clocks,
3146 - ARRAY_SIZE(rk3399_pmucru_critical_clocks));
3147 -
3156 CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init);
3158 diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
3160 --- a/drivers/clk/rockchip/clk.c
3162 @@ -38,6 +38,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
3170 @@ -60,6 +61,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
3171 mux->shift = mux_shift;
3172 mux->mask = BIT(mux_width) - 1;
3173 mux->flags = mux_flags;
3174 + mux->table = mux_table;
3175 mux->lock = lock;
3178 @@ -182,12 +184,43 @@ static void rockchip_fractional_approximation(struct clk_hw *hw,
3185 - if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
3187 + (fd->max_prate && fd->max_prate < p_rate)) {
3189 - p_parent_rate = clk_hw_get_rate(p_parent);
3190 - *parent_rate = p_parent_rate;
3196 + if (fd->max_prate && p_parent_rate > fd->max_prate) {
3198 + fd->max_prate);
3213 + } else if (!(fd->flags & CLK_FRAC_DIVIDER_NO_LIMIT)) {
3214 + pr_warn("%s p_rate(%ld) is low than rate(%ld)*20, use integer or half-div\n",
3225 @@ -210,7 +243,7 @@ static struct clk *rockchip_clk_register_frac_branch(
3229 - spinlock_t *lock)
3234 @@ -251,6 +284,7 @@ static struct clk *rockchip_clk_register_frac_branch(
3235 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
3236 div->lock = lock;
3237 div->approximation = rockchip_fractional_approximation;
3238 + div->max_prate = max_prate;
3242 @@ -278,6 +312,8 @@ static struct clk *rockchip_clk_register_frac_branch(
3243 frac_mux->shift = child->mux_shift;
3244 frac_mux->mask = BIT(child->mux_width) - 1;
3245 frac_mux->flags = child->mux_flags;
3246 + if (child->mux_table)
3247 + frac_mux->table = child->mux_table;
3248 frac_mux->lock = lock;
3249 frac_mux->hw.init = &init;
3251 @@ -360,6 +396,61 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name,
3252 return hw->clk;
3269 + if (brother && brother->branch_type != branch_half_divider) {
3272 + return ERR_PTR(-EINVAL);
3285 + brother_clk = rockchip_clk_register_halfdiv(brother->name,
3286 + brother->parent_names, brother->num_parents,
3287 + base, brother->muxdiv_offset,
3288 + brother->mux_shift, brother->mux_width,
3289 + brother->mux_flags, brother->div_offset,
3290 + brother->div_shift, brother->div_width,
3291 + brother->div_flags, brother->gate_offset,
3292 + brother->gate_shift, brother->gate_flags,
3296 + rockchip_clk_add_lookup(ctx, brother_clk, brother->id);
3303 + composite->brother_hw = brother_hw;
3304 + brother_composite->brother_hw = hw;
3313 @@ -387,6 +478,8 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
3315 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
3317 + ctx->pmugrf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
3322 @@ -452,11 +545,22 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3324 switch (list->branch_type) {
3326 - clk = clk_register_mux(NULL, list->name,
3327 - list->parent_names, list->num_parents,
3328 - flags, ctx->reg_base + list->muxdiv_offset,
3329 - list->mux_shift, list->mux_width,
3330 - list->mux_flags, &ctx->lock);
3331 + if (list->mux_table)
3332 + clk = clk_register_mux_table(NULL, list->name,
3333 + list->parent_names, list->num_parents,
3335 + ctx->reg_base + list->muxdiv_offset,
3336 + list->mux_shift,
3337 + BIT(list->mux_width) - 1,
3338 + list->mux_flags, list->mux_table,
3339 + &ctx->lock);
3341 + clk = clk_register_mux(NULL, list->name,
3342 + list->parent_names, list->num_parents,
3344 + ctx->reg_base + list->muxdiv_offset,
3345 + list->mux_shift, list->mux_width,
3346 + list->mux_flags, &ctx->lock);
3349 clk = rockchip_clk_register_muxgrf(list->name,
3350 @@ -465,6 +569,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3351 list->mux_shift, list->mux_width,
3352 list->mux_flags);
3355 + clk = rockchip_clk_register_muxgrf(list->name,
3356 + list->parent_names, list->num_parents,
3357 + flags, ctx->pmugrf, list->muxdiv_offset,
3358 + list->mux_shift, list->mux_width,
3359 + list->mux_flags);
3362 if (list->div_table)
3364 @@ -488,17 +599,18 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3365 list->div_flags,
3366 list->gate_offset, list->gate_shift,
3367 list->gate_flags, flags, list->child,
3368 - &ctx->lock);
3369 + list->max_prate, &ctx->lock);
3372 clk = rockchip_clk_register_halfdiv(list->name,
3373 list->parent_names, list->num_parents,
3374 ctx->reg_base, list->muxdiv_offset,
3375 list->mux_shift, list->mux_width,
3376 - list->mux_flags, list->div_shift,
3377 - list->div_width, list->div_flags,
3378 - list->gate_offset, list->gate_shift,
3379 - list->gate_flags, flags, &ctx->lock);
3380 + list->mux_flags, list->div_offset,
3381 + list->div_shift, list->div_width,
3382 + list->div_flags, list->gate_offset,
3383 + list->gate_shift, list->gate_flags,
3384 + flags, &ctx->lock);
3388 @@ -514,11 +626,25 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3389 ctx->reg_base, list->muxdiv_offset,
3390 list->mux_shift,
3391 list->mux_width, list->mux_flags,
3392 - list->div_offset, list->div_shift, list->div_width,
3393 + list->mux_table, list->div_offset,
3394 + list->div_shift, list->div_width,
3395 list->div_flags, list->div_table,
3396 list->gate_offset, list->gate_shift,
3397 list->gate_flags, flags, &ctx->lock);
3401 + ctx, list->name, list->parent_names,
3402 + list->num_parents, ctx->reg_base,
3403 + list->muxdiv_offset, list->mux_shift,
3404 + list->mux_width, list->mux_flags,
3405 + list->mux_table, list->div_offset,
3406 + list->div_shift, list->div_width,
3407 + list->div_flags, list->div_table,
3408 + list->gate_offset, list->gate_shift,
3409 + list->gate_flags, flags, list->child,
3410 + &ctx->lock);
3414 list->name,
3415 @@ -549,7 +675,17 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3416 list->muxdiv_offset, list->mux_shift,
3417 list->mux_width, list->div_shift,
3418 list->div_width, list->div_flags,
3419 - ctx->reg_base, &ctx->lock);
3420 + ctx->reg_base);
3423 + clk = rockchip_clk_register_dclk_branch(list->name,
3424 + list->parent_names, list->num_parents,
3425 + ctx->reg_base, list->muxdiv_offset, list->mux_shift,
3426 + list->mux_width, list->mux_flags,
3427 + list->div_offset, list->div_shift, list->div_width,
3428 + list->div_flags, list->div_table,
3429 + list->gate_offset, list->gate_shift,
3430 + list->gate_flags, flags, list->max_prate, &ctx->lock);
3434 @@ -573,15 +709,17 @@ EXPORT_SYMBOL_GPL(rockchip_clk_register_branches);
3438 - const char *name, const char *const *parent_names,
3448 - clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents,
3452 ctx->reg_base, &ctx->lock);
3454 @@ -594,20 +732,20 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
3458 -void rockchip_clk_protect_critical(const char *const clocks[],
3459 - int nclocks)
3460 -{
3461 - int i;
3462 -
3463 - /* Protect the clocks that needs to stay on */
3464 - for (i = 0; i < nclocks; i++) {
3465 - struct clk *clk = __clk_lookup(clocks[i]);
3469 - if (clk)
3470 - clk_prepare_enable(clk);
3471 - }
3479 -EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical);
3487 @@ -641,5 +779,7 @@ rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
3495 diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
3497 --- a/drivers/clk/rockchip/clk.h
3499 @@ -37,12 +37,25 @@ struct clk;
3525 @@ -79,6 +92,51 @@ struct clk;
3577 @@ -188,6 +246,34 @@ struct clk;
3612 @@ -238,22 +324,30 @@ struct rockchip_clk_provider {
3622 - unsigned int nr;
3623 - unsigned int nf;
3624 - unsigned int no;
3625 - unsigned int nb;
3626 - /* for RK3036/RK3399 */
3627 - unsigned int fbdiv;
3628 - unsigned int postdiv1;
3629 - unsigned int refdiv;
3630 - unsigned int postdiv2;
3631 - unsigned int dsmpd;
3632 - unsigned int frac;
3654 @@ -317,12 +411,21 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
3671 -#define ROCKCHIP_CPUCLK_NUM_DIVIDERS 2
3677 @@ -330,26 +433,29 @@ struct rockchip_cpuclk_rate_table {
3680 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
3681 - * @core_reg: register offset of the core settings register
3682 - * @div_core_shift: core divider offset used to divide the pll value
3683 - * @div_core_mask: core divider mask
3684 - * @mux_core_alt: mux value to select alternate parent
3694 - int core_reg;
3695 - u8 div_core_shift;
3696 - u32 div_core_mask;
3697 - u8 mux_core_alt;
3698 - u8 mux_core_main;
3699 - u8 mux_core_shift;
3700 - u32 mux_core_mask;
3713 - const char *const *parent_names, u8 num_parents,
3719 @@ -361,16 +467,21 @@ struct clk *rockchip_clk_register_mmc(const char *name,
3737 - int ddr_flags, void __iomem *reg_base,
3738 - spinlock_t *lock);
3743 @@ -388,8 +499,10 @@ struct clk *rockchip_clk_register_muxgrf(const char *name,
3754 @@ -398,6 +511,7 @@ enum rockchip_clk_branch_type {
3762 @@ -411,6 +525,7 @@ struct rockchip_clk_branch {
3770 @@ -420,6 +535,7 @@ struct rockchip_clk_branch {
3778 @@ -443,6 +559,50 @@ struct rockchip_clk_branch {
3829 @@ -539,6 +699,26 @@ struct rockchip_clk_branch {
3830 .gate_offset = -1, \
3849 + .gate_offset = -1, \
3856 @@ -559,7 +739,7 @@ struct rockchip_clk_branch {
3857 .gate_offset = -1, \
3860 -#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
3865 @@ -574,9 +754,10 @@ struct rockchip_clk_branch {
3872 -#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
3877 @@ -592,9 +773,10 @@ struct rockchip_clk_branch {
3884 -#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
3889 @@ -608,6 +790,7 @@ struct rockchip_clk_branch {
3891 .gate_offset = -1, \
3897 @@ -643,6 +826,22 @@ struct rockchip_clk_branch {
3898 .gate_offset = -1, \
3913 + .gate_offset = -1, \
3920 @@ -658,6 +857,21 @@ struct rockchip_clk_branch {
3921 .gate_offset = -1, \
3936 + .gate_offset = -1, \
3942 @@ -772,6 +986,28 @@ struct rockchip_clk_branch {
3971 @@ -824,6 +1060,28 @@ struct rockchip_clk_branch {
3972 .gate_offset = -1, \
4000 @@ -840,13 +1098,17 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
4004 -void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
4005 - unsigned int lookup_id, const char *name,
4006 - const char *const *parent_names, u8 num_parents,
4007 - const struct rockchip_cpuclk_reg_data *reg_data,
4008 - const struct rockchip_cpuclk_rate_table *rates,
4009 - int nrates);
4010 -void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
4025 @@ -857,12 +1119,27 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
4029 - u8 div_shift, u8 div_width,
4030 - u8 div_flags, int gate_offset,
4031 - u8 gate_shift, u8 gate_flags,
4032 - unsigned long flags,
4057 @@ -874,5 +1151,6 @@ static inline void rockchip_register_softrst(struct device_node *np,
4064 diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
4066 --- a/drivers/clocksource/Kconfig
4068 @@ -85,7 +85,9 @@ config IXP4XX_TIMER
4072 - bool "Rockchip timer driver" if COMPILE_TEST
4079 diff --git a/drivers/clocksource/timer-rockchip.c b/drivers/clocksource/timer-rockchip.c
4081 --- a/drivers/clocksource/timer-rockchip.c
4082 +++ b/drivers/clocksource/timer-rockchip.c
4083 @@ -8,11 +8,13 @@
4097 @@ -45,7 +47,9 @@ struct rk_clkevt {
4107 @@ -119,10 +123,12 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
4114 return ~readl_relaxed(rk_clksrc->base + TIMER_CURRENT_VALUE0);
4120 @@ -250,6 +256,7 @@ static int __init rk_clkevt_init(struct device_node *np)
4127 int ret = -EINVAL;
4128 @@ -287,14 +294,17 @@ static int __init rk_clksrc_init(struct device_node *np)
4145 return -EINVAL;
4146 @@ -302,3 +312,26 @@ static int __init rk_timer_init(struct device_node *np)
4148 TIMER_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_init);
4149 TIMER_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_init);
4154 + return rk_timer_init(pdev->dev.of_node);
4158 + { .compatible = "rockchip,rk3288-timer" },
4159 + { .compatible = "rockchip,rk3399-timer" },
4173 diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
4175 --- a/drivers/cpufreq/Kconfig.arm
4177 @@ -158,6 +158,16 @@ config ARM_RASPBERRYPI_CPUFREQ
4187 + based on cpufreq-dt.
4194 diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
4196 --- a/drivers/cpufreq/Makefile
4198 @@ -5,7 +5,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o
4200 obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o
4202 -# CPUfreq governors
4204 obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
4205 obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
4206 obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
4207 @@ -64,6 +64,7 @@ obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
4208 obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW) += qcom-cpufreq-hw.o
4209 obj-$(CONFIG_ARM_QCOM_CPUFREQ_NVMEM) += qcom-cpufreq-nvmem.o
4210 obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o
4211 +obj-$(CONFIG_ARM_ROCKCHIP_CPUFREQ) += rockchip-cpufreq.o
4212 obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
4213 obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
4214 obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
4215 diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
4217 --- a/drivers/cpufreq/cpufreq-dt-platdev.c
4218 +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
4219 @@ -66,21 +66,6 @@ static const struct of_device_id whitelist[] __initconst = {
4223 - { .compatible = "rockchip,rk2928", },
4224 - { .compatible = "rockchip,rk3036", },
4225 - { .compatible = "rockchip,rk3066a", },
4226 - { .compatible = "rockchip,rk3066b", },
4227 - { .compatible = "rockchip,rk3188", },
4228 - { .compatible = "rockchip,rk3228", },
4229 - { .compatible = "rockchip,rk3288", },
4230 - { .compatible = "rockchip,rk3328", },
4231 - { .compatible = "rockchip,rk3366", },
4232 - { .compatible = "rockchip,rk3368", },
4233 - { .compatible = "rockchip,rk3399",
4234 - .data = &(struct cpufreq_dt_platform_data)
4235 - { .have_governor_per_policy = true, },
4236 - },
4237 -
4238 { .compatible = "st-ericsson,u8500", },
4239 { .compatible = "st-ericsson,u8540", },
4240 { .compatible = "st-ericsson,u9500", },
4241 @@ -137,6 +122,28 @@ static const struct of_device_id blacklist[] __initconst = {
4270 diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
4272 --- a/drivers/cpufreq/cpufreq-dt.c
4273 +++ b/drivers/cpufreq/cpufreq-dt.c
4274 @@ -23,6 +23,9 @@
4277 #include "cpufreq-dt.h"
4279 +#include "rockchip-cpufreq.h"
4284 @@ -30,7 +33,7 @@ struct private_data {
4288 - struct opp_table *reg_opp_table;
4293 @@ -59,7 +62,11 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
4294 struct private_data *priv = policy->driver_data;
4295 unsigned long freq = policy->freq_table[index].frequency;
4298 + return rockchip_cpufreq_opp_set_rate(priv->cpu_dev, freq * 1000);
4300 return dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000);
4305 @@ -102,7 +109,6 @@ static const char *find_supply_name(struct device *dev)
4309 - struct cpufreq_frequency_table *freq_table;
4313 @@ -114,9 +120,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
4314 pr_err("failed to find data for cpu%d\n", policy->cpu);
4315 return -ENODEV;
4317 -
4318 cpu_dev = priv->cpu_dev;
4319 - cpumask_copy(policy->cpus, priv->cpus);
4323 @@ -125,67 +129,32 @@ static int cpufreq_init(struct cpufreq_policy *policy)
4327 - /*
4328 - * Initialize OPP tables for all policy->cpus. They will be shared by
4329 - * all CPUs which have marked their CPUs shared with OPP bindings.
4330 - *
4331 - * For platforms not using operating-points-v2 bindings, we do this
4332 - * before updating policy->cpus. Otherwise, we will end up creating
4333 - * duplicate OPPs for policy->cpus.
4334 - *
4335 - * OPPs might be populated at runtime, don't check for error here
4336 - */
4337 - if (!dev_pm_opp_of_cpumask_add_table(policy->cpus))
4338 - priv->have_static_opps = true;
4339 -
4340 - /*
4341 - * But we need OPP table to function so if it is not there let's
4342 - * give platform code chance to provide it for us.
4343 - */
4344 - ret = dev_pm_opp_get_opp_count(cpu_dev);
4345 - if (ret <= 0) {
4346 - dev_err(cpu_dev, "OPP table can't be empty\n");
4347 - ret = -ENODEV;
4348 - goto out_free_opp;
4349 - }
4350 -
4351 - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
4352 - if (ret) {
4353 - dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
4354 - goto out_free_opp;
4355 - }
4360 + cpumask_copy(policy->cpus, priv->cpus);
4361 policy->driver_data = priv;
4362 policy->clk = cpu_clk;
4363 - policy->freq_table = freq_table;
4364 -
4365 + policy->freq_table = priv->freq_table;
4366 policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(cpu_dev) / 1000;
4367 + policy->cpuinfo.transition_latency = transition_latency;
4368 + policy->dvfs_possible_from_any_cpu = true;
4375 - goto out_free_cpufreq_table;
4380 - transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
4381 - if (!transition_latency)
4382 - transition_latency = CPUFREQ_ETERNAL;
4383 -
4384 - policy->cpuinfo.transition_latency = transition_latency;
4385 - policy->dvfs_possible_from_any_cpu = true;
4386 -
4387 dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
4391 -out_free_cpufreq_table:
4392 - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
4393 -out_free_opp:
4394 - if (priv->have_static_opps)
4395 - dev_pm_opp_of_cpumask_remove_table(policy->cpus);
4400 @@ -208,11 +177,6 @@ static int cpufreq_offline(struct cpufreq_policy *policy)
4404 - struct private_data *priv = policy->driver_data;
4405 -
4406 - dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
4407 - if (priv->have_static_opps)
4408 - dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
4409 clk_put(policy->clk);
4412 @@ -236,6 +200,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
4420 @@ -254,68 +219,91 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
4421 if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL))
4422 return -ENOMEM;
4424 + cpumask_set_cpu(cpu, priv->cpus);
4425 priv->cpu_dev = cpu_dev;
4427 - /* Try to get OPP table early to ensure resources are available */
4428 - priv->opp_table = dev_pm_opp_get_opp_table(cpu_dev);
4429 - if (IS_ERR(priv->opp_table)) {
4430 - ret = PTR_ERR(priv->opp_table);
4431 - if (ret != -EPROBE_DEFER)
4432 - dev_err(cpu_dev, "failed to get OPP table: %d\n", ret);
4433 - goto free_cpumask;
4434 - }
4435 -
4442 - priv->reg_opp_table = dev_pm_opp_set_regulators(cpu_dev,
4443 - ®_name, 1);
4444 - if (IS_ERR(priv->reg_opp_table)) {
4445 - ret = PTR_ERR(priv->reg_opp_table);
4446 + priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, ®_name,
4448 + if (IS_ERR(priv->opp_table)) {
4449 + ret = PTR_ERR(priv->opp_table);
4450 if (ret != -EPROBE_DEFER)
4453 - goto put_table;
4458 - /* Find OPP sharing information so we can fill pri->cpus here */
4459 /* Get OPP-sharing information from "operating-points-v2" bindings */
4460 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->cpus);
4462 if (ret != -ENOENT)
4463 - goto put_reg;
4467 * operating-points-v2 not supported, fallback to all CPUs share
4471 - if (dev_pm_opp_get_sharing_cpus(cpu_dev, priv->cpus)) {
4472 - cpumask_setall(priv->cpus);
4473 -
4474 - /*
4475 - * OPP tables are initialized only for cpu, do it for
4476 - * others as well.
4477 - */
4478 - ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->cpus);
4479 - if (ret)
4480 - dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
4481 - __func__, ret);
4482 - }
4483 + if (dev_pm_opp_get_sharing_cpus(cpu_dev, priv->cpus))
4488 + * Initialize OPP tables for all priv->cpus. They will be shared by
4491 + * For platforms not using operating-points-v2 bindings, we do this
4492 + * before updating priv->cpus. Otherwise, we will end up creating
4497 + if (!dev_pm_opp_of_cpumask_add_table(priv->cpus))
4498 + priv->have_static_opps = true;
4507 + ret = -ENODEV;
4512 + cpumask_setall(priv->cpus);
4513 + ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->cpus);
4523 + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &priv->freq_table);
4529 list_add(&priv->node, &priv_list);
4532 -put_reg:
4533 - if (priv->reg_opp_table)
4534 - dev_pm_opp_put_regulators(priv->reg_opp_table);
4535 -put_table:
4536 - dev_pm_opp_put_opp_table(priv->opp_table);
4538 + if (priv->have_static_opps)
4539 + dev_pm_opp_of_cpumask_remove_table(priv->cpus);
4540 + if (priv->opp_table)
4541 + dev_pm_opp_put_regulators(priv->opp_table);
4543 free_cpumask_var(priv->cpus);
4545 @@ -326,9 +314,11 @@ static void dt_cpufreq_release(void)
4549 - if (priv->reg_opp_table)
4550 - dev_pm_opp_put_regulators(priv->reg_opp_table);
4551 - dev_pm_opp_put_opp_table(priv->opp_table);
4552 + dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table);
4553 + if (priv->have_static_opps)
4554 + dev_pm_opp_of_cpumask_remove_table(priv->cpus);
4555 + if (priv->opp_table)
4556 + dev_pm_opp_put_regulators(priv->opp_table);
4557 free_cpumask_var(priv->cpus);
4558 list_del(&priv->node);
4560 diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
4562 --- a/drivers/cpufreq/cpufreq.c
4564 @@ -688,8 +688,12 @@ static ssize_t show_##file_name \
4565 return sprintf(buf, "%u\n", policy->object); \
4570 + unsigned int max_freq = policy->cpuinfo.max_freq;
4574 -show_one(cpuinfo_max_freq, cpuinfo.max_freq);
4578 @@ -2535,6 +2539,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
4585 * cpufreq_update_policy - Re-evaluate an existing cpufreq policy.
4586 diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
4588 --- a/drivers/cpufreq/cpufreq_userspace.c
4590 @@ -78,20 +78,18 @@ static int cpufreq_userspace_policy_start(struct cpufreq_policy *policy)
4593 per_cpu(cpu_is_managed, policy->cpu) = 1;
4594 - *setspeed = policy->cur;
4596 + *setspeed = policy->cur;
4603 - unsigned int *setspeed = policy->governor_data;
4604 -
4605 pr_debug("managing cpu %u stopped\n", policy->cpu);
4608 per_cpu(cpu_is_managed, policy->cpu) = 0;
4609 - *setspeed = 0;
4613 diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
4615 --- a/drivers/cpuidle/driver.c
4617 @@ -381,3 +381,4 @@ void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
4622 diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
4624 --- a/drivers/cpuidle/governor.c
4626 @@ -102,6 +102,7 @@ int cpuidle_register_governor(struct cpuidle_governor *gov)
4633 * cpuidle_governor_latency_req - Compute a latency constraint for CPU
4634 @@ -118,3 +119,4 @@ s64 cpuidle_governor_latency_req(unsigned int cpu)
4639 diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
4641 --- a/drivers/devfreq/Kconfig
4643 @@ -131,15 +131,20 @@ config ARM_TEGRA20_DEVFREQ
4647 -config ARM_RK3399_DMC_DEVFREQ
4648 - tristate "ARM RK3399 DMC DEVFREQ Driver"
4660 - select DEVFREQ_GOV_SIMPLE_ONDEMAND
4663 - This adds the DEVFREQ driver for the RK3399 DMC(Dynamic Memory Controller).
4668 diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
4670 --- a/drivers/devfreq/Makefile
4672 @@ -11,9 +11,12 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o
4673 obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o
4674 obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o
4675 obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o
4676 -obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o
4677 +obj-$(CONFIG_ARM_ROCKCHIP_BUS_DEVFREQ) += rockchip_bus.o
4678 +obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ) += rockchip_dmc.o rockchip_dmc_common.o
4679 obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o
4680 obj-$(CONFIG_ARM_TEGRA20_DEVFREQ) += tegra20-devfreq.o
4683 obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
4685 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/gpu/drm/
4686 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
4688 --- a/drivers/devfreq/devfreq.c
4690 @@ -1763,6 +1763,40 @@ static ssize_t timer_store(struct device *dev, struct device_attribute *attr,
4699 + struct devfreq_dev_status stat = devfreq->last_status;
4718 + if (devfreq->profile->get_cur_freq &&
4719 + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
4722 + len += sprintf(buf + len, "@%luHz\n", devfreq->previous_freq);
4731 @@ -1775,6 +1809,7 @@ static struct attribute *devfreq_attrs[] = {
4739 diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig
4741 --- a/drivers/devfreq/event/Kconfig
4743 @@ -39,4 +39,11 @@ config DEVFREQ_EVENT_ROCKCHIP_DFI
4744 This add the devfreq-event driver for Rockchip SoC. It provides DFI
4751 + This add the devfreq-event driver for Rockchip SoC. It provides NoC
4755 diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile
4757 --- a/drivers/devfreq/event/Makefile
4759 @@ -4,3 +4,4 @@
4760 obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP) += exynos-nocp.o
4761 obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o
4762 obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI) += rockchip-dfi.o
4763 +obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP) += rockchip-nocp.o
4764 diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
4766 --- a/drivers/devfreq/event/rockchip-dfi.c
4767 +++ b/drivers/devfreq/event/rockchip-dfi.c
4768 @@ -20,23 +20,70 @@
4772 -#define RK3399_DMC_NUM_CH 2
4773 -
4810 -#define DDRMON_CTRL 0x04
4811 -#define CLR_DDRMON_CTRL (0x1f0000 << 0)
4812 -#define LPDDR4_EN (0x10001 << 4)
4813 -#define HARDWARE_EN (0x10001 << 3)
4814 -#define LPDDR3_EN (0x10001 << 2)
4815 -#define SOFTWARE_EN (0x10001 << 1)
4816 -#define SOFTWARE_DIS (0x10000 << 1)
4817 -#define TIME_CNT_EN (0x10001 << 0)
4849 @@ -50,33 +97,261 @@ struct dmc_usage {
4853 - struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
4873 + regmap_write(info->regmap_grf,
4882 + regmap_write(info->regmap_grf,
4917 + regmap_read(info->regmap_grf, RK3128_GRF_DFI_WRNUM, &dfi_wr);
4918 + regmap_read(info->regmap_grf, RK3128_GRF_DFI_RDNUM, &dfi_rd);
4919 + regmap_read(info->regmap_grf, RK3128_GRF_DFI_TIMERVAL, &dfi_timer);
4921 + edata->load_count = (dfi_wr + dfi_rd) * 4;
4922 + edata->total_count = dfi_timer;
4942 + regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_EN);
4949 + regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_DIS);
4982 + if (!(info->ch_msk & BIT(i)))
4984 + regmap_read(info->regmap_grf,
4986 + regmap_read(info->regmap_grf,
4988 + regmap_read(info->regmap_grf,
4990 + info->ch_usage[i].access = (wr_count + rd_count) * 4;
4991 + info->ch_usage[i].total = total_count;
4992 + tmp = info->ch_usage[i].access;
5014 + edata->load_count = info->ch_usage[busier_ch].access;
5015 + edata->total_count = info->ch_usage[busier_ch].total;
5031 + regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_EN);
5038 + regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_DIS);
5071 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS5, &dfi0_wr);
5072 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS6, &dfi0_rd);
5073 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS9, &dfi1_wr);
5074 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS10, &dfi1_rd);
5075 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS8, &dfi_timer);
5077 + edata->load_count = (dfi0_wr + dfi0_rd + dfi1_wr + dfi1_rd) * 2;
5078 + edata->total_count = dfi_timer;
5097 void __iomem *dfi_regs = info->regs;
5098 - u32 val;
5099 - u32 ddr_type;
5100 -
5101 - /* get ddr type */
5102 - regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
5103 - ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
5104 - RK3399_PMUGRF_DDRTYPE_MASK;
5110 - if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
5111 - writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
5112 - else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
5113 + if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
5115 + else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
5117 + else if (info->dram_type == DDR4)
5122 @@ -100,12 +375,22 @@ static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
5126 - for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
5127 - info->ch_usage[i].access = readl_relaxed(dfi_regs +
5128 - DDRMON_CH0_DFI_ACCESS_NUM + i * 20) * 4;
5130 + if (!(info->ch_msk & BIT(i)))
5133 info->ch_usage[i].total = readl_relaxed(dfi_regs +
5135 - tmp = info->ch_usage[i].access;
5140 + if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
5144 + info->ch_usage[i].access = tmp;
5149 @@ -121,7 +406,8 @@ static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
5153 - clk_disable_unprepare(info->clk);
5154 + if (info->clk)
5155 + clk_disable_unprepare(info->clk);
5159 @@ -131,10 +417,13 @@ static int rockchip_dfi_enable(struct devfreq_event_dev *edev)
5163 - ret = clk_prepare_enable(info->clk);
5164 - if (ret) {
5165 - dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret);
5166 - return ret;
5167 + if (info->clk) {
5168 + ret = clk_prepare_enable(info->clk);
5170 + dev_err(&edev->dev, "failed to enable dfi clk: %d\n",
5177 @@ -151,8 +440,11 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev *edev,
5187 edata->load_count = info->ch_usage[busier_ch].access;
5188 edata->total_count = info->ch_usage[busier_ch].total;
5189 @@ -167,22 +459,120 @@ static const struct devfreq_event_ops rockchip_dfi_ops = {
5193 -static const struct of_device_id rockchip_dfi_id_match[] = {
5194 - { .compatible = "rockchip,rk3399-dfi" },
5195 - { },
5196 -};
5197 -MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match);
5202 + struct device_node *np = pdev->dev.of_node, *node;
5206 -static int rockchip_dfi_probe(struct platform_device *pdev)
5208 + data->regs = devm_ioremap_resource(&pdev->dev, res);
5209 + if (IS_ERR(data->regs))
5210 + return PTR_ERR(data->regs);
5214 + data->regmap_pmugrf = syscon_node_to_regmap(node);
5215 + if (IS_ERR(data->regmap_pmugrf))
5216 + return PTR_ERR(data->regmap_pmugrf);
5219 + regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG2, &val_2);
5220 + regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG3, &val_3);
5222 + data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3);
5224 + data->dram_type = READ_DRAMTYPE_INFO(val_2);
5225 + data->ch_msk = 1;
5226 + data->clk = NULL;
5228 + desc->ops = &rockchip_dfi_ops;
5237 - struct device *dev = &pdev->dev;
5238 - struct rockchip_dfi *data;
5239 - struct devfreq_event_desc *desc;
5240 struct device_node *np = pdev->dev.of_node, *node;
5242 - data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL);
5243 - if (!data)
5244 - return -ENOMEM;
5247 + data->regmap_grf = syscon_node_to_regmap(node);
5248 + if (IS_ERR(data->regmap_grf))
5249 + return PTR_ERR(data->regmap_grf);
5252 + desc->ops = &rk3128_dfi_ops;
5261 + struct device_node *np = pdev->dev.of_node, *node;
5266 + data->regmap_pmu = syscon_node_to_regmap(node);
5267 + if (IS_ERR(data->regmap_pmu))
5268 + return PTR_ERR(data->regmap_pmu);
5273 + data->regmap_grf = syscon_node_to_regmap(node);
5274 + if (IS_ERR(data->regmap_grf))
5275 + return PTR_ERR(data->regmap_grf);
5278 + regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val);
5279 + data->dram_type = READ_DRAMTYPE_INFO(val);
5280 + data->ch_msk = READ_CH_INFO(val);
5282 + if (data->dram_type == DDR3)
5283 + regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
5286 + regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
5289 + desc->ops = &rk3288_dfi_ops;
5298 + struct device *dev = &pdev->dev;
5300 + if (!dev->parent || !dev->parent->of_node)
5301 + return -EINVAL;
5303 + data->regmap_grf = syscon_node_to_regmap(dev->parent->of_node);
5304 + if (IS_ERR(data->regmap_grf))
5305 + return PTR_ERR(data->regmap_grf);
5307 + desc->ops = &rk3368_dfi_ops;
5316 + struct device *dev = &pdev->dev;
5317 + struct device_node *np = pdev->dev.of_node, *node;
5320 data->regs = devm_platform_ioremap_resource(pdev, 0);
5321 if (IS_ERR(data->regs))
5322 @@ -202,23 +592,100 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
5323 if (IS_ERR(data->regmap_pmu))
5324 return PTR_ERR(data->regmap_pmu);
5326 - data->dev = dev;
5328 + regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val);
5329 + data->dram_type = READ_DRAMTYPE_INFO(val);
5330 + data->ch_msk = READ_CH_INFO(val);
5332 + desc->ops = &rockchip_dfi_ops;
5341 + struct device_node *np = pdev->dev.of_node, *node;
5346 + data->regs = devm_ioremap_resource(&pdev->dev, res);
5347 + if (IS_ERR(data->regs))
5348 + return PTR_ERR(data->regs);
5352 + data->regmap_grf = syscon_node_to_regmap(node);
5353 + if (IS_ERR(data->regmap_grf))
5354 + return PTR_ERR(data->regmap_grf);
5357 + regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val);
5358 + data->dram_type = READ_DRAMTYPE_INFO(val);
5359 + data->ch_msk = 1;
5360 + data->clk = NULL;
5362 + desc->ops = &rockchip_dfi_ops;
5368 + { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init },
5369 + { .compatible = "rockchip,rk1808-dfi", .data = px30_dfi_init },
5370 + { .compatible = "rockchip,rk3128-dfi", .data = rk3128_dfi_init },
5371 + { .compatible = "rockchip,rk3288-dfi", .data = rk3288_dfi_init },
5372 + { .compatible = "rockchip,rk3328-dfi", .data = rk3328_dfi_init },
5373 + { .compatible = "rockchip,rk3368-dfi", .data = rk3368_dfi_init },
5374 + { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init },
5375 + { .compatible = "rockchip,rk3568-dfi", .data = px30_dfi_init },
5376 + { .compatible = "rockchip,rv1126-dfi", .data = px30_dfi_init },
5382 + struct device *dev = &pdev->dev;
5385 + struct device_node *np = pdev->dev.of_node;
5392 + return -ENOMEM;
5396 return -ENOMEM;
5398 - desc->ops = &rockchip_dfi_ops;
5399 + match = of_match_node(rockchip_dfi_id_match, pdev->dev.of_node);
5401 + init = match->data;
5404 + return -EINVAL;
5412 desc->driver_data = data;
5413 desc->name = np->name;
5414 - data->desc = desc;
5416 - data->edev = devm_devfreq_event_add_edev(&pdev->dev, desc);
5417 + data->edev = devm_devfreq_event_add_edev(dev, desc);
5418 if (IS_ERR(data->edev)) {
5419 - dev_err(&pdev->dev,
5420 - "failed to add devfreq-event device\n");
5421 + dev_err(dev, "failed to add devfreq-event device\n");
5422 return PTR_ERR(data->edev);
5424 + data->desc = desc;
5425 + data->dev = &pdev->dev;
5429 diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig
5431 --- a/drivers/dma-buf/Kconfig
5432 +++ b/drivers/dma-buf/Kconfig
5433 @@ -21,7 +21,6 @@ config SW_SYNC
5437 - depends on DEBUG_FS
5441 @@ -80,7 +79,7 @@ menuconfig DMABUF_HEAPS
5444 bool "DMA-BUF sysfs statistics"
5445 - depends on DMA_SHARED_BUFFER
5448 Choose this option to enable DMA-BUF sysfs statistics
5450 diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.h b/drivers/dma-buf/dma-buf-sysfs-stats.h
5452 --- a/drivers/dma-buf/dma-buf-sysfs-stats.h
5453 +++ b/drivers/dma-buf/dma-buf-sysfs-stats.h
5454 @@ -14,8 +14,23 @@ int dma_buf_init_sysfs_statistics(void);
5463 + struct dma_buf_attach_sysfs_entry *entry = attach->sysfs_entry;
5465 + entry->map_counter += delta;
5471 + struct dma_buf_sysfs_entry *entry = dmabuf->sysfs_entry;
5473 + return entry->attachment_uid++;
5478 @@ -29,7 +44,19 @@ static inline int dma_buf_stats_setup(struct dma_buf *dmabuf)
5498 diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
5500 --- a/drivers/dma-buf/dma-buf.c
5501 +++ b/drivers/dma-buf/dma-buf.c
5502 @@ -32,8 +32,6 @@
5503 #include "dma-buf-sysfs-stats.h"
5504 #include "dma-buf-process-info.h"
5506 -static inline int is_dma_buf_file(struct file *);
5507 -
5511 @@ -41,6 +39,30 @@ struct dma_buf_list {
5542 @@ -129,6 +151,54 @@ static struct file_system_type dma_buf_fs_type = {
5549 + struct dma_buf *dmabuf = vma->vm_file->private_data;
5551 + dmabuf->mmap_count++;
5553 + if (dmabuf->exp_vm_ops->open)
5554 + dmabuf->exp_vm_ops->open(vma);
5559 + struct dma_buf *dmabuf = vma->vm_file->private_data;
5561 + if (dmabuf->mmap_count)
5562 + dmabuf->mmap_count--;
5564 + if (dmabuf->exp_vm_ops->close)
5565 + dmabuf->exp_vm_ops->close(vma);
5570 + /* call this first because the exporter might override vma->vm_ops */
5571 + int ret = dmabuf->ops->mmap(dmabuf, vma);
5577 + dmabuf->exp_vm_ops = vma->vm_ops;
5578 + dmabuf->vm_ops = *(dmabuf->exp_vm_ops);
5580 + dmabuf->vm_ops.open = dma_buf_vma_open;
5581 + dmabuf->vm_ops.close = dma_buf_vma_close;
5582 + vma->vm_ops = &dmabuf->vm_ops;
5583 + dmabuf->mmap_count++;
5590 + return dmabuf->ops->mmap(dmabuf, vma);
5597 @@ -147,7 +217,7 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
5598 dmabuf->size >> PAGE_SHIFT)
5599 return -EINVAL;
5601 - return dmabuf->ops->mmap(dmabuf, vma);
5606 @@ -442,10 +512,11 @@ static const struct file_operations dma_buf_fops = {
5608 * is_dma_buf_file - Check if struct file* is associated with dma_buf
5610 -static inline int is_dma_buf_file(struct file *file)
5613 return file->f_op == &dma_buf_fops;
5619 @@ -1132,6 +1203,30 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
5630 + return -EINVAL;
5632 + if (dmabuf->ops->begin_cpu_access_partial)
5633 + ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction,
5636 + /* Ensure that all fences are waited upon - but we first allow
5638 + * chooses. A double invocation here will be reasonably cheap no-op.
5648 * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the
5649 * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific
5650 @@ -1158,6 +1253,21 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf,
5662 + if (dmabuf->ops->end_cpu_access_partial)
5663 + ret = dmabuf->ops->end_cpu_access_partial(dmabuf, direction,
5671 * dma_buf_mmap - Setup up a userspace mmap with the given vma
5672 @@ -1286,6 +1396,32 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
5681 + return -EINVAL;
5683 + if (dmabuf->ops->get_flags)
5684 + ret = dmabuf->ops->get_flags(dmabuf, flags);
5693 + return -EINVAL;
5695 + if (!dmabuf->ops->get_uuid)
5696 + return -ENODEV;
5698 + return dmabuf->ops->get_uuid(dmabuf, uuid);
5705 diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
5707 --- a/drivers/dma-buf/dma-fence.c
5708 +++ b/drivers/dma-buf/dma-fence.c
5709 @@ -312,22 +312,25 @@ void __dma_fence_might_wait(void)
5713 - * dma_fence_signal_locked - signal completion of a fence
5714 + * dma_fence_signal_timestamp_locked - signal completion of a fence
5722 - * only be effective the first time.
5726 - * Unlike dma_fence_signal(), this function must be called with &dma_fence.lock
5727 - * held.
5734 -int dma_fence_signal_locked(struct dma_fence *fence)
5740 @@ -341,7 +344,7 @@ int dma_fence_signal_locked(struct dma_fence *fence)
5742 list_replace(&fence->cb_list, &cb_list);
5744 - fence->timestamp = ktime_get();
5745 + fence->timestamp = timestamp;
5746 set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
5749 @@ -352,6 +355,59 @@ int dma_fence_signal_locked(struct dma_fence *fence)
5756 + * dma_fence_signal_timestamp - signal completion of a fence
5776 + return -EINVAL;
5778 + spin_lock_irqsave(fence->lock, flags);
5780 + spin_unlock_irqrestore(fence->lock, flags);
5787 + * dma_fence_signal_locked - signal completion of a fence
5809 @@ -379,7 +435,7 @@ int dma_fence_signal(struct dma_fence *fence)
5812 spin_lock_irqsave(fence->lock, flags);
5813 - ret = dma_fence_signal_locked(fence);
5815 spin_unlock_irqrestore(fence->lock, flags);
5818 diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
5820 --- a/drivers/dma-buf/dma-heap.c
5821 +++ b/drivers/dma-buf/dma-heap.c
5822 @@ -30,6 +30,7 @@
5830 @@ -40,6 +41,8 @@ struct dma_heap {
5839 @@ -48,20 +51,72 @@ static dev_t dma_heap_devt;
5843 -static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
5844 - unsigned int fd_flags,
5845 - unsigned int heap_flags)
5852 + if (!strcmp(h->name, name)) {
5853 + kref_get(&h->refcount);
5875 + return ERR_PTR(-EINVAL);
5878 + return ERR_PTR(-EINVAL);
5885 - return -EINVAL;
5886 + return ERR_PTR(-EINVAL);
5888 return heap->ops->allocate(heap, len, fd_flags, heap_flags);
5916 @@ -89,15 +144,9 @@ static long dma_heap_ioctl_allocate(struct file *file, void *data)
5917 if (heap_allocation->fd)
5918 return -EINVAL;
5920 - if (heap_allocation->fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
5921 - return -EINVAL;
5922 -
5923 - if (heap_allocation->heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
5924 - return -EINVAL;
5925 -
5926 - fd = dma_heap_buffer_alloc(heap, heap_allocation->len,
5927 - heap_allocation->fd_flags,
5928 - heap_allocation->heap_flags);
5929 + fd = dma_heap_bufferfd_alloc(heap, heap_allocation->len,
5930 + heap_allocation->fd_flags,
5931 + heap_allocation->heap_flags);
5935 @@ -189,6 +238,47 @@ void *dma_heap_get_drvdata(struct dma_heap *heap)
5937 return heap->priv;
5944 + int minor = MINOR(heap->heap_devt);
5947 + list_del(&heap->list);
5949 + device_destroy(dma_heap_class, heap->heap_devt);
5950 + cdev_del(&heap->heap_cdev);
5963 + kref_put(&h->refcount, dma_heap_release);
5969 + * dma_heap_get_dev() - get device struct for the heap
5970 + * @heap: DMA-Heap to retrieve device struct from
5977 + return heap->heap_dev;
5982 * dma_heap_get_name() - get heap name
5983 @@ -201,11 +291,11 @@ const char *dma_heap_get_name(struct dma_heap *heap)
5985 return heap->name;
5991 - struct dma_heap *heap, *h, *err_ret;
5992 - struct device *dev_ret;
5997 @@ -220,21 +310,19 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
6001 - mutex_lock(&heap_list_lock);
6002 - list_for_each_entry(h, &heap_list, list) {
6003 - if (!strcmp(h->name, exp_info->name)) {
6004 - mutex_unlock(&heap_list_lock);
6005 - pr_err("dma_heap: Already registered heap named %s\n",
6006 - exp_info->name);
6007 - return ERR_PTR(-EINVAL);
6008 - }
6009 + heap = dma_heap_find(exp_info->name);
6012 + exp_info->name);
6014 + return ERR_PTR(-EINVAL);
6016 - mutex_unlock(&heap_list_lock);
6020 return ERR_PTR(-ENOMEM);
6022 + kref_init(&heap->refcount);
6023 heap->name = exp_info->name;
6024 heap->ops = exp_info->ops;
6025 heap->priv = exp_info->priv;
6026 @@ -259,16 +347,20 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
6030 - dev_ret = device_create(dma_heap_class,
6031 - NULL,
6032 - heap->heap_devt,
6033 - NULL,
6034 - heap->name);
6035 - if (IS_ERR(dev_ret)) {
6036 + heap->heap_dev = device_create(dma_heap_class,
6038 + heap->heap_devt,
6040 + heap->name);
6041 + if (IS_ERR(heap->heap_dev)) {
6043 - err_ret = ERR_CAST(dev_ret);
6044 + err_ret = ERR_CAST(heap->heap_dev);
6049 + heap->heap_dev = get_device(heap->heap_dev);
6053 list_add(&heap->list, &heap_list);
6054 @@ -284,27 +376,88 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
6073 + if (heap->ops->get_pool_size)
6074 + total_pool_size += heap->ops->get_pool_size(heap);
6099 + return -ENOMEM;
6119 - ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME);
6130 - unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS);
6131 - return PTR_ERR(dma_heap_class);
6135 dma_heap_class->devnode = dma_heap_devnode;
6146 diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
6148 --- a/drivers/dma-buf/heaps/Kconfig
6149 +++ b/drivers/dma-buf/heaps/Kconfig
6150 @@ -1,12 +1,22 @@
6152 + bool "DMA-BUF heaps deferred-free library"
6154 + Choose this option to enable the DMA-BUF heaps deferred-free library.
6157 + bool "DMA-BUF heaps page-pool library"
6159 + Choose this option to enable the DMA-BUF heaps page-pool library.
6162 - bool "DMA-BUF System Heap"
6163 - depends on DMABUF_HEAPS
6164 + tristate "DMA-BUF System Heap"
6171 - bool "DMA-BUF CMA Heap"
6172 + tristate "DMA-BUF CMA Heap"
6175 Choose this option to enable dma-buf CMA heap. This heap is backed
6176 diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
6178 --- a/drivers/dma-buf/heaps/Makefile
6179 +++ b/drivers/dma-buf/heaps/Makefile
6180 @@ -1,4 +1,5 @@
6181 # SPDX-License-Identifier: GPL-2.0
6182 -obj-y += heap-helpers.o
6183 +obj-$(CONFIG_DMABUF_HEAPS_DEFERRED_FREE) += deferred-free-helper.o
6184 +obj-$(CONFIG_DMABUF_HEAPS_PAGE_POOL) += page_pool.o
6185 obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
6186 obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
6187 diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
6189 --- a/drivers/dma-buf/heaps/cma_heap.c
6190 +++ b/drivers/dma-buf/heaps/cma_heap.c
6191 @@ -2,76 +2,304 @@
6195 - * Copyright (C) 2012, 2019 Linaro Ltd.
6197 * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
6200 + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6203 -
6205 -#include <linux/device.h>
6206 #include <linux/dma-buf.h>
6207 #include <linux/dma-heap.h>
6208 #include <linux/dma-map-ops.h>
6210 -#include <linux/errno.h>
6215 -#include <linux/slab.h>
6217 -#include <linux/sched/signal.h>
6221 -#include "heap-helpers.h"
6228 -static void cma_heap_free(struct heap_helper_buffer *buffer)
6251 + struct cma_heap_buffer *buffer = dmabuf->priv;
6257 + return -ENOMEM;
6259 + ret = sg_alloc_table_from_pages(&a->table, buffer->pages,
6260 + buffer->pagecount, 0,
6261 + buffer->pagecount << PAGE_SHIFT,
6268 + a->dev = attachment->dev;
6269 + INIT_LIST_HEAD(&a->list);
6270 + a->mapped = false;
6272 + attachment->priv = a;
6274 + mutex_lock(&buffer->lock);
6275 + list_add(&a->list, &buffer->attachments);
6276 + mutex_unlock(&buffer->lock);
6284 + struct cma_heap_buffer *buffer = dmabuf->priv;
6285 + struct dma_heap_attachment *a = attachment->priv;
6287 + mutex_lock(&buffer->lock);
6288 + list_del(&a->list);
6289 + mutex_unlock(&buffer->lock);
6291 + sg_free_table(&a->table);
6298 - struct cma_heap *cma_heap = dma_heap_get_drvdata(buffer->heap);
6299 - unsigned long nr_pages = buffer->pagecount;
6300 - struct page *cma_pages = buffer->priv_virt;
6301 + struct dma_heap_attachment *a = attachment->priv;
6302 + struct sg_table *table = &a->table;
6305 + ret = dma_map_sgtable(attachment->dev, table, direction, 0);
6307 + return ERR_PTR(-ENOMEM);
6308 + a->mapped = true;
6316 + struct dma_heap_attachment *a = attachment->priv;
6318 + a->mapped = false;
6319 + dma_unmap_sgtable(attachment->dev, table, direction, 0);
6325 + struct cma_heap_buffer *buffer = dmabuf->priv;
6328 + if (buffer->vmap_cnt)
6329 + invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
6331 + mutex_lock(&buffer->lock);
6332 + list_for_each_entry(a, &buffer->attachments, list) {
6333 + if (!a->mapped)
6335 + dma_sync_sgtable_for_cpu(a->dev, &a->table, direction);
6337 + mutex_unlock(&buffer->lock);
6345 + struct cma_heap_buffer *buffer = dmabuf->priv;
6348 + if (buffer->vmap_cnt)
6349 + flush_kernel_vmap_range(buffer->vaddr, buffer->len);
6351 + mutex_lock(&buffer->lock);
6352 + list_for_each_entry(a, &buffer->attachments, list) {
6353 + if (!a->mapped)
6355 + dma_sync_sgtable_for_device(a->dev, &a->table, direction);
6357 + mutex_unlock(&buffer->lock);
6364 + struct vm_area_struct *vma = vmf->vma;
6365 + struct cma_heap_buffer *buffer = vma->vm_private_data;
6367 + if (vmf->pgoff > buffer->pagecount)
6370 + vmf->page = buffer->pages[vmf->pgoff];
6371 + get_page(vmf->page);
6382 + struct cma_heap_buffer *buffer = dmabuf->priv;
6384 + if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
6385 + return -EINVAL;
6387 + vma->vm_ops = &dma_heap_vm_ops;
6388 + vma->vm_private_data = buffer;
6397 + vaddr = vmap(buffer->pages, buffer->pagecount, VM_MAP, PAGE_KERNEL);
6399 + return ERR_PTR(-ENOMEM);
6406 + struct cma_heap_buffer *buffer = dmabuf->priv;
6409 + mutex_lock(&buffer->lock);
6410 + if (buffer->vmap_cnt) {
6411 + buffer->vmap_cnt++;
6412 + vaddr = buffer->vaddr;
6420 + buffer->vaddr = vaddr;
6421 + buffer->vmap_cnt++;
6423 + mutex_unlock(&buffer->lock);
6430 + struct cma_heap_buffer *buffer = dmabuf->priv;
6432 + mutex_lock(&buffer->lock);
6433 + if (!--buffer->vmap_cnt) {
6434 + vunmap(buffer->vaddr);
6435 + buffer->vaddr = NULL;
6437 + mutex_unlock(&buffer->lock);
6442 + struct cma_heap_buffer *buffer = dmabuf->priv;
6443 + struct cma_heap *cma_heap = buffer->heap;
6445 + if (buffer->vmap_cnt > 0) {
6447 + vunmap(buffer->vaddr);
6451 kfree(buffer->pages);
6453 - cma_release(cma_heap->cma, cma_pages, nr_pages);
6454 + cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount);
6458 -/* dmabuf heap CMA operations functions */
6459 -static int cma_heap_allocate(struct dma_heap *heap,
6460 - unsigned long len,
6461 - unsigned long fd_flags,
6462 - unsigned long heap_flags)
6482 - struct heap_helper_buffer *helper_buffer;
6483 - struct page *cma_pages;
6487 - unsigned long nr_pages = size >> PAGE_SHIFT;
6492 int ret = -ENOMEM;
6495 - if (align > CONFIG_CMA_ALIGNMENT)
6496 - align = CONFIG_CMA_ALIGNMENT;
6499 + return ERR_PTR(-ENOMEM);
6501 - helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
6502 - if (!helper_buffer)
6503 - return -ENOMEM;
6504 + INIT_LIST_HEAD(&buffer->attachments);
6505 + mutex_init(&buffer->lock);
6506 + buffer->len = size;
6508 - init_heap_helper_buffer(helper_buffer, cma_heap_free);
6509 - helper_buffer->heap = heap;
6510 - helper_buffer->size = len;
6514 - cma_pages = cma_alloc(cma_heap->cma, nr_pages, align, false);
6515 + cma_pages = cma_alloc(cma_heap->cma, pagecount, align, GFP_KERNEL);
6517 - goto free_buf;
6522 - unsigned long nr_clear_pages = nr_pages;
6527 @@ -85,7 +313,6 @@ static int cma_heap_allocate(struct dma_heap *heap,
6531 -
6533 nr_clear_pages--;
6535 @@ -93,44 +320,41 @@ static int cma_heap_allocate(struct dma_heap *heap,
6539 - helper_buffer->pagecount = nr_pages;
6540 - helper_buffer->pages = kmalloc_array(helper_buffer->pagecount,
6541 - sizeof(*helper_buffer->pages),
6542 - GFP_KERNEL);
6543 - if (!helper_buffer->pages) {
6544 + buffer->pages = kmalloc_array(pagecount, sizeof(*buffer->pages), GFP_KERNEL);
6545 + if (!buffer->pages) {
6546 ret = -ENOMEM;
6550 - for (pg = 0; pg < helper_buffer->pagecount; pg++)
6551 - helper_buffer->pages[pg] = &cma_pages[pg];
6553 + buffer->pages[pg] = &cma_pages[pg];
6555 + buffer->cma_pages = cma_pages;
6556 + buffer->heap = cma_heap;
6557 + buffer->pagecount = pagecount;
6560 - dmabuf = heap_helper_export_dmabuf(helper_buffer, fd_flags);
6563 + exp_info.size = buffer->len;
6572 - helper_buffer->dmabuf = dmabuf;
6573 - helper_buffer->priv_virt = cma_pages;
6574 -
6575 - ret = dma_buf_fd(dmabuf, fd_flags);
6576 - if (ret < 0) {
6577 - dma_buf_put(dmabuf);
6578 - /* just return, as put will call release and that will free */
6579 - return ret;
6580 - }
6581 -
6582 - return ret;
6586 - kfree(helper_buffer->pages);
6587 + kfree(buffer->pages);
6589 - cma_release(cma_heap->cma, cma_pages, nr_pages);
6590 -free_buf:
6591 - kfree(helper_buffer);
6592 - return ret;
6593 + cma_release(cma_heap->cma, cma_pages, pagecount);
6601 diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
6603 --- a/drivers/dma-buf/heaps/system_heap.c
6604 +++ b/drivers/dma-buf/heaps/system_heap.c
6605 @@ -3,7 +3,11 @@
6609 - * Copyright (C) 2019 Linaro Ltd.
6613 + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6617 #include <linux/dma-buf.h>
6618 @@ -15,99 +19,546 @@
6622 -#include <linux/sched/signal.h>
6623 -#include <asm/page.h>
6627 +#include "deferred-free-helper.h"
6651 -#include "heap-helpers.h"
6655 -struct dma_heap *sys_heap;
6671 -static void system_heap_free(struct heap_helper_buffer *buffer)
6674 - pgoff_t pg;
6679 - for (pg = 0; pg < buffer->pagecount; pg++)
6680 - __free_page(buffer->pages[pg]);
6681 - kfree(buffer->pages);
6682 - kfree(buffer);
6685 + return ERR_PTR(-ENOMEM);
6687 + ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL);
6690 + return ERR_PTR(-ENOMEM);
6693 + new_sg = new_table->sgl;
6695 + sg_set_page(new_sg, sg_page(sg), sg->length, sg->offset);
6702 -static int system_heap_allocate(struct dma_heap *heap,
6703 - unsigned long len,
6704 - unsigned long fd_flags,
6705 - unsigned long heap_flags)
6709 - struct heap_helper_buffer *helper_buffer;
6710 - struct dma_buf *dmabuf;
6711 - int ret = -ENOMEM;
6712 - pgoff_t pg;
6713 + struct system_heap_buffer *buffer = dmabuf->priv;
6719 + return -ENOMEM;
6721 - helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
6722 - if (!helper_buffer)
6723 + table = dup_sg_table(&buffer->sg_table);
6726 return -ENOMEM;
6729 + a->table = table;
6730 + a->dev = attachment->dev;
6731 + INIT_LIST_HEAD(&a->list);
6732 + a->mapped = false;
6733 + a->uncached = buffer->uncached;
6734 + attachment->priv = a;
6736 + mutex_lock(&buffer->lock);
6737 + list_add(&a->list, &buffer->attachments);
6738 + mutex_unlock(&buffer->lock);
6746 + struct system_heap_buffer *buffer = dmabuf->priv;
6747 + struct dma_heap_attachment *a = attachment->priv;
6749 + mutex_lock(&buffer->lock);
6750 + list_del(&a->list);
6751 + mutex_unlock(&buffer->lock);
6753 + sg_free_table(a->table);
6754 + kfree(a->table);
6758 - init_heap_helper_buffer(helper_buffer, system_heap_free);
6759 - helper_buffer->heap = heap;
6760 - helper_buffer->size = len;
6764 + struct dma_heap_attachment *a = attachment->priv;
6765 + struct sg_table *table = a->table;
6769 + if (a->uncached)
6772 + ret = dma_map_sgtable(attachment->dev, table, direction, attr);
6776 + a->mapped = true;
6784 + struct dma_heap_attachment *a = attachment->priv;
6787 + if (a->uncached)
6789 + a->mapped = false;
6790 + dma_unmap_sgtable(attachment->dev, table, direction, attr);
6793 - helper_buffer->pagecount = len / PAGE_SIZE;
6794 - helper_buffer->pages = kmalloc_array(helper_buffer->pagecount,
6795 - sizeof(*helper_buffer->pages),
6796 - GFP_KERNEL);
6797 - if (!helper_buffer->pages) {
6798 - ret = -ENOMEM;
6799 - goto err0;
6803 + struct system_heap_buffer *buffer = dmabuf->priv;
6806 + mutex_lock(&buffer->lock);
6808 + if (buffer->vmap_cnt)
6809 + invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
6811 + if (!buffer->uncached) {
6812 + list_for_each_entry(a, &buffer->attachments, list) {
6813 + if (!a->mapped)
6815 + dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
6818 + mutex_unlock(&buffer->lock);
6826 + struct system_heap_buffer *buffer = dmabuf->priv;
6829 + mutex_lock(&buffer->lock);
6831 + if (buffer->vmap_cnt)
6832 + flush_kernel_vmap_range(buffer->vaddr, buffer->len);
6834 + if (!buffer->uncached) {
6835 + list_for_each_entry(a, &buffer->attachments, list) {
6836 + if (!a->mapped)
6838 + dma_sync_sgtable_for_device(a->dev, a->table, direction);
6841 + mutex_unlock(&buffer->lock);
6848 + struct system_heap_buffer *buffer = dmabuf->priv;
6849 + struct sg_table *table = &buffer->sg_table;
6850 + unsigned long addr = vma->vm_start;
6854 + if (buffer->uncached)
6855 + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
6857 + for_each_sgtable_page(table, &piter, vma->vm_pgoff) {
6861 + vma->vm_page_prot);
6865 + if (addr >= vma->vm_end)
6873 + struct sg_table *table = &buffer->sg_table;
6874 + int npages = PAGE_ALIGN(buffer->len) / PAGE_SIZE;
6882 + return ERR_PTR(-ENOMEM);
6884 + if (buffer->uncached)
6888 + WARN_ON(tmp - pages >= npages);
6896 + return ERR_PTR(-ENOMEM);
6903 + struct system_heap_buffer *buffer = dmabuf->priv;
6906 + mutex_lock(&buffer->lock);
6907 + if (buffer->vmap_cnt) {
6908 + buffer->vmap_cnt++;
6909 + vaddr = buffer->vaddr;
6917 + buffer->vaddr = vaddr;
6918 + buffer->vmap_cnt++;
6920 + mutex_unlock(&buffer->lock);
6922 - for (pg = 0; pg < helper_buffer->pagecount; pg++) {
6928 + struct system_heap_buffer *buffer = dmabuf->priv;
6930 + mutex_lock(&buffer->lock);
6931 + if (!--buffer->vmap_cnt) {
6932 + vunmap(buffer->vaddr);
6933 + buffer->vaddr = NULL;
6935 + mutex_unlock(&buffer->lock);
6940 + struct sg_table *sgt = &buffer->sg_table;
6970 + table = &buffer->sg_table;
6971 + for_each_sg(table->sgl, sg, table->nents, i) {
6990 + struct system_heap_buffer *buffer = dmabuf->priv;
6991 + int npages = PAGE_ALIGN(buffer->len) / PAGE_SIZE;
6993 + deferred_free(&buffer->deferred_free, system_heap_buf_free, npages);
7043 + int i, ret = -ENOMEM;
7047 + return ERR_PTR(-ENOMEM);
7049 + INIT_LIST_HEAD(&buffer->attachments);
7050 + mutex_init(&buffer->lock);
7051 + buffer->heap = heap;
7052 + buffer->len = len;
7053 + buffer->uncached = uncached;
7060 - * has been killed by by SIGKILL
7064 - goto err1;
7071 + list_add_tail(&page->lru, &pages);
7072 + size_remaining -= page_size(page);
7077 - helper_buffer->pages[pg] = alloc_page(GFP_KERNEL | __GFP_ZERO);
7078 - if (!helper_buffer->pages[pg])
7079 - goto err1;
7080 + table = &buffer->sg_table;
7084 + sg = table->sgl;
7088 + list_del(&page->lru);
7092 - dmabuf = heap_helper_export_dmabuf(helper_buffer, fd_flags);
7095 + exp_info.size = buffer->len;
7101 - goto err1;
7111 + if (buffer->uncached) {
7116 - helper_buffer->dmabuf = dmabuf;
7119 - ret = dma_buf_fd(dmabuf, fd_flags);
7120 - if (ret < 0) {
7121 - dma_buf_put(dmabuf);
7122 - /* just return, as put will call release and that will free */
7123 - return ret;
7136 - return ret;
7140 -err1:
7141 - while (pg > 0)
7142 - __free_page(helper_buffer->pages[--pg]);
7143 - kfree(helper_buffer->pages);
7144 -err0:
7145 - kfree(helper_buffer);
7154 - return ret;
7163 + num_pages += ((*pool)->count[POOL_LOWPAGE] +
7164 + (*pool)->count[POOL_HIGHPAGE]) << (*pool)->order;
7189 + return ERR_PTR(-EBUSY);
7200 - int ret = 0;
7212 + return -ENOMEM;
7218 @@ -115,9 +566,21 @@ static int system_heap_create(void)
7222 - ret = PTR_ERR(sys_heap);
7225 - return ret;
7226 + exp_info.name = "system-uncached";
7242 diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
7244 --- a/drivers/dma-buf/sw_sync.c
7245 +++ b/drivers/dma-buf/sw_sync.c
7246 @@ -7,6 +7,8 @@
7255 @@ -410,3 +412,13 @@ const struct file_operations sw_sync_debugfs_fops = {
7269 diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c
7271 --- a/drivers/dma-buf/sync_debug.c
7272 +++ b/drivers/dma-buf/sync_debug.c
7273 @@ -8,6 +8,7 @@
7281 @@ -188,3 +189,4 @@ static __init int sync_debugfs_init(void)
7286 diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
7288 --- a/drivers/dma-buf/sync_debug.h
7289 +++ b/drivers/dma-buf/sync_debug.h
7290 @@ -62,11 +62,18 @@ struct sync_pt {
7309 diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
7311 --- a/drivers/firmware/Kconfig
7313 @@ -9,7 +9,7 @@ menu "Firmware Drivers"
7317 - depends on MAILBOX || HAVE_ARM_SMCCC_DISCOVERY
7321 set of operating system-independent software interfaces that are
7322 @@ -251,6 +251,13 @@ config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
7336 diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
7338 --- a/drivers/firmware/Makefile
7340 @@ -16,6 +16,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
7341 obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
7342 obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
7343 obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
7344 +obj-$(CONFIG_ROCKCHIP_SIP) += ../$(VENDOR_DRIVER_DIR)/firmware/
7345 obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
7346 obj-$(CONFIG_QCOM_SCM) += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
7347 obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o
7348 diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
7350 --- a/drivers/gpio/Kconfig
7352 @@ -495,6 +495,14 @@ config GPIO_REG
7353 A 32-bit single register GPIO fixed in/out implementation. This
7367 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
7369 --- a/drivers/gpio/Makefile
7371 @@ -125,6 +125,7 @@ obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
7372 obj-$(CONFIG_GPIO_RDA) += gpio-rda.o
7373 obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
7374 obj-$(CONFIG_GPIO_REG) += gpio-reg.o
7375 +obj-$(CONFIG_GPIO_ROCKCHIP) += ../$(VENDOR_DRIVER_DIR)/gpio/
7376 obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
7377 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
7378 obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
7379 diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
7381 --- a/drivers/gpio/gpiolib-of.c
7382 +++ b/drivers/gpio/gpiolib-of.c
7383 @@ -1039,3 +1039,14 @@ void of_gpiochip_remove(struct gpio_chip *chip)
7385 of_node_put(chip->of_node);
7391 + if (gc->of_node)
7392 + gdev->dev.of_node = gc->of_node;
7394 + gc->of_node = gdev->dev.of_node;
7395 + if (gdev->dev.of_node)
7396 + gdev->dev.fwnode = of_fwnode_handle(gdev->dev.of_node);
7398 diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h
7400 --- a/drivers/gpio/gpiolib-of.h
7401 +++ b/drivers/gpio/gpiolib-of.h
7402 @@ -15,6 +15,7 @@ int of_gpiochip_add(struct gpio_chip *gc);
7410 @@ -33,6 +34,10 @@ static inline bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
7421 diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
7423 --- a/drivers/gpu/Makefile
7425 @@ -3,6 +3,6 @@
7428 obj-$(CONFIG_TEGRA_HOST1X) += host1x/
7429 -obj-y += drm/ vga/
7430 +obj-y += drm/ vga/ arm/
7431 obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
7432 obj-$(CONFIG_TRACE_GPU_MEM) += trace/
7433 diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
7435 --- a/drivers/gpu/drm/Kconfig
7437 @@ -9,10 +9,10 @@ menuconfig DRM
7441 - select HDMI
7445 - select I2C_ALGOBIT
7449 # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate
7450 @@ -31,10 +31,30 @@ config DRM_MIPI_DBI
7481 diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
7483 --- a/drivers/gpu/drm/Makefile
7485 @@ -7,7 +7,7 @@ drm-y := drm_auth.o drm_cache.o \
7489 - drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \
7494 @@ -20,6 +20,7 @@ drm-y := drm_auth.o drm_cache.o \
7498 +drm-$(CONFIG_DRM_EDID) += drm_edid.o
7499 …drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm…
7500 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
7501 drm-$(CONFIG_DRM_VM) += drm_vm.o
7502 @@ -39,10 +40,10 @@ obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
7503 drm_ttm_helper-y := drm_gem_ttm_helper.o
7504 obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
7506 -drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
7507 +drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
7509 - drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
7510 - drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
7516 @@ -51,6 +52,8 @@ drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
7517 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
7518 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
7519 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
7520 +drm_kms_helper-$(CONFIG_DRM_DP) += drm_dp_helper.o drm_dp_mst_topology.o \
7522 drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
7523 drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
7525 diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
7527 --- a/drivers/gpu/drm/amd/display/Kconfig
7529 @@ -33,8 +33,6 @@ config DRM_AMD_DC_HDCP
7533 - depends on DRM_AMDGPU_SI
7534 - depends on DRM_AMD_DC
7538 diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
7540 --- a/drivers/gpu/drm/bridge/Kconfig
7542 @@ -126,6 +126,22 @@ config DRM_PARADE_PS8640
7543 The PS8640 is a high-performance and low-power
7565 diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
7567 --- a/drivers/gpu/drm/bridge/Makefile
7569 @@ -8,6 +8,8 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v
7570 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
7571 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
7572 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
7573 +obj-$(CONFIG_DRM_RK630_TVE) += rk630-tve.o
7574 +obj-$(CONFIG_DRM_RK1000_TVE) += rk1000.o
7575 obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
7576 obj-$(CONFIG_DRM_SII902X) += sii902x.o
7577 obj-$(CONFIG_DRM_SII9234) += sii9234.o
7578 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/a…
7580 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
7582 @@ -8,11 +8,13 @@
7586 +#include <linux/extcon-provider.h>
7596 @@ -35,11 +37,30 @@
7616 + req_bw = mode->clock * bpp / 8;
7627 @@ -64,6 +85,46 @@ static int analogix_dp_init_dp(struct analogix_dp_device *dp)
7635 + mutex_lock(&dp->panel_lock);
7637 + if (dp->panel_is_prepared)
7640 + ret = drm_panel_prepare(dp->plat_data->panel);
7644 + dp->panel_is_prepared = true;
7647 + mutex_unlock(&dp->panel_lock);
7655 + mutex_lock(&dp->panel_lock);
7657 + if (!dp->panel_is_prepared)
7660 + ret = drm_panel_unprepare(dp->plat_data->panel);
7664 + dp->panel_is_prepared = false;
7667 + mutex_unlock(&dp->panel_lock);
7674 @@ -108,6 +169,9 @@ static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
7678 + if (!device_property_read_bool(dp->dev, "support-psr"))
7681 ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version);
7683 dev_err(dp->dev, "failed to get PSR version, disable it\n");
7684 @@ -216,8 +280,24 @@ static int analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp)
7694 + ret = drm_dp_dpcd_readb(&dp->aux, DP_EDP_CONFIGURATION_CAP,
7704 + dp->link_train.enhanced_framing = data;
7709 @@ -233,32 +313,10 @@ static int analogix_dp_training_pattern_dis(struct analogix_dp_device *dp)
7713 -static void
7714 -analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp,
7715 - int pre_emphasis, int lane)
7716 -{
7717 - switch (lane) {
7718 - case 0:
7719 - analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
7720 - break;
7721 - case 1:
7722 - analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
7723 - break;
7724 -
7725 - case 2:
7726 - analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
7727 - break;
7728 -
7729 - case 3:
7730 - analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
7731 - break;
7732 - }
7733 -}
7734 -
7738 - int lane, lane_count, pll_tries, retval;
7741 lane_count = dp->link_train.lane_count;
7743 @@ -278,6 +336,14 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
7744 retval = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, 2);
7751 + retval = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, 2);
7758 @@ -285,22 +351,12 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
7762 - /* Set TX pre-emphasis to minimum */
7763 + /* Set TX voltage-swing and pre-emphasis to minimum */
7765 - analogix_dp_set_lane_lane_pre_emphasis(dp,
7766 - PRE_EMPHASIS_LEVEL_0, lane);
7767 -
7768 - /* Wait for PLL lock */
7769 - pll_tries = 0;
7770 - while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
7771 - if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
7772 - dev_err(dp->dev, "Wait for PLL lock timed out\n");
7773 - return -ETIMEDOUT;
7774 - }
7775 -
7776 - pll_tries++;
7777 - usleep_range(90, 120);
7778 - }
7779 + dp->link_train.training_lane[lane] =
7786 @@ -383,54 +439,6 @@ static unsigned char analogix_dp_get_adjust_request_pre_emphasis(
7790 -static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp,
7791 - u8 training_lane_set, int lane)
7792 -{
7793 - switch (lane) {
7794 - case 0:
7795 - analogix_dp_set_lane0_link_training(dp, training_lane_set);
7796 - break;
7797 - case 1:
7798 - analogix_dp_set_lane1_link_training(dp, training_lane_set);
7799 - break;
7800 -
7801 - case 2:
7802 - analogix_dp_set_lane2_link_training(dp, training_lane_set);
7803 - break;
7804 -
7805 - case 3:
7806 - analogix_dp_set_lane3_link_training(dp, training_lane_set);
7807 - break;
7808 - }
7809 -}
7810 -
7811 -static unsigned int
7812 -analogix_dp_get_lane_link_training(struct analogix_dp_device *dp,
7813 - int lane)
7814 -{
7815 - u32 reg;
7816 -
7817 - switch (lane) {
7818 - case 0:
7819 - reg = analogix_dp_get_lane0_link_training(dp);
7820 - break;
7821 - case 1:
7822 - reg = analogix_dp_get_lane1_link_training(dp);
7823 - break;
7824 - case 2:
7825 - reg = analogix_dp_get_lane2_link_training(dp);
7826 - break;
7827 - case 3:
7828 - reg = analogix_dp_get_lane3_link_training(dp);
7829 - break;
7830 - default:
7831 - WARN_ON(1);
7832 - return 0;
7833 - }
7834 -
7835 - return reg;
7836 -}
7837 -
7841 @@ -463,13 +471,27 @@ static void analogix_dp_get_adjust_training_lane(struct analogix_dp_device *d…
7851 + dp->video_info.max_link_rate == DP_LINK_BW_5_4;
7852 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &dpcd);
7865 - usleep_range(100, 101);
7866 + drm_dp_link_train_clock_recovery_delay(dp->dpcd);
7868 lane_count = dp->link_train.lane_count;
7870 @@ -483,12 +505,16 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
7874 - /* set training pattern 2 for EQ */
7875 - analogix_dp_set_training_pattern(dp, TRAINING_PTN2);
7882 retval = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
7884 - DP_TRAINING_PATTERN_2);
7890 @@ -522,10 +548,7 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
7894 -
7895 - for (lane = 0; lane < lane_count; lane++)
7896 - analogix_dp_set_lane_link_training(dp,
7897 - dp->link_train.training_lane[lane], lane);
7900 retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
7901 dp->link_train.training_lane, lane_count);
7902 @@ -537,11 +560,11 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
7906 - int lane, lane_count, retval;
7911 - usleep_range(400, 401);
7912 + drm_dp_link_train_channel_eq_delay(dp->dpcd);
7914 lane_count = dp->link_train.lane_count;
7916 @@ -597,9 +620,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
7917 return -EIO;
7920 - for (lane = 0; lane < lane_count; lane++)
7921 - analogix_dp_set_lane_link_training(dp,
7922 - dp->link_train.training_lane[lane], lane);
7925 retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
7926 dp->link_train.training_lane, lane_count);
7927 @@ -609,10 +630,11 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *…
7931 -static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
7932 - u8 *bandwidth)
7941 @@ -620,28 +642,41 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
7945 - drm_dp_dpcd_readb(&dp->aux, DP_MAX_LINK_RATE, &data);
7946 + ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LINK_RATE, &data);
7955 -static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp,
7956 - u8 *lane_count)
7967 - drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data);
7968 + ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data);
7980 + struct video_info *video = &dp->video_info;
7987 @@ -667,6 +702,16 @@ static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
7988 dp->link_train.lane_count = (u8)LANE_COUNT1;
7991 + if (!analogix_dp_bandwidth_ok(dp, &video->mode,
7992 + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate),
7993 + dp->link_train.lane_count)) {
7994 + dev_err(dp->dev, "bandwidth overflow\n");
7995 + return -EINVAL;
7998 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &dpcd);
7999 + dp->link_train.ssc = !!(dpcd & DP_MAX_DOWNSPREAD_0_5);
8001 /* Setup TX lane count & rate */
8002 if (dp->link_train.lane_count > max_lanes)
8003 dp->link_train.lane_count = max_lanes;
8004 @@ -711,27 +756,15 @@ static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
8008 - int i, ret;
8011 - enum pll_status status;
8015 analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
8016 analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
8017 -
8018 - for (i = 0; i < dp->link_train.lane_count; i++) {
8019 - analogix_dp_set_lane_link_training(dp,
8020 - dp->link_train.training_lane[i], i);
8021 - }
8022 -
8023 - ret = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status,
8024 - status != PLL_UNLOCKED, 120,
8025 - 120 * DP_TIMEOUT_LOOP_COUNT);
8026 - if (ret) {
8027 - DRM_DEV_ERROR(dp->dev, "Wait for pll lock failed %d\n", ret);
8028 - return ret;
8029 - }
8031 + analogix_dp_enable_enhanced_mode(dp, dp->link_train.enhanced_framing);
8035 @@ -742,7 +775,6 @@ static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
8036 /* From DP spec, pattern must be on-screen for a minimum 500us */
8039 - /* TODO: enhanced_mode?*/
8043 @@ -884,38 +916,21 @@ static int analogix_dp_enable_scramble(struct analogix_dp_device *dp,
8047 -static irqreturn_t analogix_dp_hardirq(int irq, void *arg)
8051 - irqreturn_t ret = IRQ_NONE;
8052 - enum dp_irq_type irq_type;
8054 - irq_type = analogix_dp_get_irq_type(dp);
8055 - if (irq_type != DP_IRQ_TYPE_UNKNOWN) {
8056 - analogix_dp_mute_hpd_interrupt(dp);
8057 - ret = IRQ_WAKE_THREAD;
8058 - }
8059 + if (dp->drm_dev)
8060 + drm_helper_hpd_irq_event(dp->drm_dev);
8062 - return ret;
8069 - enum dp_irq_type irq_type;
8071 - irq_type = analogix_dp_get_irq_type(dp);
8072 - if (irq_type & DP_IRQ_TYPE_HP_CABLE_IN ||
8073 - irq_type & DP_IRQ_TYPE_HP_CABLE_OUT) {
8074 - dev_dbg(dp->dev, "Detected cable status changed!\n");
8075 - if (dp->drm_dev)
8076 - drm_helper_hpd_irq_event(dp->drm_dev);
8077 - }
8078 -
8079 - if (irq_type != DP_IRQ_TYPE_UNKNOWN) {
8080 - analogix_dp_clear_hotplug_interrupts(dp);
8081 - analogix_dp_unmute_hpd_interrupt(dp);
8082 - }
8087 @@ -936,16 +951,73 @@ static int analogix_dp_fast_link_train_detection(struct analogix_dp_device *d…
8096 + if (dp->dpcd[DP_DPCD_REV] < 0x11)
8099 + ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value);
8106 + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value);
8120 + if (dp->dpcd[DP_DPCD_REV] < 0x11)
8123 + ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value);
8130 + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value);
8139 + struct video_info *video = &dp->video_info;
8142 - /* Keep the panel disabled while we configure video */
8143 - if (dp->plat_data->panel) {
8144 - if (drm_panel_disable(dp->plat_data->panel))
8145 - DRM_ERROR("failed to disable the panel\n");
8146 + ret = drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd);
8148 + dev_err(dp->dev, "failed to read dpcd caps: %d\n", ret);
8154 + dev_err(dp->dev, "failed to power up link: %d\n", ret);
8158 + if (device_property_read_bool(dp->dev, "panel-self-test"))
8159 + return drm_dp_dpcd_writeb(&dp->aux, DP_EDP_CONFIGURATION_SET,
8164 dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
8165 @@ -959,21 +1031,17 @@ static int analogix_dp_commit(struct analogix_dp_device *dp)
8171 + if (video->video_bist_enable)
8176 dev_err(dp->dev, "unable to config video\n");
8180 - /* Safe to enable the panel now */
8181 - if (dp->plat_data->panel) {
8182 - ret = drm_panel_enable(dp->plat_data->panel);
8183 - if (ret) {
8184 - DRM_ERROR("failed to enable the panel\n");
8185 - return ret;
8186 - }
8187 - }
8188 -
8192 @@ -1010,9 +1078,20 @@ static int analogix_dp_enable_psr(struct analogix_dp_device *dp)
8196 - if (!ret)
8200 + if (dp->phy) {
8205 + ret = phy_configure(dp->phy, &phy_cfg);
8214 @@ -1058,70 +1137,24 @@ static int analogix_dp_disable_psr(struct analogix_dp_device *dp)
8218 -/*
8219 - * This function is a bit of a catch-all for panel preparation, hopefully
8220 - * simplifying the logic of functions that need to prepare/unprepare the panel
8221 - * below.
8222 - *
8223 - * If @prepare is true, this function will prepare the panel. Conversely, if it
8224 - * is false, the panel will be unprepared.
8225 - *
8226 - * If @is_modeset_prepare is true, the function will disregard the current state
8227 - * of the panel and either prepare/unprepare the panel based on @prepare. Once
8228 - * it finishes, it will update dp->panel_is_modeset to reflect the current state
8229 - * of the panel.
8230 - */
8231 -static int analogix_dp_prepare_panel(struct analogix_dp_device *dp,
8232 - bool prepare, bool is_modeset_prepare)
8233 -{
8234 - int ret = 0;
8235 -
8236 - if (!dp->plat_data->panel)
8237 - return 0;
8238 -
8239 - mutex_lock(&dp->panel_lock);
8240 -
8241 - /*
8242 - * Exit early if this is a temporary prepare/unprepare and we're already
8243 - * modeset (since we neither want to prepare twice or unprepare early).
8244 - */
8245 - if (dp->panel_is_modeset && !is_modeset_prepare)
8246 - goto out;
8247 -
8248 - if (prepare)
8249 - ret = drm_panel_prepare(dp->plat_data->panel);
8250 - else
8251 - ret = drm_panel_unprepare(dp->plat_data->panel);
8252 -
8253 - if (ret)
8254 - goto out;
8255 -
8256 - if (is_modeset_prepare)
8257 - dp->panel_is_modeset = prepare;
8258 -
8259 -out:
8260 - mutex_unlock(&dp->panel_lock);
8261 - return ret;
8262 -}
8263 -
8270 - if (dp->plat_data->panel) {
8271 + if (dp->plat_data->panel)
8272 num_modes += drm_panel_get_modes(dp->plat_data->panel, connector);
8273 - } else {
8274 - ret = analogix_dp_prepare_panel(dp, true, false);
8275 - if (ret) {
8276 - DRM_ERROR("Failed to prepare panel (%d)\n", ret);
8282 - }
8284 - pm_runtime_get_sync(dp->dev);
8285 + if (dp->plat_data->panel)
8288 edid = drm_get_edid(connector, &dp->aux.ddc);
8289 - pm_runtime_put(dp->dev);
8291 drm_connector_update_edid_property(&dp->connector,
8293 @@ -1129,14 +1162,19 @@ static int analogix_dp_get_modes(struct drm_connector *connector)
8297 - ret = analogix_dp_prepare_panel(dp, false, false);
8298 - if (ret)
8299 - DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
8303 if (dp->plat_data->get_modes)
8304 num_modes += dp->plat_data->get_modes(dp->plat_data, connector);
8306 + if (num_modes > 0 && dp->plat_data->split_mode) {
8309 + list_for_each_entry(mode, &connector->probed_modes, head)
8310 + dp->plat_data->convert_to_split_mode(mode);
8316 @@ -1182,38 +1220,76 @@ static const struct drm_connector_helper_funcs analogix_dp_connector_helper…
8320 -analogix_dp_detect(struct drm_connector *connector, bool force)
8323 - struct analogix_dp_device *dp = to_dp(connector);
8327 - if (dp->plat_data->panel)
8328 - return connector_status_connected;
8329 -
8330 - ret = analogix_dp_prepare_panel(dp, true, false);
8333 - DRM_ERROR("Failed to prepare panel (%d)\n", ret);
8334 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
8338 - if (!analogix_dp_detect_hpd(dp))
8339 + if (dp->plat_data->panel)
8343 + ret = analogix_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
8345 + dev_err(dp->dev, "failed to read max link rate\n");
8349 + ret = analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
8351 + dev_err(dp->dev, "failed to read max lane count\n");
8358 - ret = analogix_dp_prepare_panel(dp, false, false);
8359 - if (ret)
8360 - DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
8365 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true);
8367 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
8377 + if (dp->plat_data->right && analogix_dp_detect(dp->plat_data->right) != connector_status_connecte…
8387 + if (connector->status == connector_status_connected)
8388 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true);
8390 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
8395 - .detect = analogix_dp_detect,
8405 @@ -1224,10 +1300,8 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
8409 - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
8410 - DRM_ERROR("Fix bridge driver to make connector optional!");
8411 - return -EINVAL;
8412 - }
8416 if (!bridge->encoder) {
8418 @@ -1240,6 +1314,8 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
8420 ret = drm_connector_init(dp->drm_dev, connector,
8422 + dp->plat_data->bridge ?
8423 + dp->plat_data->bridge->type :
8427 @@ -1268,11 +1344,20 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
8433 + struct analogix_dp_device *dp = bridge->driver_private;
8435 + if (dp->plat_data->detach)
8436 + dp->plat_data->detach(dp->plat_data, bridge);
8443 - struct drm_encoder *encoder = dp->encoder;
8444 + struct drm_bridge *bridge = &dp->bridge;
8445 + struct drm_encoder *encoder = bridge->encoder;
8449 @@ -1295,7 +1380,6 @@ analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
8450 struct analogix_dp_device *dp = bridge->driver_private;
8453 - int ret;
8457 @@ -1306,27 +1390,20 @@ analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
8458 if (old_crtc_state && old_crtc_state->self_refresh_active)
8461 - ret = analogix_dp_prepare_panel(dp, true, true);
8462 - if (ret)
8463 - DRM_ERROR("failed to setup the panel ret = %d\n", ret);
8464 + if (dp->plat_data->panel)
8472 - pm_runtime_get_sync(dp->dev);
8473 -
8474 - ret = clk_prepare_enable(dp->clock);
8475 - if (ret < 0) {
8476 - DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
8477 - goto out_dp_clk_pre;
8478 - }
8479 -
8480 if (dp->plat_data->power_on_start)
8481 dp->plat_data->power_on_start(dp->plat_data);
8483 - phy_power_on(dp->phy);
8490 @@ -1344,28 +1421,35 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
8494 - if (ret) {
8500 + if (dp->plat_data->panel)
8501 + drm_panel_enable(dp->plat_data->panel);
8503 if (dp->plat_data->power_on_end)
8504 dp->plat_data->power_on_end(dp->plat_data);
8506 - enable_irq(dp->irq);
8510 - phy_power_off(dp->phy);
8512 if (dp->plat_data->power_off)
8513 dp->plat_data->power_off(dp->plat_data);
8514 - clk_disable_unprepare(dp->clock);
8515 -out_dp_clk_pre:
8516 - pm_runtime_put_sync(dp->dev);
8517 -
8527 + drm_kms_helper_hotplug_event(dp->bridge.dev);
8533 @@ -1404,12 +1488,14 @@ analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge,
8536 dev_err(dp->dev, "too many times retry set bridge, give it up\n");
8539 + schedule_work(&dp->modeset_retry_work);
8544 struct analogix_dp_device *dp = bridge->driver_private;
8545 - int ret;
8547 if (dp->dpms_mode != DRM_MODE_DPMS_ON)
8549 @@ -1421,21 +1507,17 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
8553 - disable_irq(dp->irq);
8557 if (dp->plat_data->power_off)
8558 dp->plat_data->power_off(dp->plat_data);
8561 - phy_power_off(dp->phy);
8564 - clk_disable_unprepare(dp->clock);
8565 -
8566 - pm_runtime_put_sync(dp->dev);
8567 -
8568 - ret = analogix_dp_prepare_panel(dp, false, true);
8569 - if (ret)
8570 - DRM_ERROR("failed to setup the panel ret = %d\n", ret);
8571 + if (dp->plat_data->panel)
8574 dp->fast_train_enable = false;
8575 dp->psr_supported = false;
8576 @@ -1492,14 +1574,19 @@ analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge,
8580 - const struct drm_display_mode *mode)
8583 struct analogix_dp_device *dp = bridge->driver_private;
8584 struct drm_display_info *display_info = &dp->connector.display_info;
8585 struct video_info *video = &dp->video_info;
8586 + struct drm_display_mode *mode = &video->mode;
8587 struct device_node *dp_node = dp->dev->of_node;
8591 + if (dp->plat_data->split_mode)
8592 + dp->plat_data->convert_to_origin_mode(mode);
8595 video->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
8596 video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
8597 @@ -1508,16 +1595,12 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
8601 - (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) {
8603 video->dynamic_range = CEA;
8604 - video->ycbcr_coeff = COLOR_YCBCR601;
8605 - } else if (vic) {
8607 video->dynamic_range = CEA;
8608 - video->ycbcr_coeff = COLOR_YCBCR709;
8609 - } else {
8611 video->dynamic_range = VESA;
8612 - video->ycbcr_coeff = COLOR_YCBCR709;
8613 - }
8616 switch (display_info->bpc) {
8617 @@ -1537,12 +1620,16 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
8618 video->color_depth = COLOR_8;
8621 - if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
8622 + if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB444) {
8623 video->color_space = COLOR_YCBCR444;
8624 - else if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
8625 + video->ycbcr_coeff = COLOR_YCBCR709;
8626 + } else if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422) {
8627 video->color_space = COLOR_YCBCR422;
8628 - else
8629 + video->ycbcr_coeff = COLOR_YCBCR709;
8631 video->color_space = COLOR_RGB;
8632 + video->ycbcr_coeff = COLOR_YCBCR601;
8637 @@ -1567,6 +1654,56 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
8638 video->interlaced = true;
8669 + struct analogix_dp_device *dp = bridge->driver_private;
8675 + if (dp->plat_data->split_mode)
8676 + dp->plat_data->convert_to_origin_mode(&m);
8678 + max_link_rate = min_t(u32, dp->video_info.max_link_rate,
8679 + dp->link_train.link_rate);
8680 + max_lane_count = min_t(u32, dp->video_info.max_lane_count,
8681 + dp->link_train.lane_count);
8694 @@ -1577,29 +1714,30 @@ static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
8702 -static int analogix_dp_create_bridge(struct drm_device *drm_dev,
8703 - struct analogix_dp_device *dp)
8706 - struct drm_bridge *bridge;
8707 + struct drm_bridge *bridge = &dp->bridge;
8710 - bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
8711 - if (!bridge) {
8712 - DRM_ERROR("failed to allocate for drm bridge\n");
8713 - return -ENOMEM;
8714 + if (!dp->plat_data->left) {
8715 + ret = drm_bridge_attach(dp->encoder, bridge, NULL, 0);
8722 - dp->bridge = bridge;
8723 -
8724 - bridge->driver_private = dp;
8725 - bridge->funcs = &analogix_dp_bridge_funcs;
8726 + if (dp->plat_data->right) {
8727 + struct analogix_dp_device *secondary = dp->plat_data->right;
8729 - ret = drm_bridge_attach(dp->encoder, bridge, NULL, 0);
8730 - if (ret) {
8731 - DRM_ERROR("failed to attach drm bridge\n");
8732 - return -EINVAL;
8733 + ret = drm_bridge_attach(dp->encoder, &secondary->bridge, bridge,
8740 @@ -1609,10 +1747,11 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
8742 struct device_node *dp_node = dp->dev->of_node;
8743 struct video_info *video_info = &dp->video_info;
8747 switch (dp->plat_data->dev_type) {
8749 - case RK3399_EDP:
8753 @@ -1620,6 +1759,10 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
8754 video_info->max_link_rate = 0x0A;
8755 video_info->max_lane_count = 0x04;
8758 + video_info->max_link_rate = 0x14;
8759 + video_info->max_lane_count = 0x04;
8764 @@ -1632,6 +1775,35 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
8768 + video_info->video_bist_enable =
8769 + of_property_read_bool(dp_node, "analogix,video-bist-enable");
8771 + prop = of_find_property(dp_node, "data-lanes", &len);
8773 + video_info->lane_map[0] = 0;
8774 + video_info->lane_map[1] = 1;
8775 + video_info->lane_map[2] = 2;
8776 + video_info->lane_map[3] = 3;
8777 + DRM_DEV_DEBUG(dp->dev, "failed to find data lane mapping, using default\n");
8784 + DRM_DEV_ERROR(dp->dev, "bad number of data lanes\n");
8785 + return -EINVAL;
8788 + video_info->max_lane_count = num_lanes;
8790 + ret = of_property_read_u32_array(dp_node, "data-lanes",
8791 + video_info->lane_map, num_lanes);
8793 + DRM_DEV_ERROR(dp->dev, "failed to read lane data\n");
8800 @@ -1643,13 +1815,99 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux,
8808 + switch (daifmt->fmt) {
8816 + DRM_DEV_ERROR(dp->dev, "invalid daifmt %d\n", daifmt->fmt);
8817 + return -EINVAL;
8840 + memcpy(buf, dp->connector.eld, min(sizeof(dp->connector.eld), len));
8853 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &spread);
8855 + dp->link_train.link_rate = link_rate;
8856 + dp->link_train.lane_count = lane_count;
8857 + dp->link_train.enhanced_framing = analogix_dp_get_enhanced_mode(dp);
8858 + dp->link_train.ssc = !!(spread & DP_MAX_DOWNSPREAD_0_5);
8861 + dp->link_train.training_lane[lane] =
8873 + dp->dpms_mode = DRM_MODE_DPMS_ON;
8897 - unsigned int irq_flags;
8901 @@ -1663,9 +1921,10 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_dat…
8903 dp->dev = &pdev->dev;
8904 dp->dpms_mode = DRM_MODE_DPMS_OFF;
8905 + INIT_WORK(&dp->modeset_retry_work, analogix_dp_modeset_retry_work_fn);
8907 mutex_init(&dp->panel_lock);
8908 - dp->panel_is_modeset = false;
8909 + dp->panel_is_prepared = false;
8913 @@ -1694,13 +1953,13 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_da…
8917 - dp->clock = devm_clk_get(&pdev->dev, "dp");
8918 - if (IS_ERR(dp->clock)) {
8919 - dev_err(&pdev->dev, "failed to get clock\n");
8920 - return ERR_CAST(dp->clock);
8921 + ret = devm_clk_bulk_get_all(dev, &dp->clks);
8927 - clk_prepare_enable(dp->clock);
8928 + dp->nr_clks = ret;
8932 @@ -1722,34 +1981,49 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_da…
8935 if (dp->hpd_gpiod) {
8936 - /*
8937 - * Set up the hotplug GPIO from the device tree as an interrupt.
8938 - * Simply specifying a different interrupt in the device tree
8939 - * doesn't work since we handle hotplug rather differently when
8940 - * using a GPIO. We also need the actual GPIO specifier so
8941 - * that we can get the current state of the GPIO.
8942 - */
8943 - dp->irq = gpiod_to_irq(dp->hpd_gpiod);
8944 - irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
8945 - } else {
8946 - dp->irq = platform_get_irq(pdev, 0);
8947 - irq_flags = 0;
8949 + gpiod_to_irq(dp->hpd_gpiod),
8955 + "analogix-hpd", dp);
8962 + dp->irq = platform_get_irq(pdev, 0);
8963 if (dp->irq == -ENXIO) {
8964 dev_err(&pdev->dev, "failed to get irq\n");
8965 return ERR_PTR(-ENODEV);
8968 - ret = devm_request_threaded_irq(&pdev->dev, dp->irq,
8969 - analogix_dp_hardirq,
8970 + irq_set_status_flags(dp->irq, IRQ_NOAUTOEN);
8971 + ret = devm_request_threaded_irq(dev, dp->irq, NULL,
8973 - irq_flags, "analogix-dp", dp);
8976 dev_err(&pdev->dev, "failed to request irq\n");
8979 - disable_irq(dp->irq);
8981 + dp->extcon = devm_extcon_dev_allocate(dev, analogix_dp_cable);
8982 + if (IS_ERR(dp->extcon)) {
8984 + return ERR_CAST(dp->extcon);
8987 + ret = devm_extcon_dev_register(dev, dp->extcon);
8993 + dp->bridge.driver_private = dp;
8994 + dp->bridge.funcs = &analogix_dp_bridge_funcs;
8998 @@ -1771,16 +2045,21 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_…
9001 pm_runtime_enable(dp->dev);
9002 + pm_runtime_get_sync(dp->dev);
9005 - ret = analogix_dp_create_bridge(drm_dev, dp);
9008 - DRM_ERROR("failed to create bridge (%d)\n", ret);
9013 + enable_irq(dp->irq);
9018 + pm_runtime_put(dp->dev);
9019 pm_runtime_disable(dp->dev);
9022 @@ -1789,34 +2068,23 @@ EXPORT_SYMBOL_GPL(analogix_dp_bind);
9026 - analogix_dp_bridge_disable(dp->bridge);
9027 + disable_irq(dp->irq);
9028 dp->connector.funcs->destroy(&dp->connector);
9029 -
9030 - if (dp->plat_data->panel) {
9031 - if (drm_panel_unprepare(dp->plat_data->panel))
9032 - DRM_ERROR("failed to turnoff the panel\n");
9033 - }
9034 -
9035 drm_dp_aux_unregister(&dp->aux);
9036 + pm_runtime_put(dp->dev);
9037 pm_runtime_disable(dp->dev);
9043 - clk_disable_unprepare(dp->clock);
9044 + cancel_work_sync(&dp->modeset_retry_work);
9048 -#ifdef CONFIG_PM
9051 - clk_disable_unprepare(dp->clock);
9052 -
9053 - if (dp->plat_data->panel) {
9054 - if (drm_panel_unprepare(dp->plat_data->panel))
9055 - DRM_ERROR("failed to turnoff the panel\n");
9056 - }
9057 + pm_runtime_force_suspend(dp->dev);
9061 @@ -1824,25 +2092,26 @@ EXPORT_SYMBOL_GPL(analogix_dp_suspend);
9065 - int ret;
9066 + pm_runtime_force_resume(dp->dev);
9069 - ret = clk_prepare_enable(dp->clock);
9070 - if (ret < 0) {
9071 - DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
9072 - return ret;
9073 - }
9078 - if (dp->plat_data->panel) {
9079 - if (drm_panel_prepare(dp->plat_data->panel)) {
9080 - DRM_ERROR("failed to setup the panel\n");
9081 - return -EBUSY;
9082 - }
9083 - }
9086 + clk_bulk_disable_unprepare(dp->nr_clks, dp->clks);
9090 -EXPORT_SYMBOL_GPL(analogix_dp_resume);
9091 -#endif
9096 + return clk_bulk_prepare_enable(dp->nr_clks, dp->clks);
9102 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/a…
9104 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
9106 @@ -10,6 +10,7 @@
9114 @@ -69,6 +70,7 @@ enum pattern_set {
9122 @@ -120,15 +122,9 @@ enum analog_power_block {
9126 -enum dp_irq_type {
9127 - DP_IRQ_TYPE_HP_CABLE_IN = BIT(0),
9128 - DP_IRQ_TYPE_HP_CABLE_OUT = BIT(1),
9129 - DP_IRQ_TYPE_HP_CHANGE = BIT(2),
9130 - DP_IRQ_TYPE_UNKNOWN = BIT(3),
9131 -};
9132 -
9139 @@ -141,6 +137,9 @@ struct video_info {
9149 @@ -150,6 +149,8 @@ struct link_train {
9158 @@ -159,9 +160,10 @@ struct analogix_dp_device {
9162 - struct drm_bridge *bridge;
9165 - struct clk *clock;
9171 @@ -173,17 +175,19 @@ struct analogix_dp_device {
9178 - bool panel_is_modeset;
9189 -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable);
9193 @@ -199,7 +203,6 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
9197 -enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
9201 @@ -211,28 +214,11 @@ void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count);
9208 -void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
9209 - u32 level);
9210 -void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
9211 - u32 level);
9212 -void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
9213 - u32 level);
9214 -void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
9215 - u32 level);
9216 -void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
9217 - u32 training_lane);
9218 -void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
9219 - u32 training_lane);
9220 -void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
9221 - u32 training_lane);
9222 -void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
9223 - u32 training_lane);
9224 -u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp);
9225 -u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp);
9226 -u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp);
9227 -u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp);
9233 @@ -255,5 +241,16 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
9250 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/an…
9252 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
9254 @@ -11,30 +11,44 @@
9266 -#define COMMON_INT_MASK_1 0
9267 -#define COMMON_INT_MASK_2 0
9268 -#define COMMON_INT_MASK_3 0
9269 -#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
9270 -#define INT_STA_MASK INT_HPD
9273 + if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
9274 + readl(dp->reg_base);
9275 + writel(val, dp->reg_base + reg);
9278 + writel(val, dp->reg_base + reg);
9283 + if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
9284 + readl(dp->reg_base + reg);
9286 + return readl(dp->reg_base + reg);
9294 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9297 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9300 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9303 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9308 @@ -42,23 +56,20 @@ void analogix_dp_stop_video(struct analogix_dp_device *dp)
9312 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9315 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9319 -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
9322 - u32 reg;
9323 + struct video_info *video_info = &dp->video_info;
9326 - if (enable)
9327 - reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
9328 - LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
9329 - else
9330 - reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
9331 - LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
9332 + for (i = 0; i < video_info->max_lane_count; i++)
9333 + reg |= video_info->lane_map[i] << (2 * i);
9335 - writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
9340 @@ -66,53 +77,54 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
9344 - writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1);
9348 - writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
9351 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
9353 if (dp->plat_data->dev_type == RK3288_DP)
9356 - writel(reg, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
9357 - writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
9358 - writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
9359 - writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
9360 - writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
9370 - writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
9375 - writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1);
9380 - writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL);
9387 - writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL);
9391 - writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
9392 - writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2);
9393 - writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3);
9394 - writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
9395 - writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA);
9403 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
9404 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
9405 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
9406 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9407 - writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9416 @@ -130,65 +142,54 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
9420 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
9426 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9431 - analogix_dp_lane_swap(dp, 0);
9432 -
9433 - writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
9434 - writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
9435 - writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9436 - writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
9439 - writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
9440 - writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL);
9446 - writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L);
9447 - writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H);
9451 - writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL);
9454 - writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST);
9457 - writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD);
9458 - writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN);
9462 - writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH);
9463 - writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH);
9467 - writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
9473 - writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET);
9479 - u32 reg;
9480 -
9482 - reg = COMMON_INT_MASK_1;
9483 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
9484 -
9485 - reg = COMMON_INT_MASK_2;
9486 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
9487 -
9488 - reg = COMMON_INT_MASK_3;
9489 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
9494 - reg = COMMON_INT_MASK_4;
9495 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9496 -
9497 - reg = INT_STA_MASK;
9498 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9499 + if (dp->force_hpd || dp->hpd_gpiod)
9506 @@ -196,13 +197,13 @@ void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp)
9510 - reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9511 - reg &= ~COMMON_INT_MASK_4;
9512 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9517 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9518 - reg &= ~INT_STA_MASK;
9519 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9526 @@ -210,18 +211,20 @@ void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp)
9530 - reg = COMMON_INT_MASK_4;
9531 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9536 - reg = INT_STA_MASK;
9537 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9547 - reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
9552 @@ -239,12 +242,12 @@ void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enabl…
9556 - reg = readl(dp->reg_base + pd_addr);
9562 - writel(reg, dp->reg_base + pd_addr);
9567 @@ -265,52 +268,54 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
9571 - reg = readl(dp->reg_base + phy_pd_addr);
9572 - if (enable)
9577 - else
9580 - writel(reg, dp->reg_base + phy_pd_addr);
9586 - reg = readl(dp->reg_base + phy_pd_addr);
9593 - writel(reg, dp->reg_base + phy_pd_addr);
9598 - reg = readl(dp->reg_base + phy_pd_addr);
9605 - writel(reg, dp->reg_base + phy_pd_addr);
9610 - reg = readl(dp->reg_base + phy_pd_addr);
9617 - writel(reg, dp->reg_base + phy_pd_addr);
9622 - reg = readl(dp->reg_base + phy_pd_addr);
9629 - writel(reg, dp->reg_base + phy_pd_addr);
9634 @@ -323,29 +328,29 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
9638 - reg = readl(dp->reg_base + phy_pd_addr);
9645 - writel(reg, dp->reg_base + phy_pd_addr);
9647 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
9653 - writel(reg, dp->reg_base + phy_pd_addr);
9657 - writel(reg, dp->reg_base + phy_pd_addr);
9661 - writel(reg, dp->reg_base + phy_pd_addr);
9665 - writel(0x00, dp->reg_base + phy_pd_addr);
9670 @@ -356,36 +361,24 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
9674 - int timeout_loop = 0;
9679 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
9682 - reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
9685 - writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
9689 - if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
9690 - analogix_dp_set_pll_power_down(dp, 0);
9691 -
9692 - while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
9693 - timeout_loop++;
9694 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
9695 - dev_err(dp->dev, "failed to get pll lock status\n");
9696 - return -ETIMEDOUT;
9697 - }
9698 - usleep_range(10, 20);
9699 - }
9700 - }
9704 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9708 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9713 @@ -397,10 +390,10 @@ void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
9717 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
9721 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
9726 @@ -410,47 +403,47 @@ void analogix_dp_init_hpd(struct analogix_dp_device *dp)
9727 if (dp->hpd_gpiod)
9730 - analogix_dp_clear_hotplug_interrupts(dp);
9734 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9737 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9745 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9746 - reg = (F_HPD | HPD_CTRL);
9747 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9753 -enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
9759 - if (dp->hpd_gpiod) {
9760 - reg = gpiod_get_value(dp->hpd_gpiod);
9761 - if (reg)
9762 - return DP_IRQ_TYPE_HP_CABLE_IN;
9763 - else
9764 - return DP_IRQ_TYPE_HP_CABLE_OUT;
9765 - } else {
9766 - /* Parse hotplug interrupt status register */
9767 - reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
9768 -
9769 - if (reg & PLUG)
9770 - return DP_IRQ_TYPE_HP_CABLE_IN;
9773 + dev_info(dp->dev, "irq-hpd, it's being ignored for now\n");
9777 - if (reg & HPD_LOST)
9778 - return DP_IRQ_TYPE_HP_CABLE_OUT;
9785 - if (reg & HOTPLUG_CHG)
9786 - return DP_IRQ_TYPE_HP_CHANGE;
9788 + drm_helper_hpd_irq_event(dp->drm_dev);
9791 - return DP_IRQ_TYPE_UNKNOWN;
9792 - }
9799 @@ -458,9 +451,9 @@ void analogix_dp_reset_aux(struct analogix_dp_device *dp)
9803 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9806 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9811 @@ -469,7 +462,7 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
9815 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
9820 @@ -487,16 +480,17 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
9824 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
9829 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL);
9833 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9837 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9842 @@ -507,7 +501,7 @@ int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp)
9843 if (gpiod_get_value(dp->hpd_gpiod))
9846 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9851 @@ -519,148 +513,193 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
9855 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
9858 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
9862 -int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp)
9865 - int reg;
9866 - int retval = 0;
9867 - int timeout_loop = 0;
9868 -
9869 - /* Enable AUX CH operation */
9870 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
9871 - reg |= AUX_EN;
9872 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
9873 -
9874 - /* Is AUX CH command reply received? */
9875 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
9876 - while (!(reg & RPLY_RECEIV)) {
9877 - timeout_loop++;
9878 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
9879 - dev_err(dp->dev, "AUX CH command reply failed!\n");
9880 - return -ETIMEDOUT;
9881 - }
9882 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
9883 - usleep_range(10, 11);
9884 - }
9885 -
9886 - /* Clear interrupt source for AUX CH command reply */
9887 - writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
9888 -
9889 - /* Clear interrupt source for AUX CH access error */
9890 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
9891 - if (reg & AUX_ERR) {
9892 - writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
9893 - return -EREMOTEIO;
9894 - }
9895 -
9896 - /* Check AUX CH error access status */
9897 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
9898 - if ((reg & AUX_STATUS_MASK) != 0) {
9899 - dev_err(dp->dev, "AUX CH error happens: %d\n\n",
9900 - reg & AUX_STATUS_MASK);
9901 - return -EREMOTEIO;
9902 - }
9905 - return retval;
9907 + writel(0x19, dp->reg_base + ANALOIGX_DP_SSC_REG);
9912 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9914 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9916 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9919 -int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
9920 - unsigned int reg_addr,
9921 - unsigned char data)
9925 - int i;
9926 - int retval;
9927 -
9928 - for (i = 0; i < 3; i++) {
9929 - /* Clear AUX CH data buffer */
9930 - reg = BUF_CLR;
9931 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
9932 -
9933 - /* Select DPCD device address */
9934 - reg = AUX_ADDR_7_0(reg_addr);
9935 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
9936 - reg = AUX_ADDR_15_8(reg_addr);
9937 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
9938 - reg = AUX_ADDR_19_16(reg_addr);
9939 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
9940 -
9941 - /* Write data buffer */
9942 - reg = (unsigned int)data;
9943 - writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
9945 - /*
9946 - * Set DisplayPort transaction and write 1 byte
9947 - * If bit 3 is 1, DisplayPort transaction.
9948 - * If Bit 3 is 0, I2C transaction.
9949 - */
9950 - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
9951 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
9952 -
9953 - /* Start AUX transaction */
9954 - retval = analogix_dp_start_aux_transaction(dp);
9955 - if (retval == 0)
9956 - break;
9957 -
9958 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
9959 - }
9960 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9962 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9965 - return retval;
9969 + return dp->plat_data->ssc && dp->link_train.ssc;
9974 - u32 reg;
9980 + if (dp->phy) {
9983 + phy_cfg.dp.lanes = dp->link_train.lane_count;
9985 + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
9990 + ret = phy_configure(dp->phy, &phy_cfg);
9991 + if (ret && ret != -EOPNOTSUPP) {
9992 + dev_err(dp->dev, "%s: phy_configure failed: %d\n",
10003 - reg = bwtype;
10004 - if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
10005 - writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
10010 + dev_err(dp->dev, "Wait for pll lock failed %d\n", ret);
10019 - reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
10030 - writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
10033 + if (dp->phy) {
10036 + phy_cfg.dp.lanes = dp->link_train.lane_count;
10040 + ret = phy_configure(dp->phy, &phy_cfg);
10041 + if (ret && ret != -EOPNOTSUPP) {
10042 + dev_err(dp->dev, "%s: phy_configure() failed: %d\n",
10053 - reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
10063 + for (lane = 0; lane < dp->link_train.lane_count; lane++)
10066 + dp->link_train.training_lane[lane]);
10068 + if (dp->phy) {
10071 + for (lane = 0; lane < dp->link_train.lane_count; lane++) {
10072 + u8 training_lane = dp->link_train.training_lane[lane];
10083 + phy_cfg.dp.lanes = dp->link_train.lane_count;
10085 + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
10089 + ret = phy_configure(dp->phy, &phy_cfg);
10090 + if (ret && ret != -EOPNOTSUPP) {
10091 + dev_err(dp->dev, "%s: phy_configure() failed: %d\n",
10110 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10113 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10116 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10119 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10136 @@ -669,144 +708,48 @@ void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
10140 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10145 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10150 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10155 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10166 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10174 -void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
10175 - u32 level)
10176 -{
10177 - u32 reg;
10178 -
10179 - reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
10180 - reg &= ~PRE_EMPHASIS_SET_MASK;
10181 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
10182 - writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
10183 -}
10184 -
10185 -void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
10186 - u32 level)
10187 -{
10188 - u32 reg;
10189 -
10190 - reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
10191 - reg &= ~PRE_EMPHASIS_SET_MASK;
10192 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
10193 - writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
10194 -}
10195 -
10196 -void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
10197 - u32 level)
10198 -{
10199 - u32 reg;
10200 -
10201 - reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
10202 - reg &= ~PRE_EMPHASIS_SET_MASK;
10203 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
10204 - writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
10205 -}
10206 -
10207 -void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
10208 - u32 level)
10209 -{
10210 - u32 reg;
10211 -
10212 - reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
10213 - reg &= ~PRE_EMPHASIS_SET_MASK;
10214 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
10215 - writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
10216 -}
10217 -
10218 -void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
10219 - u32 training_lane)
10220 -{
10221 - u32 reg;
10222 -
10223 - reg = training_lane;
10224 - writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
10225 -}
10226 -
10227 -void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
10228 - u32 training_lane)
10229 -{
10230 - u32 reg;
10231 -
10232 - reg = training_lane;
10233 - writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
10234 -}
10235 -
10236 -void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
10237 - u32 training_lane)
10238 -{
10239 - u32 reg;
10240 -
10241 - reg = training_lane;
10242 - writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
10243 -}
10244 -
10245 -void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
10246 - u32 training_lane)
10247 -{
10248 - u32 reg;
10249 -
10250 - reg = training_lane;
10251 - writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
10252 -}
10253 -
10254 -u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
10255 -{
10256 - return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
10257 -}
10258 -
10259 -u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
10260 -{
10261 - return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
10262 -}
10263 -
10264 -u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
10265 -{
10266 - return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
10267 -}
10268 -
10269 -u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
10270 -{
10271 - return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
10272 -}
10273 -
10278 - reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
10281 - writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
10288 - writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
10293 @@ -814,19 +757,19 @@ void analogix_dp_init_video(struct analogix_dp_device *dp)
10297 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
10301 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10305 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10309 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10313 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
10318 @@ -837,36 +780,36 @@ void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
10319 reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
10320 (dp->video_info.color_depth << IN_BPC_SHIFT) |
10321 (dp->video_info.color_space << IN_COLOR_F_SHIFT);
10322 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
10326 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10329 if (dp->video_info.ycbcr_coeff)
10333 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10341 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10342 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10346 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10350 dev_dbg(dp->dev, "Input stream clock not detected.\n");
10351 return -EINVAL;
10354 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10355 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10359 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10361 dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
10364 @@ -884,30 +827,30 @@ void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
10368 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10371 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10374 - writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
10377 - writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
10380 - writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
10384 - writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
10387 - writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
10390 - writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
10393 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10396 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10399 - writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
10400 - writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
10401 - writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
10408 @@ -916,13 +859,13 @@ void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 typ…
10412 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10415 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10418 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10421 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10426 @@ -931,15 +874,15 @@ void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enab…
10430 - reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10434 - writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10437 - reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10441 - writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10446 @@ -947,19 +890,19 @@ void analogix_dp_start_video(struct analogix_dp_device *dp)
10450 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
10453 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
10461 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10462 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10466 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10469 dev_dbg(dp->dev, "Input video stream is not detected.\n");
10470 return -EINVAL;
10471 @@ -972,55 +915,55 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
10475 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
10477 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
10483 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
10486 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10489 reg |= (dp->video_info.interlaced << 2);
10490 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10493 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10496 reg |= (dp->video_info.v_sync_polarity << 1);
10497 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10500 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10503 reg |= (dp->video_info.h_sync_polarity << 0);
10504 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10508 - writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10516 - reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10519 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10527 - reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10530 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10536 - writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
10541 @@ -1036,6 +979,24 @@ static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
10549 + switch (dp->plat_data->dev_type) {
10566 @@ -1044,53 +1005,66 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
10570 - val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10573 - writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10577 - writel(PSR_FRAME_UP_TYPE_BURST | PSR_CRC_SEL_HARDWARE,
10578 - dp->reg_base + ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL);
10583 - writel(vsc->sdp_header.HB0, dp->reg_base + ANALOGIX_DP_SPD_HB0);
10584 - writel(vsc->sdp_header.HB1, dp->reg_base + ANALOGIX_DP_SPD_HB1);
10585 - writel(vsc->sdp_header.HB2, dp->reg_base + ANALOGIX_DP_SPD_HB2);
10586 - writel(vsc->sdp_header.HB3, dp->reg_base + ANALOGIX_DP_SPD_HB3);
10587 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB0, vsc->sdp_header.HB0);
10588 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB1, vsc->sdp_header.HB1);
10589 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB2, vsc->sdp_header.HB2);
10590 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB3, vsc->sdp_header.HB3);
10593 - writel(0x00, dp->reg_base + ANALOGIX_DP_SPD_PB0);
10594 - writel(0x16, dp->reg_base + ANALOGIX_DP_SPD_PB1);
10595 - writel(0xCE, dp->reg_base + ANALOGIX_DP_SPD_PB2);
10596 - writel(0x5D, dp->reg_base + ANALOGIX_DP_SPD_PB3);
10603 - writel(vsc->db[0], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB0);
10604 - writel(vsc->db[1], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB1);
10605 + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB0, vsc->db[0]);
10606 + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB1, vsc->db[1]);
10610 + vsc->db[1] ? 0x8d : 0x00);
10614 - val = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10615 - val |= REUSE_SPD_EN;
10616 - writel(val, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10620 - val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10623 - writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10627 - val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10630 - writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10639 + * (a) ACTIVE_RESYNC - the sink "must display the
10642 + * re-synchronizing; or
10643 + * (b) INACTIVE - the transition is fully complete.
10647 ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
10648 - (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
10649 - DP_TIMEOUT_PSR_LOOP_MS * 1000);
10650 + (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC ||
10654 dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
10656 @@ -1098,11 +1072,46 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
10664 + ret = phy_set_mode(dp->phy, PHY_MODE_DP);
10666 + dev_err(dp->dev, "phy_set_mode failed: %d\n", ret);
10670 + ret = phy_power_on(dp->phy);
10672 + dev_err(dp->dev, "phy_power_on failed: %d\n", ret);
10681 + phy_power_off(dp->phy);
10700 - u32 status_reg;
10701 u8 *buffer = msg->buffer;
10704 @@ -1114,7 +1123,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10708 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
10711 switch (msg->request & ~DP_AUX_I2C_MOT) {
10713 @@ -1142,21 +1151,21 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10716 reg |= AUX_LENGTH(msg->size);
10717 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
10721 reg = AUX_ADDR_7_0(msg->address);
10722 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
10724 reg = AUX_ADDR_15_8(msg->address);
10725 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
10727 reg = AUX_ADDR_19_16(msg->address);
10728 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
10731 if (!(msg->request & DP_AUX_I2C_READ)) {
10732 for (i = 0; i < msg->size; i++) {
10734 - writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
10735 - 4 * i);
10741 @@ -1168,7 +1177,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10742 if (msg->size < 1)
10745 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
10748 ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
10750 @@ -1187,30 +1196,31 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10754 - writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
10755 -
10756 - /* Clear interrupt source for AUX CH access error */
10757 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
10758 - status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
10759 - if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
10760 - writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
10763 - dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
10764 - status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
10765 - goto aux_error;
10766 - }
10769 + return -ETIMEDOUT;
10771 if (msg->request & DP_AUX_I2C_READ) {
10777 + if (buf_data_count != msg->size)
10778 + return -EBUSY;
10780 for (i = 0; i < msg->size; i++) {
10781 - reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
10782 - 4 * i);
10791 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
10794 msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
10796 @@ -1222,7 +1232,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10797 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
10798 msg->reply = DP_AUX_NATIVE_REPLY_ACK;
10800 - return num_transferred > 0 ? num_transferred : -EBUSY;
10801 + return (num_transferred == msg->size) ? num_transferred : -EBUSY;
10805 @@ -1230,3 +1240,127 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10807 return -EREMOTEIO;
10812 + struct video_info *video = &dp->video_info;
10813 + const struct drm_display_mode *mode = &video->mode;
10816 + hsw = mode->hsync_end - mode->hsync_start;
10817 + hfp = mode->hsync_start - mode->hdisplay;
10818 + hbp = mode->htotal - mode->hsync_end;
10819 + vsw = mode->vsync_end - mode->vsync_start;
10820 + vfp = mode->vsync_start - mode->vdisplay;
10821 + vbp = mode->vtotal - mode->vsync_end;
10825 + TOTAL_LINE_CFG_L(mode->vtotal));
10827 + TOTAL_LINE_CFG_H(mode->vtotal >> 8));
10829 + ACTIVE_LINE_CFG_L(mode->vdisplay));
10831 + ACTIVE_LINE_CFG_H(mode->vdisplay >> 8));
10839 + TOTAL_PIXEL_CFG_L(mode->htotal));
10841 + TOTAL_PIXEL_CFG_H(mode->htotal >> 8));
10843 + ACTIVE_PIXEL_CFG_L(mode->hdisplay));
10845 + ACTIVE_PIXEL_CFG_H(mode->hdisplay >> 8));
10933 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/an…
10935 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
10937 @@ -15,9 +15,27 @@
10965 @@ -27,6 +45,8 @@
10974 @@ -43,6 +63,8 @@
10983 @@ -70,7 +92,7 @@
10987 -
10992 @@ -116,8 +138,9 @@
10996 -
11003 @@ -171,6 +194,11 @@
11015 @@ -181,6 +209,60 @@
11076 @@ -309,6 +391,10 @@
11087 @@ -319,6 +405,7 @@
11095 @@ -406,6 +493,11 @@
11107 @@ -414,4 +506,7 @@
11115 diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c
11117 --- a/drivers/gpu/drm/bridge/display-connector.c
11118 +++ b/drivers/gpu/drm/bridge/display-connector.c
11119 @@ -11,7 +11,9 @@
11129 @@ -20,6 +22,8 @@ struct display_connector {
11138 @@ -84,10 +88,95 @@ static struct edid *display_connector_get_edid(struct drm_bridge *bridge,
11139 return drm_get_edid(connector, conn->bridge.ddc);
11158 + if (!prev_bridge || !prev_bridge->funcs->atomic_get_output_bus_fmts) {
11159 + struct drm_connector *conn = conn_state->connector;
11167 + if (conn->display_info.num_bus_formats &&
11168 + conn->display_info.bus_formats)
11169 + out_bus_fmts[0] = conn->display_info.bus_formats[0];
11176 + prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
11179 + return prev_bridge->funcs->atomic_get_output_bus_fmts(prev_bridge, prev_bridge_state,
11201 + if (!prev_bridge || !prev_bridge->funcs->atomic_get_input_bus_fmts) {
11214 + prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
11217 + return prev_bridge->funcs->atomic_get_input_bus_fmts(prev_bridge, prev_bridge_state,
11234 @@ -172,11 +261,12 @@ static int display_connector_probe(struct platform_device *pdev)
11235 of_property_read_string(pdev->dev.of_node, "label", &label);
11238 - * Get the HPD GPIO for DVI and HDMI connectors. If the GPIO can provide
11243 - type == DRM_MODE_CONNECTOR_HDMIA) {
11246 conn->hpd_gpio = devm_gpiod_get_optional(&pdev->dev, "hpd",
11248 if (IS_ERR(conn->hpd_gpio)) {
11249 @@ -223,6 +313,38 @@ static int display_connector_probe(struct platform_device *pdev)
11257 + conn->dp_pwr = devm_regulator_get_optional(&pdev->dev, "dp-pwr");
11259 + if (IS_ERR(conn->dp_pwr)) {
11260 + ret = PTR_ERR(conn->dp_pwr);
11263 + case -ENODEV:
11264 + conn->dp_pwr = NULL;
11267 + case -EPROBE_DEFER:
11268 + return -EPROBE_DEFER;
11271 + dev_err(&pdev->dev, "failed to get DP PWR regulator: %d\n", ret);
11276 + if (conn->dp_pwr) {
11277 + ret = regulator_enable(conn->dp_pwr);
11279 + dev_err(&pdev->dev, "failed to enable DP PWR regulator: %d\n", ret);
11285 conn->bridge.funcs = &display_connector_bridge_funcs;
11286 conn->bridge.of_node = pdev->dev.of_node;
11288 @@ -251,6 +373,9 @@ static int display_connector_remove(struct platform_device *pdev)
11292 + if (conn->dp_pwr)
11293 + regulator_disable(conn->dp_pwr);
11295 drm_bridge_remove(&conn->bridge);
11297 if (!IS_ERR(conn->bridge.ddc))
11298 @@ -275,6 +400,9 @@ static const struct of_device_id display_connector_match[] = {
11300 .compatible = "vga-connector",
11303 + .compatible = "dp-connector",
11308 diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
11310 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c
11311 +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
11312 @@ -867,14 +867,8 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge,
11316 - struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
11318 - if (!lt9611_mode)
11319 - return MODE_BAD;
11320 - else if (lt9611_mode->intfs > 1 && !lt9611->dsi1)
11321 - return MODE_PANEL;
11322 - else
11323 - return MODE_OK;
11328 diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
11330 --- a/drivers/gpu/drm/bridge/nwl-dsi.c
11331 +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
11332 @@ -196,7 +196,7 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
11333 u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
11335 return DIV64_U64_ROUND_UP(ps * dsi->mode.clock * bpp,
11336 - dsi->lanes * 8ULL * NSEC_PER_SEC);
11337 + dsi->lanes * 8 * NSEC_PER_SEC);
11341 diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
11343 --- a/drivers/gpu/drm/bridge/sii902x.c
11345 @@ -24,10 +24,12 @@
11353 #include <sound/hdmi-codec.h>
11358 @@ -146,6 +148,12 @@
11371 @@ -168,6 +176,7 @@ struct sii902x {
11379 @@ -180,6 +189,14 @@ struct sii902x {
11394 @@ -270,13 +287,56 @@ static const struct drm_connector_funcs sii902x_connector_funcs = {
11399 + /* 4 - 1280x720@60Hz 16:9 */
11404 + /* 16 - 1920x1080@60Hz 16:9 */
11409 + /* 5 - 1920x1080i@60Hz 16:9 */
11415 + /* 31 - 1920x1080@50Hz 16:9 */
11420 + /* 19 - 1280x720@50Hz 16:9 */
11425 + /* 0x10 - 1024x768@60Hz */
11429 + /* 17 - 720x576@50Hz 4:3 */
11434 + /* 2 - 720x480@60Hz 4:3 */
11444 - u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
11447 - int num = 0, ret;
11451 mutex_lock(&sii902x->mutex);
11453 @@ -288,10 +348,24 @@ static int sii902x_get_modes(struct drm_connector *connector)
11462 + mode = drm_mode_duplicate(connector->dev, ptr);
11465 + mode->type = DRM_MODE_TYPE_PREFERRED;
11473 ret = drm_display_info_set_bus_formats(&connector->display_info,
11474 - &bus_format, 1);
11475 + &sii902x->bus_format, 1);
11479 @@ -311,7 +385,10 @@ static int sii902x_get_modes(struct drm_connector *connector)
11483 - /* TODO: check mode */
11484 + if (mode->hdisplay > 1920 || mode->vdisplay > 1080)
11486 + if (mode->clock > 165000)
11491 @@ -349,6 +426,106 @@ static void sii902x_bridge_enable(struct drm_bridge *bridge)
11492 mutex_unlock(&sii902x->mutex);
11517 + if (!sii902x_check_embedded_format(sii902x->bus_format))
11520 + switch (sii902x->bus_format) {
11525 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11532 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11534 + regmap_write(sii902x->regmap,
11536 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11539 + drm_display_mode_to_videomode(&sii902x->mode, &vm);
11548 + regmap_bulk_write(sii902x->regmap, SII902X_TPI_HBIT_TO_HSYNC, data, 8);
11550 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11552 + sii902x_update_bits_unlocked(sii902x->i2c,
11556 + regmap_update_bits(sii902x->regmap,
11566 + switch (sii902x->bus_format) {
11590 + regmap_write(sii902x->regmap, SII902X_TPI_AVI_IN_FORMAT, val);
11598 @@ -358,20 +535,56 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
11601 u16 pixel_clock_10kHz = adj->clock / 10;
11602 - int ret;
11605 + drm_mode_copy(&sii902x->mode, adj);
11609 - buf[2] = drm_mode_vrefresh(adj);
11610 - buf[3] = 0x00;
11611 - buf[4] = adj->hdisplay;
11612 - buf[5] = adj->hdisplay >> 8;
11613 - buf[6] = adj->vdisplay;
11614 - buf[7] = adj->vdisplay >> 8;
11617 + buf[4] = adj->crtc_htotal;
11618 + buf[5] = adj->crtc_htotal >> 8;
11619 + buf[6] = adj->crtc_vtotal;
11620 + buf[7] = adj->crtc_vtotal >> 8;
11623 - buf[9] = SII902X_TPI_AVI_INPUT_RANGE_AUTO |
11624 - SII902X_TPI_AVI_INPUT_COLORSPACE_RGB;
11625 + switch (sii902x->bus_format) {
11641 + switch (sii902x->bus_format) {
11662 mutex_lock(&sii902x->mutex);
11664 @@ -396,7 +609,7 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
11666 buf + HDMI_INFOFRAME_HEADER_SIZE - 1,
11668 -
11671 mutex_unlock(&sii902x->mutex);
11673 @@ -413,6 +626,7 @@ static int sii902x_bridge_attach(struct drm_bridge *bridge,
11674 return -EINVAL;
11677 + sii902x->connector.interlace_allowed = true;
11678 drm_connector_helper_add(&sii902x->connector,
11681 @@ -966,8 +1180,10 @@ static int sii902x_init(struct sii902x *sii902x)
11684 ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0);
11685 - if (ret)
11691 ret = regmap_bulk_read(sii902x->regmap, SII902X_REG_CHIPID(0),
11693 @@ -992,6 +1208,7 @@ static int sii902x_init(struct sii902x *sii902x)
11695 ret = devm_request_threaded_irq(dev, sii902x->i2c->irq, NULL,
11701 @@ -1024,6 +1241,7 @@ static int sii902x_probe(struct i2c_client *client,
11702 struct device *dev = &client->dev;
11707 ret = i2c_check_functionality(client->adapter,
11709 @@ -1049,6 +1267,37 @@ static int sii902x_probe(struct i2c_client *client,
11710 return PTR_ERR(sii902x->reset_gpio);
11713 + sii902x->enable_gpio = devm_gpiod_get_optional(dev, "enable",
11715 + if (IS_ERR(sii902x->enable_gpio)) {
11717 + PTR_ERR(sii902x->enable_gpio));
11718 + return PTR_ERR(sii902x->enable_gpio);
11719 + } else if (sii902x->enable_gpio) {
11720 + gpiod_direction_output(sii902x->enable_gpio, 1);
11724 + ret = of_property_read_u32(dev->of_node, "bus-format", &val);
11726 + sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
11730 + sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
11733 + sii902x->bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
11736 + sii902x->bus_format = MEDIA_BUS_FMT_YUV8_1X24;
11739 + sii902x->bus_format = val;
11744 mutex_init(&sii902x->mutex);
11746 sii902x->supplies[0].supply = "iovcc";
11747 @@ -1067,6 +1316,7 @@ static int sii902x_probe(struct i2c_client *client,
11752 regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
11753 sii902x->supplies);
11755 diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
11757 --- a/drivers/gpu/drm/bridge/synopsys/Makefile
11759 @@ -1,7 +1,8 @@
11760 # SPDX-License-Identifier: GPL-2.0-only
11761 -obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
11762 +obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o dw-hdmi-hdcp.o \
11763 + dw-hdmi-qp.o
11764 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
11765 -obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
11766 -obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
11767 +obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o dw-hdmi-qp-i2s-audio.o
11768 +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o dw-hdmi-qp-cec.o
11770 obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
11771 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdm…
11773 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
11774 +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
11775 @@ -12,6 +12,7 @@
11782 #include <media/cec-notifier.h>
11783 @@ -262,6 +263,8 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)
11784 if (IS_ERR(cec->adap))
11785 return PTR_ERR(cec->adap);
11787 + dw_hdmi_set_cec_adap(cec->hdmi, cec->adap);
11790 cec->adap->owner = THIS_MODULE;
11792 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
11794 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
11795 +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
11796 @@ -9,6 +9,8 @@
11801 +#include <linux/extcon-provider.h>
11805 @@ -18,6 +20,7 @@
11807 #include <linux/dma-mapping.h>
11811 #include <media/cec-notifier.h>
11813 @@ -36,6 +39,7 @@
11815 #include "dw-hdmi-audio.h"
11816 #include "dw-hdmi-cec.h"
11817 +#include "dw-hdmi-hdcp.h"
11818 #include "dw-hdmi.h"
11821 @@ -48,6 +52,11 @@
11833 @@ -62,6 +71,61 @@ enum hdmi_datamap {
11840 + * slow so we pre-compute values we expect to see.
11895 @@ -98,12 +162,47 @@ static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
11900 + /* 4 - 1280x720@60Hz 16:9 */
11905 + /* 16 - 1920x1080@60Hz 16:9 */
11910 + /* 31 - 1920x1080@50Hz 16:9 */
11915 + /* 19 - 1280x720@50Hz 16:9 */
11920 + /* 17 - 720x576@50Hz 4:3 */
11925 + /* 2 - 720x480@60Hz 4:3 */
11943 @@ -112,8 +211,8 @@ struct hdmi_data_info {
11949 - unsigned int hdcp_enable;
11953 @@ -128,6 +227,9 @@ struct dw_hdmi_i2c {
11963 @@ -143,6 +245,8 @@ struct dw_hdmi_phy_data {
11972 @@ -156,8 +260,10 @@ struct dw_hdmi {
11983 @@ -174,6 +280,13 @@ struct dw_hdmi {
11997 @@ -190,10 +303,14 @@ struct dw_hdmi {
12012 @@ -202,10 +319,12 @@ struct dw_hdmi {
12025 @@ -263,6 +382,124 @@ static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
12033 + sink_hdmi = hdmi->sink_is_hdmi;
12035 + if (hdmi->force_output == 1)
12036 + hdmi->sink_is_hdmi = true;
12037 + else if (hdmi->force_output == 2)
12038 + hdmi->sink_is_hdmi = false;
12040 + hdmi->sink_is_hdmi = hdmi->support_hdmi;
12042 + if (sink_hdmi != hdmi->sink_is_hdmi)
12051 + enum drm_connector_status status = hdmi->hpd_state ?
12055 + mutex_lock(&hdmi->mutex);
12057 + hdmi->rxsense = false;
12059 + hdmi->rxsense = true;
12060 + mutex_unlock(&hdmi->mutex);
12062 + if (hdmi->bridge.dev) {
12065 + change = drm_helper_hpd_irq_event(hdmi->bridge.dev);
12066 + if (change && hdmi->cec_adap &&
12067 + hdmi->cec_adap->devnode.registered)
12068 + cec_queue_pin_hpd_event(hdmi->cec_adap,
12069 + hdmi->hpd_state,
12071 + drm_bridge_hpd_notify(&hdmi->bridge, status);
12085 + dev_dbg(hdmi->dev, "dw hdmi plug in\n");
12087 + hdmi->hpd_state = true;
12089 + dev_dbg(hdmi->dev, "dw hdmi plug out\n");
12091 + hdmi->hpd_state = false;
12093 + mod_delayed_work(hdmi->workqueue, &hdmi->work, msecs_to_jiffies(msecs));
12100 + hdmi->workqueue = create_workqueue("hpd_queue");
12101 + INIT_DELAYED_WORK(&hdmi->work, repo_hpd_event);
12110 + /* Standard-mode */
12111 + if (hdmi->i2c->scl_high_ns < 4000)
12114 + high_ns = hdmi->i2c->scl_high_ns;
12116 + if (hdmi->i2c->scl_low_ns < 4700)
12119 + low_ns = hdmi->i2c->scl_low_ns;
12122 + clk_rate_khz = DIV_ROUND_UP(clk_get_rate(hdmi->isfr_clk), 1000);
12150 @@ -276,7 +513,8 @@ static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
12154 - hdmi_writeb(hdmi, 0x00, HDMI_I2CM_DIV);
12160 @@ -290,6 +528,11 @@ static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
12172 @@ -461,6 +704,8 @@ static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
12181 @@ -570,60 +815,117 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
12185 -static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
12190 - unsigned int n = (128 * freq) / 1000;
12191 - unsigned int mult = 1;
12192 + const struct dw_hdmi_plat_data *plat_data = hdmi->plat_data;
12196 + if (plat_data->tmds_n_table) {
12197 + for (i = 0; plat_data->tmds_n_table[i].tmds != 0; i++) {
12198 + if (pixel_clk == plat_data->tmds_n_table[i].tmds) {
12199 + tmds_n = &plat_data->tmds_n_table[i];
12205 - while (freq > 48000) {
12206 - mult *= 2;
12207 - freq /= 2;
12218 + return -ENOENT;
12222 - if (pixel_clk == 25175000)
12223 - n = 4576;
12224 - else if (pixel_clk == 27027000)
12225 - n = 4096;
12226 - else if (pixel_clk == 74176000 || pixel_clk == 148352000)
12227 - n = 11648;
12228 - else
12229 - n = 4096;
12230 - n *= mult;
12231 - break;
12232 -
12233 + return tmds_n->n_32k;
12235 - if (pixel_clk == 25175000)
12236 - n = 7007;
12237 - else if (pixel_clk == 74176000)
12238 - n = 17836;
12239 - else if (pixel_clk == 148352000)
12240 - n = 8918;
12241 - else
12242 - n = 6272;
12243 - n *= mult;
12244 - break;
12245 -
12248 + return (freq / 44100) * tmds_n->n_44k1;
12250 - if (pixel_clk == 25175000)
12251 - n = 6864;
12252 - else if (pixel_clk == 27027000)
12253 - n = 6144;
12254 - else if (pixel_clk == 74176000)
12255 - n = 11648;
12256 - else if (pixel_clk == 148352000)
12257 - n = 5824;
12258 - else
12259 - n = 6144;
12260 - n *= mult;
12261 - break;
12262 -
12265 + return (freq / 48000) * tmds_n->n_48k;
12267 - break;
12268 + return -ENOENT;
12283 + diff = final - (u64)cts * (128 * freq);
12308 + abs(n - ideal_n) < best_n_distance)) {
12311 + best_n_distance = abs(best_n - ideal_n);
12318 + if ((best_diff == 0) && (abs(n - ideal_n) > best_n_distance))
12322 - return n;
12335 + dev_warn(hdmi->dev, "Rate %lu missing; compute N dynamically\n",
12342 @@ -654,7 +956,7 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
12346 - n = hdmi_compute_n(sample_rate, pixel_clk);
12351 @@ -1005,6 +1307,15 @@ static bool is_csc_needed(struct dw_hdmi *hdmi)
12357 + if (hdmi->hdmi_data.quant_range == HDMI_QUANTIZATION_RANGE_LIMITED ||
12358 + (!hdmi->hdmi_data.quant_range && hdmi->hdmi_data.rgb_limited_range))
12367 @@ -1027,7 +1338,7 @@ static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
12371 - hdmi->hdmi_data.rgb_limited_range) {
12376 @@ -1059,7 +1370,7 @@ static void hdmi_video_csc(struct dw_hdmi *hdmi)
12380 - decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
12383 switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) {
12385 @@ -1106,7 +1417,7 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
12387 hdmi->hdmi_data.enc_out_bus_format)) {
12389 - color_depth = 4;
12394 @@ -1144,18 +1455,15 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
12398 - val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
12399 - HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
12400 - ((hdmi_data->pix_repet_factor <<
12401 - HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
12402 - HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
12411 - if (hdmi_data->pix_repet_factor > 1) {
12412 + if (hdmi_data->pix_repet_factor > 0) {
12416 @@ -1167,8 +1475,13 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
12420 - hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
12421 - HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
12422 + if ((color_depth == 5 && hdmi->previous_mode.htotal % 4) ||
12423 + (color_depth == 6 && hdmi->previous_mode.htotal % 2))
12432 @@ -1269,6 +1582,23 @@ static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
12455 * - The Source shall suspend transmission of the TMDS clock and data
12456 @@ -1446,6 +1776,13 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12457 const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg;
12458 const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
12459 const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
12460 + unsigned int tmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
12462 + hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format);
12464 + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) &&
12465 + pdata->mpll_cfg_420)
12466 + mpll_config = pdata->mpll_cfg_420;
12470 @@ -1455,11 +1792,11 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12473 for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++)
12474 - if (mpixelclock <= curr_ctrl->mpixelclock)
12475 + if (tmdsclock <= curr_ctrl->mpixelclock)
12478 for (; phy_config->mpixelclock != ~0UL; phy_config++)
12479 - if (mpixelclock <= phy_config->mpixelclock)
12480 + if (tmdsclock <= phy_config->mpixelclock)
12483 if (mpll_config->mpixelclock == ~0UL ||
12484 @@ -1467,11 +1804,18 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12485 phy_config->mpixelclock == ~0UL)
12486 return -EINVAL;
12488 - dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce,
12489 + if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
12490 + depth = fls(depth - 8);
12494 + depth--;
12496 + dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].cpce,
12498 - dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
12499 + dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].gmp,
12501 - dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
12502 + dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[depth],
12506 @@ -1484,10 +1828,6 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12507 dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
12510 - /* Override and disable clock termination. */
12511 - dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
12512 - HDMI_3D_TX_PHY_CKCALCTRL);
12513 -
12517 @@ -1589,14 +1929,16 @@ void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
12521 - /* Enable cable hot plug irq. */
12522 - hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
12523 + if (!hdmi->next_bridge) {
12525 + hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
12527 - /* Clear and unmute interrupts. */
12528 - hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
12529 - HDMI_IH_PHY_STAT0);
12530 - hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
12531 - HDMI_IH_MUTE_PHY_STAT0);
12541 @@ -1612,23 +1954,36 @@ static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
12542 * HDMI TX Setup
12545 -static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
12549 - u8 de;
12550 -
12551 - if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
12552 - de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
12553 - else
12554 - de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
12555 -
12556 - /* disable rx detect */
12557 - hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE,
12558 - HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0);
12559 -
12560 - hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG);
12561 -
12562 - hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE,
12563 - HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
12564 + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
12568 + vsync_pol = mode->flags & DRM_MODE_FLAG_PVSYNC ?
12571 + hsync_pol = mode->flags & DRM_MODE_FLAG_PHSYNC ?
12574 + data_pol = vmode->mdataenablepolarity ?
12584 + hdmi_dvi = hdmi->sink_is_hdmi ? HDMI_A_HDCPCFG0_HDMIDVI_HDMI :
12589 + if (hdmi->hdcp && hdmi->hdcp->hdcp_start)
12590 + hdmi->hdcp->hdcp_start(hdmi->hdcp);
12594 @@ -1642,10 +1997,15 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi,
12597 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
12598 - drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode,
12599 - hdmi->hdmi_data.rgb_limited_range ?
12600 - HDMI_QUANTIZATION_RANGE_LIMITED :
12601 - HDMI_QUANTIZATION_RANGE_FULL);
12603 + if (!hdmi->hdmi_data.quant_range)
12605 + hdmi->hdmi_data.rgb_limited_range ?
12610 + hdmi->hdmi_data.quant_range);
12614 @@ -1680,6 +2040,14 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi,
12619 + if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_BT2020)
12629 @@ -1816,17 +2184,44 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi,
12632 const struct drm_connector_state *conn_state = connector->state;
12640 + if (hdmi->version < 0x211a) {
12645 if (!hdmi->plat_data->use_drm_infoframe)
12651 + if (!hdmi->connector.hdr_sink_metadata.hdmi_type1.eotf) {
12656 + if (!conn_state->hdr_output_metadata) {
12662 + conn_state->hdr_output_metadata->data;
12664 + if (!(hdmi->connector.hdr_sink_metadata.hdmi_type1.eotf &
12665 + BIT(hdr_metadata->hdmi_metadata_type1.eotf))) {
12667 + hdr_metadata->hdmi_metadata_type1.eotf);
12674 @@ -1846,51 +2241,66 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi,
12680 + hdr_metadata->hdmi_metadata_type1.eotf);
12683 -static void hdmi_av_composer(struct dw_hdmi *hdmi,
12684 - const struct drm_display_info *display,
12685 - const struct drm_display_mode *mode)
12689 - u8 inv_val, bytes;
12690 - const struct drm_hdmi_info *hdmi_info = &display->hdmi;
12691 - struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
12692 - int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
12693 - unsigned int vdisplay, hdisplay;
12694 -
12695 - vmode->mpixelclock = mode->clock * 1000;
12696 -
12697 - dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
12698 -
12699 - vmode->mtmdsclock = vmode->mpixelclock;
12702 + hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format);
12704 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) {
12705 - switch (hdmi_bus_fmt_color_depth(
12706 - hdmi->hdmi_data.enc_out_bus_format)) {
12709 - vmode->mtmdsclock = vmode->mpixelclock * 2;
12713 - vmode->mtmdsclock = vmode->mpixelclock * 3 / 2;
12717 - vmode->mtmdsclock = vmode->mpixelclock * 5 / 4;
12733 + const struct drm_hdmi_info *hdmi_info = &display->hdmi;
12734 + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
12738 + vmode->previous_pixelclock = vmode->mpixelclock;
12739 + vmode->mpixelclock = mode->crtc_clock * 1000;
12740 + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) ==
12742 + vmode->mpixelclock *= 2;
12743 + dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
12745 + vmode->previous_tmdsclock = vmode->mtmdsclock;
12746 + vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi, vmode->mpixelclock);
12747 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
12748 vmode->mtmdsclock /= 2;
12749 -
12750 dev_dbg(hdmi->dev, "final tmdsclock = %d\n", vmode->mtmdsclock);
12752 - /* Set up HDMI_FC_INVIDCONF */
12753 - inv_val = (hdmi->hdmi_data.hdcp_enable ||
12754 - (dw_hdmi_support_scdc(hdmi, display) &&
12755 - (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
12756 - hdmi_info->scdc.scrambling.low_rates)) ?
12757 - HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
12758 - HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
12766 inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
12768 @@ -1956,7 +2366,8 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
12771 if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
12772 - hdmi_info->scdc.scrambling.low_rates) {
12773 + (hdmi_info->scdc.scrambling.low_rates &&
12774 + hdmi->scramble_low_rates)) {
12778 @@ -1990,6 +2401,8 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
12780 drm_scdc_set_scrambling(hdmi->ddc, 0);
12787 @@ -2047,6 +2460,12 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
12788 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
12789 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
12792 + if (hdmi->hdmi_data.video_mode.mpixelrepetitioninput) {
12793 + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PREPCLK_DISABLE;
12794 + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
12799 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
12800 @@ -2122,6 +2541,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
12804 + void *data = hdmi->plat_data->phy_data;
12808 @@ -2133,48 +2553,91 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
12809 dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
12812 - if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
12813 - (hdmi->vic == 21) || (hdmi->vic == 22) ||
12814 - (hdmi->vic == 2) || (hdmi->vic == 3) ||
12815 - (hdmi->vic == 17) || (hdmi->vic == 18))
12816 + if (hdmi->plat_data->get_enc_out_encoding)
12817 + hdmi->hdmi_data.enc_out_encoding =
12818 + hdmi->plat_data->get_enc_out_encoding(data);
12819 + else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
12820 + (hdmi->vic == 21) || (hdmi->vic == 22) ||
12821 + (hdmi->vic == 2) || (hdmi->vic == 3) ||
12822 + (hdmi->vic == 17) || (hdmi->vic == 18))
12823 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
12825 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
12827 - hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
12828 - hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
12829 + if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
12830 + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
12831 + hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 1;
12833 + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
12834 + hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
12837 + if (hdmi->plat_data->get_input_bus_format)
12838 + hdmi->hdmi_data.enc_in_bus_format =
12839 + hdmi->plat_data->get_input_bus_format(data);
12840 + else if (hdmi->plat_data->input_bus_format)
12841 + hdmi->hdmi_data.enc_in_bus_format =
12842 + hdmi->plat_data->input_bus_format;
12844 + hdmi->hdmi_data.enc_in_bus_format =
12847 - if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
12848 - hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
12850 + if (hdmi->plat_data->get_output_bus_format)
12851 + hdmi->hdmi_data.enc_out_bus_format =
12852 + hdmi->plat_data->get_output_bus_format(data);
12854 + hdmi->hdmi_data.enc_out_bus_format =
12858 - if (hdmi->plat_data->input_bus_encoding)
12859 + if (hdmi->plat_data->get_enc_in_encoding)
12860 + hdmi->hdmi_data.enc_in_encoding =
12861 + hdmi->plat_data->get_enc_in_encoding(data);
12862 + else if (hdmi->plat_data->input_bus_encoding)
12863 hdmi->hdmi_data.enc_in_encoding =
12864 hdmi->plat_data->input_bus_encoding;
12866 hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
12868 - if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED)
12869 - hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
12871 + if (hdmi->plat_data->get_quant_range)
12872 + hdmi->hdmi_data.quant_range =
12873 + hdmi->plat_data->get_quant_range(data);
12875 hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi &&
12879 - hdmi->hdmi_data.pix_repet_factor = 0;
12880 - hdmi->hdmi_data.hdcp_enable = 0;
12881 + if (!hdmi->sink_is_hdmi)
12882 + hdmi->hdmi_data.quant_range = HDMI_QUANTIZATION_RANGE_FULL;
12885 + * According to the dw-hdmi specification 6.4.2
12890 + hdmi->hdmi_data.pix_repet_factor =
12891 + (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 1 : 0;
12892 hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
12895 hdmi_av_composer(hdmi, &connector->display_info, mode);
12898 - ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
12899 - &connector->display_info,
12900 - &hdmi->previous_mode);
12901 - if (ret)
12902 - return ret;
12903 - hdmi->phy.enabled = true;
12904 + if (!hdmi->phy.enabled ||
12905 + hdmi->hdmi_data.video_mode.previous_pixelclock !=
12906 + hdmi->hdmi_data.video_mode.mpixelclock ||
12907 + hdmi->hdmi_data.video_mode.previous_tmdsclock !=
12908 + hdmi->hdmi_data.video_mode.mtmdsclock) {
12909 + ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
12910 + &connector->display_info,
12911 + &hdmi->previous_mode);
12914 + hdmi->phy.enabled = true;
12919 @@ -2202,7 +2665,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
12923 - hdmi_tx_hdcp_config(hdmi);
12928 @@ -2278,6 +2741,8 @@ static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
12929 hdmi->phy.enabled = false;
12932 + if (hdmi->hdcp && hdmi->hdcp->hdcp_stop)
12933 + hdmi->hdcp->hdcp_stop(hdmi->hdcp);
12934 hdmi->bridge_is_on = false;
12937 @@ -2295,6 +2760,10 @@ static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
12941 + if (hdmi->initialized) {
12942 + hdmi->initialized = false;
12943 + hdmi->disabled = true;
12945 if (hdmi->bridge_is_on)
12948 @@ -2327,8 +2796,15 @@ static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
12952 - result = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
12953 + if (!hdmi->force_logo) {
12954 + mutex_lock(&hdmi->mutex);
12955 + hdmi->force = DRM_FORCE_UNSPECIFIED;
12958 + mutex_unlock(&hdmi->mutex);
12961 + result = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
12962 mutex_lock(&hdmi->mutex);
12963 if (result != hdmi->last_connector_result) {
12964 dev_dbg(hdmi->dev, "read_hpd result: %d", result);
12965 @@ -2338,6 +2814,11 @@ static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
12967 mutex_unlock(&hdmi->mutex);
12970 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, true);
12972 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false);
12977 @@ -2358,7 +2839,7 @@ static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi,
12978 dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
12979 edid->width_cm, edid->height_cm);
12981 - hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
12982 + hdmi->support_hdmi = drm_detect_hdmi_monitor(edid);
12983 hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
12986 @@ -2376,21 +2857,105 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
12993 + struct drm_device *dev = connector->dev;
12996 + void *data = hdmi->plat_data->phy_data;
12998 + &connector->hdr_sink_metadata.hdmi_type1;
13004 + if (hdmi->plat_data->get_hdr_property)
13005 + property = hdmi->plat_data->get_hdr_property(data);
13007 + return -EINVAL;
13009 + if (hdmi->plat_data->get_hdr_blob)
13010 + blob = hdmi->plat_data->get_hdr_blob(data);
13012 + return -EINVAL;
13015 + &connector->base, property);
13024 + &connector->hdr_sink_metadata.hdmi_type1;
13026 - int ret;
13028 + struct drm_display_info *info = &connector->display_info;
13033 - if (!edid)
13034 - return 0;
13036 + dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
13037 + edid->width_cm, edid->height_cm);
13039 + cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
13041 + if (hdmi->plat_data->get_color_changed)
13042 + hdmi->plat_data->get_yuv422_format(connector, edid);
13046 + hdmi->support_hdmi = true;
13047 + hdmi->sink_has_audio = true;
13052 + mode = drm_mode_duplicate(connector->dev, ptr);
13055 + mode->type = DRM_MODE_TYPE_PREFERRED;
13056 + mode->picture_aspect_ratio =
13063 + info->edid_hdmi_dc_modes = 0;
13064 + info->hdmi.y420_dc_modes = 0;
13065 + info->color_formats = 0;
13067 + dev_info(hdmi->dev, "failed to get edid\n");
13080 + return hdmi->bridge.encoder;
13083 - drm_connector_update_edid_property(connector, edid);
13084 - cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
13085 - ret = drm_add_edid_modes(connector, edid);
13086 - kfree(edid);
13091 + void *data = hdmi->plat_data->phy_data;
13094 + if (hdmi->plat_data->get_color_changed)
13095 + ret = hdmi->plat_data->get_color_changed(data);
13099 @@ -2419,11 +2984,54 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
13101 struct drm_crtc *crtc = new_state->crtc;
13106 + void *data = hdmi->plat_data->phy_data;
13107 + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
13108 + unsigned int in_bus_format = hdmi->hdmi_data.enc_in_bus_format;
13109 + unsigned int out_bus_format = hdmi->hdmi_data.enc_out_bus_format;
13115 - if (!hdr_metadata_equal(old_state, new_state)) {
13120 + if (!vmode->mpixelclock) {
13122 + if (hdmi->plat_data->get_enc_in_encoding)
13123 + hdmi->hdmi_data.enc_in_encoding =
13124 + hdmi->plat_data->get_enc_in_encoding(data);
13125 + if (hdmi->plat_data->get_enc_out_encoding)
13126 + hdmi->hdmi_data.enc_out_encoding =
13127 + hdmi->plat_data->get_enc_out_encoding(data);
13128 + if (hdmi->plat_data->get_input_bus_format)
13129 + hdmi->hdmi_data.enc_in_bus_format =
13130 + hdmi->plat_data->get_input_bus_format(data);
13131 + if (hdmi->plat_data->get_output_bus_format)
13132 + hdmi->hdmi_data.enc_out_bus_format =
13133 + hdmi->plat_data->get_output_bus_format(data);
13135 + mode = &crtc_state->mode;
13136 + memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
13137 + vmode->mpixelclock = mode->crtc_clock * 1000;
13138 + vmode->previous_pixelclock = mode->clock;
13139 + vmode->previous_tmdsclock = mode->clock;
13140 + vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi,
13141 + vmode->mpixelclock);
13142 + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
13143 + vmode->mtmdsclock /= 2;
13145 + if (in_bus_format != hdmi->hdmi_data.enc_in_bus_format ||
13146 + out_bus_format != hdmi->hdmi_data.enc_out_bus_format)
13155 @@ -2434,12 +3042,105 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
13168 + hdmi->plat_data->property_ops;
13170 + if (ops && ops->set_property)
13171 + return ops->set_property(connector, state, property,
13172 + val, hdmi->plat_data->phy_data);
13174 + return -EINVAL;
13186 + hdmi->plat_data->property_ops;
13188 + if (ops && ops->get_property)
13189 + return ops->get_property(connector, state, property,
13190 + val, hdmi->plat_data->phy_data);
13192 + return -EINVAL;
13205 + if (!hdmi->bridge_is_on)
13209 + dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
13216 + hdmi->force_output = val;
13221 + if (!hdmi->bridge_is_on)
13225 + dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
13232 + return hdmi->sink_is_hdmi;
13238 + return hdmi->support_hdmi;
13247 mutex_lock(&hdmi->mutex);
13249 + if (hdmi->force != connector->force) {
13250 + if (!hdmi->disabled && connector->force == DRM_FORCE_OFF)
13251 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI,
13253 + else if (hdmi->disabled && connector->force == DRM_FORCE_ON)
13254 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI,
13258 hdmi->force = connector->force;
13261 @@ -2452,15 +3153,98 @@ static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
13283 + hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
13285 + hdmi->plat_data->property_ops;
13323 + dev_err(hdmi->dev, "unexpected mapping: 0x%x\n",
13327 + hdmi->hdmi_data.enc_in_bus_format = color;
13328 + hdmi->hdmi_data.enc_out_bus_format = color;
13334 + hdmi->hdmi_data.enc_in_bus_format =
13337 + hdmi->hdmi_data.enc_in_bus_format =
13341 + if (ops && ops->attach_properties)
13342 + return ops->attach_properties(&hdmi->connector,
13343 + color, hdmi->version,
13344 + hdmi->plat_data->phy_data);
13350 + hdmi->plat_data->property_ops;
13352 + if (ops && ops->destroy_properties)
13353 + return ops->destroy_properties(&hdmi->connector,
13354 + hdmi->plat_data->phy_data);
13359 struct drm_connector *connector = &hdmi->connector;
13360 @@ -2497,6 +3281,8 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi)
13362 drm_connector_attach_encoder(connector, hdmi->bridge.encoder);
13368 notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
13369 @@ -2771,16 +3557,36 @@ static int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
13372 struct dw_hdmi *hdmi = bridge->driver_private;
13373 + void *data = hdmi->plat_data->phy_data;
13375 - hdmi->hdmi_data.enc_out_bus_format =
13376 - bridge_state->output_bus_cfg.format;
13377 + if (bridge_state->output_bus_cfg.format == MEDIA_BUS_FMT_FIXED) {
13378 + if (hdmi->plat_data->get_output_bus_format)
13379 + hdmi->hdmi_data.enc_out_bus_format =
13380 + hdmi->plat_data->get_output_bus_format(data);
13382 + hdmi->hdmi_data.enc_out_bus_format =
13385 + if (hdmi->plat_data->get_input_bus_format)
13386 + hdmi->hdmi_data.enc_in_bus_format =
13387 + hdmi->plat_data->get_input_bus_format(data);
13388 + else if (hdmi->plat_data->input_bus_format)
13389 + hdmi->hdmi_data.enc_in_bus_format =
13390 + hdmi->plat_data->input_bus_format;
13392 + hdmi->hdmi_data.enc_in_bus_format =
13395 + hdmi->hdmi_data.enc_out_bus_format =
13396 + bridge_state->output_bus_cfg.format;
13398 - hdmi->hdmi_data.enc_in_bus_format =
13399 - bridge_state->input_bus_cfg.format;
13400 + hdmi->hdmi_data.enc_in_bus_format =
13401 + bridge_state->input_bus_cfg.format;
13403 - dev_dbg(hdmi->dev, "input format 0x%04x, output format 0x%04x\n",
13404 - bridge_state->input_bus_cfg.format,
13405 - bridge_state->output_bus_cfg.format);
13406 + dev_dbg(hdmi->dev, "input format 0x%04x, output format 0x%04x\n",
13407 + bridge_state->input_bus_cfg.format,
13408 + bridge_state->output_bus_cfg.format);
13413 @@ -2789,10 +3595,22 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
13416 struct dw_hdmi *hdmi = bridge->driver_private;
13422 + if (hdmi->next_bridge) {
13423 + hdmi->next_bridge->encoder = bridge->encoder;
13424 + ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge, bridge, flags);
13426 + DRM_ERROR("Failed to attach bridge with dw-hdmi\n");
13436 @@ -2812,17 +3630,16 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
13439 struct dw_hdmi *hdmi = bridge->driver_private;
13440 + struct drm_connector *connector = &hdmi->connector;
13441 const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
13444 - /* We don't support double-clocked modes */
13445 - if (mode->flags & DRM_MODE_FLAG_DBLCLK)
13446 - return MODE_BAD;
13447 + if (hdmi->next_bridge)
13450 if (pdata->mode_valid)
13451 - mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info,
13452 - mode);
13453 -
13454 + mode_status = pdata->mode_valid(connector, pdata->priv_data,
13459 @@ -2903,6 +3720,12 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
13465 + hdmi->cec_adap = adap;
13469 /* -----------------------------------------------------------------------------
13472 @@ -2928,7 +3751,7 @@ static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
13476 - u8 intr_stat;
13480 if (hdmi->i2c)
13481 @@ -2940,6 +3763,13 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
13487 + dev_dbg(hdmi->dev, "HDCP irq %#x\n", hdcp_stat);
13495 @@ -2947,7 +3777,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
13497 mutex_lock(&hdmi->mutex);
13499 - if (!hdmi->force) {
13500 + if (!hdmi->force && !hdmi->force_logo) {
13504 @@ -2974,7 +3804,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
13508 - u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat;
13513 @@ -3015,25 +3845,21 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
13517 - if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
13518 - enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
13519 - ? connector_status_connected
13520 - : connector_status_disconnected;
13521 -
13522 - dev_dbg(hdmi->dev, "EVENT=%s\n",
13523 - status == connector_status_connected ?
13524 - "plugin" : "plugout");
13525 -
13526 - if (hdmi->bridge.dev) {
13527 - drm_helper_hpd_irq_event(hdmi->bridge.dev);
13528 - drm_bridge_hpd_notify(&hdmi->bridge, status);
13529 - }
13530 - }
13534 - hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
13535 - HDMI_IH_MUTE_PHY_STAT0);
13536 -
13537 + if (!hdmi->next_bridge)
13544 + if (hdmi->hdcp)
13545 + hdmi->hdcp->hdcp_isr(hdmi->hdcp, hdcp_stat);
13552 @@ -3167,12 +3993,363 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
13556 - dw_hdmi_i2c_init(hdmi);
13557 + if (hdmi->i2c)
13560 if (hdmi->phy.ops->setup_hpd)
13561 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
13566 + struct dw_hdmi *hdmi = s->private;
13570 + if (!hdmi->phy.enabled) {
13575 + if (hdmi->sink_is_hdmi)
13579 + if (hdmi->hdmi_data.video_mode.mtmdsclock > 340000000)
13580 + val = hdmi->hdmi_data.video_mode.mtmdsclock / 4;
13582 + val = hdmi->hdmi_data.video_mode.mtmdsclock;
13584 + hdmi->hdmi_data.video_mode.mpixelclock, val);
13586 + if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format))
13588 + else if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
13590 + else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
13592 + else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
13596 + val = hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format);
13599 + switch (hdmi->hdmi_data.enc_out_encoding) {
13616 + if (hdmi->version < 0x211a) {
13686 + return single_open(file, dw_hdmi_status_show, inode->i_private);
13726 + struct dw_hdmi *hdmi = s->private;
13732 + seq_puts(s, "\n---------------------------------------------------");
13738 + if ((j - hdmi_reg_table[i].reg_base) % 16 == 0)
13743 + seq_puts(s, "\n---------------------------------------------------\n");
13750 + return single_open(file, dw_hdmi_ctrl_show, inode->i_private);
13758 + ((struct seq_file *)file->private_data)->private;
13763 + return -EFAULT;
13764 + if (sscanf(kbuf, "%x%x", ®, &val) == -1)
13765 + return -EFAULT;
13767 + dev_err(hdmi->dev, "it is no a hdmi register\n");
13770 + dev_info(hdmi->dev, "/**********hdmi register config******/");
13771 + dev_info(hdmi->dev, "\n reg=%x val=%x\n", reg, val);
13787 + struct dw_hdmi *hdmi = s->private;
13799 + return single_open(file, dw_hdmi_phy_show, inode->i_private);
13807 + ((struct seq_file *)file->private_data)->private;
13812 + return -EFAULT;
13813 + if (sscanf(kbuf, "%x%x", ®, &val) == -1)
13814 + return -EFAULT;
13816 + dev_err(hdmi->dev, "it is not a hdmi phy register\n");
13819 + dev_info(hdmi->dev, "/*******hdmi phy register config******/");
13820 + dev_info(hdmi->dev, "\n reg=%x val=%x\n", reg, val);
13836 + hdmi->debugfs_dir = debugfs_create_dir("dw-hdmi", NULL);
13837 + if (IS_ERR(hdmi->debugfs_dir)) {
13841 + debugfs_create_file("status", 0400, hdmi->debugfs_dir,
13843 + debugfs_create_file("ctrl", 0400, hdmi->debugfs_dir,
13845 + debugfs_create_file("phy", 0400, hdmi->debugfs_dir,
13856 + .regs = hdmi->regs,
13871 + hdmi->hdcp_dev = platform_device_register_full(&hdcp_device_info);
13872 + if (IS_ERR(hdmi->hdcp_dev))
13875 + hdmi->hdcp = hdmi->hdcp_dev->dev.platform_data;
13884 + dss = of_find_node_by_name(NULL, "display-subsystem");
13886 + dev_err(hdmi->dev, "can't find display-subsystem\n");
13887 + return -ENODEV;
13892 + dev_err(hdmi->dev, "can't find route\n");
13894 + return -ENODEV;
13898 + route_hdmi = of_find_node_by_name(route, "route-hdmi");
13900 + dev_err(hdmi->dev, "can't find route-hdmi\n");
13902 + return -ENODEV;
13906 + hdmi->force_logo =
13907 + of_property_read_bool(route_hdmi, "force-output");
13914 /* -----------------------------------------------------------------------------
13917 @@ -3181,6 +4358,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13919 struct device *dev = &pdev->dev;
13920 struct device_node *np = dev->of_node;
13925 @@ -3193,11 +4371,13 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13933 return ERR_PTR(-ENOMEM);
13935 + hdmi->connector.stereo_allowed = 1;
13936 hdmi->plat_data = plat_data;
13937 hdmi->dev = dev;
13938 hdmi->sample_rate = 48000;
13939 @@ -3328,7 +4508,24 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13941 hdmi->phy.name);
13943 - dw_hdmi_init_hw(hdmi);
13948 + hdmi->initialized = false;
13951 + hdmi_readb(hdmi, HDMI_FC_EXCTRLDUR)) || hdmi->force_logo) {
13952 + hdmi->mc_clkdis = hdmi_readb(hdmi, HDMI_MC_CLKDIS);
13953 + hdmi->disabled = false;
13954 + hdmi->bridge_is_on = true;
13955 + hdmi->phy.enabled = true;
13956 + hdmi->initialized = true;
13958 + hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
13965 @@ -3336,6 +4533,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13969 + hdmi->irq = irq;
13973 @@ -3371,8 +4569,20 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13974 hdmi->ddc = dw_hdmi_i2c_adapter(hdmi);
13975 if (IS_ERR(hdmi->ddc))
13976 hdmi->ddc = NULL;
13981 + if (of_property_read_u32(np, "ddc-i2c-scl-high-time-ns",
13982 + &hdmi->i2c->scl_high_ns))
13983 + hdmi->i2c->scl_high_ns = 4708;
13984 + if (of_property_read_u32(np, "ddc-i2c-scl-low-time-ns",
13985 + &hdmi->i2c->scl_low_ns))
13986 + hdmi->i2c->scl_low_ns = 4916;
13991 hdmi->bridge.driver_private = hdmi;
13992 hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
13993 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
13994 @@ -3381,6 +4591,30 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13995 hdmi->bridge.of_node = pdev->dev.of_node;
13998 + endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node, 1, -1);
14006 + ret = -ENODEV;
14010 + hdmi->next_bridge = of_drm_find_bridge(remote);
14012 + if (!hdmi->next_bridge) {
14013 + dev_err(hdmi->dev, "can't find next bridge\n");
14014 + ret = -EPROBE_DEFER;
14018 + hdmi->sink_is_hdmi = true;
14019 + hdmi->sink_has_audio = true;
14025 @@ -3434,8 +4668,40 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
14026 hdmi->cec = platform_device_register_full(&pdevinfo);
14029 + hdmi->extcon = devm_extcon_dev_allocate(hdmi->dev, dw_hdmi_cable);
14030 + if (IS_ERR(hdmi->extcon)) {
14031 + ret = PTR_ERR(hdmi->extcon);
14032 + dev_err(hdmi->dev, "allocate extcon failed: %d\n", ret);
14036 + ret = devm_extcon_dev_register(hdmi->dev, hdmi->extcon);
14038 + dev_err(hdmi->dev, "failed to register extcon: %d\n",
14043 + ret = extcon_set_property_capability(hdmi->extcon, EXTCON_DISP_HDMI,
14046 + dev_err(hdmi->dev,
14052 drm_bridge_add(&hdmi->bridge);
14056 + if (of_property_read_bool(np, "scramble-low-rates"))
14057 + hdmi->scramble_low_rates = true;
14059 + if (of_property_read_bool(np, "hdcp1x-enable"))
14066 @@ -3445,7 +4711,10 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
14068 clk_disable_unprepare(hdmi->isfr_clk);
14070 - i2c_put_adapter(hdmi->ddc);
14071 + if (hdmi->i2c)
14072 + i2c_del_adapter(&hdmi->i2c->adap);
14074 + i2c_put_adapter(hdmi->ddc);
14078 @@ -3453,16 +4722,35 @@ EXPORT_SYMBOL_GPL(dw_hdmi_probe);
14082 + if (hdmi->irq)
14083 + disable_irq(hdmi->irq);
14085 + cancel_delayed_work(&hdmi->work);
14086 + flush_workqueue(hdmi->workqueue);
14087 + destroy_workqueue(hdmi->workqueue);
14089 + debugfs_remove_recursive(hdmi->debugfs_dir);
14091 drm_bridge_remove(&hdmi->bridge);
14093 if (hdmi->audio && !IS_ERR(hdmi->audio))
14094 platform_device_unregister(hdmi->audio);
14095 + if (hdmi->hdcp_dev && !IS_ERR(hdmi->hdcp_dev))
14096 + platform_device_unregister(hdmi->hdcp_dev);
14097 if (!IS_ERR(hdmi->cec))
14098 platform_device_unregister(hdmi->cec);
14103 + if (!hdmi->next_bridge) {
14105 + hdmi->connector.funcs->destroy(&hdmi->connector);
14108 + if (hdmi->bridge.encoder)
14109 + hdmi->bridge.encoder->funcs->destroy(hdmi->bridge.encoder);
14111 clk_disable_unprepare(hdmi->iahb_clk);
14112 clk_disable_unprepare(hdmi->isfr_clk);
14113 if (hdmi->cec_clk)
14114 @@ -3480,7 +4768,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
14118 - const struct dw_hdmi_plat_data *plat_data)
14123 @@ -3496,6 +4784,9 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
14127 + if (!hdmi->next_bridge)
14128 + plat_data->connector = &hdmi->connector;
14133 @@ -3506,9 +4797,87 @@ void dw_hdmi_unbind(struct dw_hdmi *hdmi)
14151 + if (!hdmi->next_bridge) {
14154 + hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
14167 + mutex_lock(&hdmi->mutex);
14175 + if (!hdmi->disabled) {
14176 + hdmi->disabled = true;
14180 + mutex_unlock(&hdmi->mutex);
14182 + if (hdmi->irq)
14183 + disable_irq(hdmi->irq);
14184 + cancel_delayed_work(&hdmi->work);
14185 + flush_workqueue(hdmi->workqueue);
14186 + pinctrl_pm_select_sleep_state(hdmi->dev);
14192 - dw_hdmi_init_hw(hdmi);
14196 + pinctrl_pm_select_default_state(hdmi->dev);
14197 + mutex_lock(&hdmi->mutex);
14199 + if (hdmi->i2c)
14201 + if (hdmi->irq)
14202 + enable_irq(hdmi->irq);
14205 + * HDMI plug in -> system sleep -> HDMI plug out -> system wake up.
14206 + * At this time, cat /sys/class/drm/card 0-HDMI-A-1/status is connected.
14210 + if (hdmi->connector.status == connector_status_connected) {
14211 + if (hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data) ==
14213 + hdmi->hpd_state = false;
14214 + mod_delayed_work(hdmi->workqueue, &hdmi->work,
14218 + mutex_unlock(&hdmi->mutex);
14222 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
14224 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
14225 +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
14226 @@ -509,6 +509,51 @@
14275 /* I2C Master Registers (E-DDC) */
14278 @@ -529,6 +574,7 @@
14286 @@ -842,6 +888,10 @@ enum {
14297 @@ -1085,6 +1135,11 @@ enum {
14309 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mip…
14311 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
14312 +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
14313 @@ -244,7 +244,7 @@ struct dw_mipi_dsi {
14317 - struct clk *pclk;
14322 @@ -316,15 +316,10 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
14323 const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
14326 + int max_data_lanes = dsi->plat_data->max_data_lanes;
14329 - if (device->lanes > dsi->plat_data->max_data_lanes) {
14330 - dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
14331 - device->lanes);
14332 - return -EINVAL;
14333 - }
14334 -
14335 - dsi->lanes = device->lanes;
14336 + dsi->lanes = (device->lanes > max_data_lanes) ? device->lanes / 2 : device->lanes;
14337 dsi->channel = device->channel;
14338 dsi->format = device->format;
14339 dsi->mode_flags = device->mode_flags;
14340 @@ -599,8 +594,14 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
14344 + const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
14346 + if (phy_ops->power_off)
14347 + phy_ops->power_off(dsi->plat_data->priv_data);
14351 + pm_runtime_put(dsi->dev);
14355 @@ -715,16 +716,16 @@ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
14359 - u32 frac, lbcc;
14362 lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8;
14364 - frac = lbcc % mode->clock;
14365 - lbcc = lbcc / mode->clock;
14366 - if (frac)
14367 - lbcc++;
14368 + if (mode->clock == 0) {
14373 - return lbcc;
14374 + return DIV_ROUND_CLOSEST_ULL(lbcc, mode->clock);
14378 @@ -837,13 +838,13 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
14379 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
14382 - DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
14385 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
14389 - DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
14394 @@ -857,7 +858,6 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
14398 - const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
14401 * Switch to command mode before panel-bridge post_disable &
14402 @@ -866,6 +866,8 @@ static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
14406 + if (dsi->slave)
14407 + dw_mipi_dsi_set_mode(dsi->slave, 0);
14410 * TODO Only way found to call panel-bridge post_disable &
14411 @@ -876,18 +878,10 @@ static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
14412 if (dsi->panel_bridge->funcs->post_disable)
14413 dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
14415 - if (phy_ops->power_off)
14416 - phy_ops->power_off(dsi->plat_data->priv_data);
14417 -
14418 - if (dsi->slave) {
14419 + if (dsi->slave)
14420 dw_mipi_dsi_disable(dsi->slave);
14421 - clk_disable_unprepare(dsi->slave->pclk);
14422 - pm_runtime_put(dsi->slave->dev);
14423 - }
14424 - dw_mipi_dsi_disable(dsi);
14426 - clk_disable_unprepare(dsi->pclk);
14427 - pm_runtime_put(dsi->dev);
14432 @@ -912,7 +906,11 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
14436 - clk_prepare_enable(dsi->pclk);
14437 + if (dsi->apb_rst) {
14438 + reset_control_assert(dsi->apb_rst);
14440 + reset_control_deassert(dsi->apb_rst);
14443 ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi->mode_flags,
14444 lanes, dsi->format, &dsi->lane_mbps);
14445 @@ -939,15 +937,15 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
14449 + if (phy_ops->power_on)
14450 + phy_ops->power_on(dsi->plat_data->priv_data);
14456 /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */
14458 -
14459 - if (phy_ops->power_on)
14460 - phy_ops->power_on(dsi->plat_data->priv_data);
14464 @@ -959,16 +957,25 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
14466 if (dsi->slave)
14467 dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode);
14469 + DRM_DEV_INFO(dsi->dev, "final DSI-Link bandwidth: %u x %d Mbps\n",
14470 + dsi->lane_mbps, dsi->slave ? dsi->lanes * 2 : dsi->lanes);
14477 - /* Switch to video mode for panel-bridge enable & panel enable */
14478 - dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO);
14479 - if (dsi->slave)
14480 - dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO);
14481 + /* Switch to video/cmd mode for panel-bridge enable & panel enable */
14482 + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
14484 + if (dsi->slave)
14485 + dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO);
14488 + if (dsi->slave)
14489 + dw_mipi_dsi_set_mode(dsi->slave, 0);
14494 @@ -1103,7 +1110,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
14497 struct device *dev = &pdev->dev;
14498 - struct reset_control *apb_rst;
14502 @@ -1129,20 +1135,13 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
14503 dsi->base = plat_data->base;
14506 - dsi->pclk = devm_clk_get(dev, "pclk");
14507 - if (IS_ERR(dsi->pclk)) {
14508 - ret = PTR_ERR(dsi->pclk);
14509 - dev_err(dev, "Unable to get pclk: %d\n", ret);
14510 - return ERR_PTR(ret);
14511 - }
14512 -
14517 - apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
14518 - if (IS_ERR(apb_rst)) {
14519 - ret = PTR_ERR(apb_rst);
14520 + dsi->apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
14521 + if (IS_ERR(dsi->apb_rst)) {
14522 + ret = PTR_ERR(dsi->apb_rst);
14524 if (ret != -EPROBE_DEFER)
14526 @@ -1150,20 +1149,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
14530 - if (apb_rst) {
14531 - ret = clk_prepare_enable(dsi->pclk);
14532 - if (ret) {
14533 - dev_err(dev, "%s: Failed to enable pclk\n", __func__);
14534 - return ERR_PTR(ret);
14535 - }
14536 -
14537 - reset_control_assert(apb_rst);
14538 - usleep_range(10, 20);
14539 - reset_control_deassert(apb_rst);
14540 -
14541 - clk_disable_unprepare(dsi->pclk);
14542 - }
14543 -
14547 @@ -1246,6 +1231,12 @@ void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi)
14553 + return drm_panel_bridge_connector(dsi->panel_bridge);
14557 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
14560 diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
14562 --- a/drivers/gpu/drm/drm_atomic_helper.c
14564 @@ -296,12 +296,14 @@ update_connector_routing(struct drm_atomic_state *state,
14565 if (old_connector_state->crtc != new_connector_state->crtc) {
14566 if (old_connector_state->crtc) {
14567 crtc_state = drm_atomic_get_new_crtc_state(state, old_connector_state->crtc);
14568 - crtc_state->connectors_changed = true;
14569 + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
14570 + crtc_state->connectors_changed = true;
14573 if (new_connector_state->crtc) {
14574 crtc_state = drm_atomic_get_new_crtc_state(state, new_connector_state->crtc);
14575 - crtc_state->connectors_changed = true;
14576 + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
14577 + crtc_state->connectors_changed = true;
14581 @@ -386,7 +388,8 @@ update_connector_routing(struct drm_atomic_state *state,
14585 - crtc_state->connectors_changed = true;
14586 + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
14587 + crtc_state->connectors_changed = true;
14590 connector->base.id,
14591 @@ -3544,6 +3547,9 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
14592 replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
14593 replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
14594 replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
14596 + replaced |= drm_property_replace_blob(&crtc_state->cubic_lut, NULL);
14598 crtc_state->color_mgmt_changed |= replaced;
14601 diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
14603 --- a/drivers/gpu/drm/drm_atomic_state_helper.c
14605 @@ -141,6 +141,10 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
14606 drm_property_blob_get(state->ctm);
14607 if (state->gamma_lut)
14608 drm_property_blob_get(state->gamma_lut);
14610 + if (state->cubic_lut)
14611 + drm_property_blob_get(state->cubic_lut);
14613 state->mode_changed = false;
14614 state->active_changed = false;
14615 state->planes_changed = false;
14616 @@ -213,6 +217,9 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
14617 drm_property_blob_put(state->degamma_lut);
14618 drm_property_blob_put(state->ctm);
14619 drm_property_blob_put(state->gamma_lut);
14621 + drm_property_blob_put(state->cubic_lut);
14626 diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
14628 --- a/drivers/gpu/drm/drm_atomic_uapi.c
14630 @@ -459,6 +459,16 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
14632 state->color_mgmt_changed |= replaced;
14635 + } else if (property == config->cubic_lut_property) {
14637 + &state->cubic_lut,
14639 + -1, sizeof(struct drm_color_lut),
14641 + state->color_mgmt_changed |= replaced;
14644 } else if (property == config->prop_out_fence_ptr) {
14647 @@ -501,6 +511,10 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
14648 *val = (state->ctm) ? state->ctm->base.id : 0;
14649 else if (property == config->gamma_lut_property)
14650 *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
14652 + else if (property == config->cubic_lut_property)
14653 + *val = (state->cubic_lut) ? state->cubic_lut->base.id : 0;
14655 else if (property == config->prop_out_fence_ptr)
14657 else if (crtc->funcs->atomic_get_property)
14658 diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
14660 --- a/drivers/gpu/drm/drm_auth.c
14662 @@ -135,18 +135,16 @@ static void drm_set_master(struct drm_device *dev, struct drm_file *fpriv,
14666 - struct drm_master *new_master;
14668 lockdep_assert_held_once(&dev->master_mutex);
14670 WARN_ON(fpriv->is_master);
14671 old_master = fpriv->master;
14672 - new_master = drm_master_create(dev);
14673 - if (!new_master)
14674 + fpriv->master = drm_master_create(dev);
14675 + if (!fpriv->master) {
14676 + fpriv->master = old_master;
14677 return -ENOMEM;
14678 - spin_lock(&fpriv->master_lookup_lock);
14679 - fpriv->master = new_master;
14680 - spin_unlock(&fpriv->master_lookup_lock);
14683 fpriv->is_master = 1;
14684 fpriv->authenticated = 1;
14685 @@ -304,13 +302,10 @@ int drm_master_open(struct drm_file *file_priv)
14688 mutex_lock(&dev->master_mutex);
14689 - if (!dev->master) {
14690 + if (!dev->master)
14692 - } else {
14693 - spin_lock(&file_priv->master_lookup_lock);
14695 file_priv->master = drm_master_get(dev->master);
14696 - spin_unlock(&file_priv->master_lookup_lock);
14697 - }
14698 mutex_unlock(&dev->master_mutex);
14701 @@ -376,31 +371,6 @@ struct drm_master *drm_master_get(struct drm_master *master)
14705 -/**
14706 - * drm_file_get_master - reference &drm_file.master of @file_priv
14707 - * @file_priv: DRM file private
14708 - *
14709 - * Increments the reference count of @file_priv's &drm_file.master and returns
14710 - * the &drm_file.master. If @file_priv has no &drm_file.master, returns NULL.
14711 - *
14712 - * Master pointers returned from this function should be unreferenced using
14713 - * drm_master_put().
14714 - */
14715 -struct drm_master *drm_file_get_master(struct drm_file *file_priv)
14716 -{
14717 - struct drm_master *master = NULL;
14718 -
14719 - spin_lock(&file_priv->master_lookup_lock);
14720 - if (!file_priv->master)
14721 - goto unlock;
14722 - master = drm_master_get(file_priv->master);
14723 -
14724 -unlock:
14725 - spin_unlock(&file_priv->master_lookup_lock);
14726 - return master;
14727 -}
14728 -EXPORT_SYMBOL(drm_file_get_master);
14729 -
14733 diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
14735 --- a/drivers/gpu/drm/drm_color_mgmt.c
14737 @@ -33,7 +33,7 @@
14741 - * Color management or color space adjustments is supported through a set of 5
14746 @@ -60,7 +60,7 @@
14750 - * lookup through the gamma LUT. The data is interpreted as a struct
14755 @@ -68,13 +68,40 @@
14756 * boot-up state too. Drivers can access the blob for the color conversion
14765 + * as a 3D coordinate. The LUT is subsampled as 8-bit (or more) precision
14777 + * boot-up state too. Drivers can access this blob through
14784 + * largest size, and sub-sample smaller sized LUTs appropriately.
14788 - * after the transformation matrix to data sent to the connector. The
14789 - * data is interpreted as an array of &struct drm_color_lut elements.
14790 - * Hardware might choose not to use the full precision of the LUT elements
14791 - * nor use all the elements of the LUT (for example the hardware might
14792 - * choose to interpolate between LUT[0] and LUT[4]).
14800 * linear/pass-thru gamma table should be used. This is generally the
14801 diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
14803 --- a/drivers/gpu/drm/drm_crtc_internal.h
14805 @@ -276,7 +276,29 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
14835 diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
14837 --- a/drivers/gpu/drm/drm_debugfs.c
14839 @@ -91,7 +91,6 @@ static int drm_clients_info(struct seq_file *m, void *data)
14840 mutex_lock(&dev->filelist_mutex);
14841 list_for_each_entry_reverse(priv, &dev->filelist, lhead) {
14843 - bool is_current_master = drm_is_current_master(priv);
14845 rcu_read_lock(); /* locks pid_task()->comm */
14846 task = pid_task(priv->pid, PIDTYPE_PID);
14847 @@ -100,7 +99,7 @@ static int drm_clients_info(struct seq_file *m, void *data)
14848 task ? task->comm : "<unknown>",
14849 pid_vnr(priv->pid),
14850 priv->minor->index,
14851 - is_current_master ? 'y' : 'n',
14853 priv->authenticated ? 'y' : 'n',
14855 priv->magic);
14856 diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
14858 --- a/drivers/gpu/drm/drm_edid.c
14860 @@ -1835,20 +1835,11 @@ static void connector_bad_edid(struct drm_connector *connector,
14864 - u8 last_block;
14865 -
14866 - /*
14867 - * 0x7e in the EDID is the number of extension blocks. The EDID
14868 - * is 1 (base block) + num_ext_blocks big. That means we can think
14869 - * of 0x7e in the EDID of the _index_ of the last block in the
14870 - * combined chunk of memory.
14871 - */
14872 - last_block = edid[0x7e];
14876 - if (last_block < num_blocks)
14877 - connector->real_edid_checksum =
14878 - drm_edid_block_checksum(edid + last_block * EDID_LENGTH);
14879 + connector->real_edid_checksum =
14882 if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
14884 @@ -4860,6 +4851,43 @@ static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
14885 info->rgb_quant_range_selectable = true;
14928 @@ -4913,6 +4941,76 @@ static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
14937 + struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
14941 + drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
14942 + &hdmi->max_frl_rate_per_lane);
14943 + hdmi_dsc->v_1p2 = hf_vsdb[11] & DRM_EDID_DSC_1P2;
14945 + if (hdmi_dsc->v_1p2) {
14946 + hdmi_dsc->native_420 = hf_vsdb[11] & DRM_EDID_DSC_NATIVE_420;
14947 + hdmi_dsc->all_bpp = hf_vsdb[11] & DRM_EDID_DSC_ALL_BPP;
14950 + hdmi_dsc->bpc_supported = 16;
14952 + hdmi_dsc->bpc_supported = 12;
14954 + hdmi_dsc->bpc_supported = 10;
14956 + hdmi_dsc->bpc_supported = 0;
14959 + drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
14960 + &hdmi_dsc->max_frl_rate_per_lane);
14961 + hdmi_dsc->total_chunk_kbytes = hf_vsdb[13] & DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
14966 + hdmi_dsc->max_slices = 1;
14967 + hdmi_dsc->clk_per_slice = 340;
14970 + hdmi_dsc->max_slices = 2;
14971 + hdmi_dsc->clk_per_slice = 340;
14974 + hdmi_dsc->max_slices = 4;
14975 + hdmi_dsc->clk_per_slice = 340;
14978 + hdmi_dsc->max_slices = 8;
14979 + hdmi_dsc->clk_per_slice = 340;
14982 + hdmi_dsc->max_slices = 8;
14983 + hdmi_dsc->clk_per_slice = 400;
14986 + hdmi_dsc->max_slices = 12;
14987 + hdmi_dsc->clk_per_slice = 400;
14990 + hdmi_dsc->max_slices = 16;
14991 + hdmi_dsc->clk_per_slice = 400;
14995 + hdmi_dsc->max_slices = 0;
14996 + hdmi_dsc->clk_per_slice = 0;
15005 diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
15007 --- a/drivers/gpu/drm/drm_file.c
15009 @@ -177,7 +177,6 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
15010 init_waitqueue_head(&file->event_wait);
15011 file->event_space = 4096; /* set aside 4k for event buffer */
15013 - spin_lock_init(&file->master_lookup_lock);
15014 mutex_init(&file->event_read_lock);
15017 @@ -776,20 +775,19 @@ void drm_event_cancel_free(struct drm_device *dev,
15021 - * drm_send_event_locked - send DRM event to file descriptor
15022 + * drm_send_event_helper - send DRM event to file descriptor
15028 - * This function sends the event @e, initialized with drm_event_reserve_init(),
15029 - * to its associated userspace DRM file. Callers must already hold
15030 - * &drm_device.event_lock, see drm_send_event() for the unlocked version.
15031 - *
15032 - * Note that the core will take care of unlinking and disarming events when the
15033 - * corresponding DRM file is closed. Drivers need not worry about whether the
15034 - * DRM file for this event still exists and can call this function upon
15035 - * completion of the asynchronous work unconditionally.
15041 -void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
15045 assert_spin_locked(&dev->event_lock);
15047 @@ -800,7 +798,10 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
15050 if (e->fence) {
15051 - dma_fence_signal(e->fence);
15053 + dma_fence_signal_timestamp(e->fence, timestamp);
15055 + dma_fence_signal(e->fence);
15056 dma_fence_put(e->fence);
15059 @@ -815,6 +816,48 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
15060 wake_up_interruptible_poll(&e->file_priv->event_wait,
15065 + * drm_send_event_timestamp_locked - send DRM event to file descriptor
15088 + * drm_send_event_locked - send DRM event to file descriptor
15108 @@ -837,7 +880,7 @@ void drm_send_event(struct drm_device *dev, struct drm_pending_event *e)
15111 spin_lock_irqsave(&dev->event_lock, irqflags);
15112 - drm_send_event_locked(dev, e);
15114 spin_unlock_irqrestore(&dev->event_lock, irqflags);
15117 diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
15119 --- a/drivers/gpu/drm/drm_fourcc.c
15121 @@ -278,6 +278,16 @@ const struct drm_format_info *__drm_format_info(u32 format)
15138 diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
15140 --- a/drivers/gpu/drm/drm_ioctl.c
15142 @@ -537,6 +537,7 @@ int drm_version(struct drm_device *dev, void *data,
15149 return -EACCES;
15150 @@ -555,6 +556,7 @@ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
15153 return -EACCES;
15158 @@ -678,9 +680,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
15162 - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0),
15163 - DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, 0),
15164 - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, 0),
15171 diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
15173 --- a/drivers/gpu/drm/drm_lease.c
15175 @@ -107,19 +107,10 @@ static bool _drm_has_leased(struct drm_master *master, int id)
15179 - bool ret;
15180 - struct drm_master *master;
15181 -
15182 - if (!file_priv)
15183 + if (!file_priv || !file_priv->master)
15186 - master = drm_file_get_master(file_priv);
15187 - if (!master)
15188 - return true;
15189 - ret = _drm_lease_held_master(master, id);
15190 - drm_master_put(&master);
15191 -
15192 - return ret;
15193 + return _drm_lease_held_master(file_priv->master, id);
15197 @@ -138,22 +129,13 @@ bool drm_lease_held(struct drm_file *file_priv, int id)
15201 - if (!file_priv)
15202 + if (!file_priv || !file_priv->master || !file_priv->master->lessor)
15205 - master = drm_file_get_master(file_priv);
15206 - if (!master)
15207 - return true;
15208 - if (!master->lessor) {
15209 - ret = true;
15210 - goto out;
15211 - }
15212 + master = file_priv->master;
15213 mutex_lock(&master->dev->mode_config.idr_mutex);
15215 mutex_unlock(&master->dev->mode_config.idr_mutex);
15216 -
15217 -out:
15218 - drm_master_put(&master);
15222 @@ -173,16 +155,10 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
15226 - if (!file_priv)
15227 + if (!file_priv || !file_priv->master || !file_priv->master->lessor)
15230 - master = drm_file_get_master(file_priv);
15231 - if (!master)
15232 - return crtcs_in;
15233 - if (!master->lessor) {
15234 - crtcs_out = crtcs_in;
15235 - goto out;
15236 - }
15237 + master = file_priv->master;
15238 dev = master->dev;
15241 @@ -201,9 +177,6 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
15244 mutex_unlock(&master->dev->mode_config.idr_mutex);
15245 -
15246 -out:
15247 - drm_master_put(&master);
15251 @@ -517,7 +490,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15255 - struct drm_master *lessor;
15256 + struct drm_master *lessor = lessor_priv->master;
15259 struct file *lessor_file = lessor_priv->filp;
15260 @@ -529,6 +502,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15262 return -EOPNOTSUPP;
15264 + /* Do not allow sub-leases */
15265 + if (lessor->lessor) {
15267 + return -EINVAL;
15271 if (cl->object_count == 0) {
15273 @@ -540,22 +519,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15274 return -EINVAL;
15277 - lessor = drm_file_get_master(lessor_priv);
15278 - /* Do not allow sub-leases */
15279 - if (lessor->lessor) {
15280 - DRM_DEBUG_LEASE("recursive leasing not allowed\n");
15281 - ret = -EINVAL;
15282 - goto out_lessor;
15283 - }
15284 -
15285 object_count = cl->object_count;
15287 object_ids = memdup_user(u64_to_user_ptr(cl->object_ids),
15289 - if (IS_ERR(object_ids)) {
15290 - ret = PTR_ERR(object_ids);
15291 - goto out_lessor;
15292 - }
15298 @@ -566,15 +535,14 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15302 - goto out_lessor;
15307 fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
15310 - ret = fd;
15311 - goto out_lessor;
15316 @@ -610,7 +578,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15320 - drm_master_put(&lessor);
15324 @@ -620,8 +587,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15328 -out_lessor:
15329 - drm_master_put(&lessor);
15333 @@ -644,7 +609,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
15335 __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
15336 __u32 count_lessees = arg->count_lessees;
15337 - struct drm_master *lessor, *lessee;
15338 + struct drm_master *lessor = lessor_priv->master, *lessee;
15342 @@ -655,7 +620,6 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
15344 return -EOPNOTSUPP;
15346 - lessor = drm_file_get_master(lessor_priv);
15347 DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
15349 mutex_lock(&dev->mode_config.idr_mutex);
15350 @@ -679,7 +643,6 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
15351 arg->count_lessees = count;
15353 mutex_unlock(&dev->mode_config.idr_mutex);
15354 - drm_master_put(&lessor);
15358 @@ -699,7 +662,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
15360 __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
15361 __u32 count_objects = arg->count_objects;
15362 - struct drm_master *lessee;
15363 + struct drm_master *lessee = lessee_priv->master;
15367 @@ -713,7 +676,6 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
15369 return -EOPNOTSUPP;
15371 - lessee = drm_file_get_master(lessee_priv);
15372 DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
15374 mutex_lock(&dev->mode_config.idr_mutex);
15375 @@ -741,7 +703,6 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
15376 arg->count_objects = count;
15378 mutex_unlock(&dev->mode_config.idr_mutex);
15379 - drm_master_put(&lessee);
15383 @@ -760,7 +721,7 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
15387 - struct drm_master *lessor;
15388 + struct drm_master *lessor = lessor_priv->master;
15392 @@ -770,7 +731,6 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
15394 return -EOPNOTSUPP;
15396 - lessor = drm_file_get_master(lessor_priv);
15397 mutex_lock(&dev->mode_config.idr_mutex);
15399 lessee = _drm_find_lessee(lessor, arg->lessee_id);
15400 @@ -791,7 +751,6 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
15403 mutex_unlock(&dev->mode_config.idr_mutex);
15404 - drm_master_put(&lessor);
15408 diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
15410 --- a/drivers/gpu/drm/drm_mipi_dsi.c
15412 @@ -355,6 +355,7 @@ static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
15414 if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
15415 msg->flags |= MIPI_DSI_MSG_USE_LPM;
15416 + msg->flags |= MIPI_DSI_MSG_LASTCOMMAND;
15418 return ops->transfer(dsi->host, msg);
15420 diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
15422 --- a/drivers/gpu/drm/drm_mode_config.c
15424 @@ -364,6 +364,22 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
15425 return -ENOMEM;
15426 dev->mode_config.gamma_lut_size_property = prop;
15433 + return -ENOMEM;
15434 + dev->mode_config.cubic_lut_property = prop;
15440 + return -ENOMEM;
15441 + dev->mode_config.cubic_lut_size_property = prop;
15447 diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
15449 --- a/drivers/gpu/drm/drm_modes.c
15451 @@ -1940,6 +1940,7 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
15452 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
15453 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
15458 * drm_crtc_convert_umode - convert a modeinfo into a drm_display_mode
15459 @@ -2016,6 +2017,7 @@ int drm_mode_convert_umode(struct drm_device *dev,
15466 * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
15467 diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
15469 --- a/drivers/gpu/drm/drm_prime.c
15471 @@ -780,6 +780,28 @@ int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
15476 + * drm_gem_dmabuf_get_uuid - dma_buf get_uuid implementation for GEM
15487 + struct drm_gem_object *obj = dma_buf->priv;
15488 + struct drm_device *dev = obj->dev;
15490 + if (!dev->driver->gem_prime_get_uuid)
15491 + return -ENODEV;
15493 + return dev->driver->gem_prime_get_uuid(obj, uuid);
15500 @@ -790,6 +812,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
15508 diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
15510 --- a/drivers/gpu/drm/drm_vblank.c
15512 @@ -1000,7 +1000,14 @@ static void send_vblank_event(struct drm_device *dev,
15515 trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq);
15516 - drm_send_event_locked(dev, &e->base);
15521 + * retire-fence timestamp to match exactly with HW vsync as it uses it
15524 + drm_send_event_timestamp_locked(dev, &e->base, now);
15528 diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h b/drivers/gpu/drm/hisilicon/kirin/kiri…
15530 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h
15532 @@ -1,7 +1,7 @@
15533 /* SPDX-License-Identifier: GPL-2.0-only */
15535 - * Copyright (c) 2016 Linaro Limited.
15536 - * Copyright (c) 2014-2016 Hisilicon Limited.
15538 + * Copyright (c) 2014-2016,2019 Hisilicon Limited.
15542 diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
15544 --- a/drivers/gpu/drm/panel/Kconfig
15546 @@ -233,7 +233,6 @@ config DRM_PANEL_OLIMEX_LCD_OLINUXINO
15550 - select CRC32
15554 diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
15556 --- a/drivers/gpu/drm/panel/Makefile
15558 @@ -53,3 +53,5 @@ obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
15559 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
15560 obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o
15561 obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
15563 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/gpu/drm/panel
15564 diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
15566 --- a/drivers/gpu/drm/panel/panel-simple.c
15567 +++ b/drivers/gpu/drm/panel/panel-simple.c
15568 @@ -30,6 +30,7 @@
15576 @@ -37,6 +38,25 @@
15582 +#include "panel-simple.h"
15602 @@ -83,6 +103,10 @@ struct panel_desc {
15613 @@ -90,17 +114,24 @@ struct panel_desc {
15638 @@ -109,10 +140,12 @@ struct panel_simple {
15651 @@ -121,6 +154,124 @@ static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
15665 + return -EINVAL;
15669 + return -ENOMEM;
15678 + len -= sizeof(*header);
15680 + if (header->payload_length > len)
15681 + return -EINVAL;
15683 + d += header->payload_length;
15684 + len -= header->payload_length;
15689 + return -EINVAL;
15691 + seq->cmd_cnt = cnt;
15692 + seq->cmds = devm_kcalloc(dev, cnt, sizeof(*desc), GFP_KERNEL);
15693 + if (!seq->cmds)
15694 + return -ENOMEM;
15700 + len -= sizeof(*header);
15703 + desc = &seq->cmds[i];
15704 + desc->header = *header;
15705 + desc->payload = d;
15707 + d += header->payload_length;
15708 + len -= header->payload_length;
15717 + struct device *dev = panel->base.dev;
15718 + struct mipi_dsi_device *dsi = panel->dsi;
15723 + return -EINVAL;
15725 + return -EINVAL;
15727 + for (i = 0; i < seq->cmd_cnt; i++) {
15728 + struct panel_cmd_desc *cmd = &seq->cmds[i];
15730 + switch (cmd->header.data_type) {
15732 + err = mipi_dsi_compression_mode(dsi, cmd->payload[0]);
15738 + err = mipi_dsi_generic_write(dsi, cmd->payload,
15739 + cmd->header.payload_length);
15744 + err = mipi_dsi_dcs_write_buffer(dsi, cmd->payload,
15745 + cmd->header.payload_length);
15748 + if (!panel->pps) {
15749 + panel->pps = devm_kzalloc(dev, sizeof(*panel->pps),
15751 + if (!panel->pps)
15752 + return -ENOMEM;
15754 + memcpy(panel->pps, cmd->payload, cmd->header.payload_length);
15757 + err = mipi_dsi_picture_parameter_set(dsi, panel->pps);
15760 + return -EINVAL;
15766 + if (cmd->header.delay)
15767 + msleep(cmd->header.delay);
15776 @@ -219,17 +370,72 @@ static int panel_simple_get_non_edid_modes(struct panel_simple *panel,
15780 - connector->display_info.bpc = panel->desc->bpc;
15781 - connector->display_info.width_mm = panel->desc->size.width;
15782 - connector->display_info.height_mm = panel->desc->size.height;
15783 + if (panel->desc->bpc)
15784 + connector->display_info.bpc = panel->desc->bpc;
15785 + if (panel->desc->size.width)
15786 + connector->display_info.width_mm = panel->desc->size.width;
15787 + if (panel->desc->size.height)
15788 + connector->display_info.height_mm = panel->desc->size.height;
15789 if (panel->desc->bus_format)
15790 drm_display_info_set_bus_formats(&connector->display_info,
15791 &panel->desc->bus_format, 1);
15792 - connector->display_info.bus_flags = panel->desc->bus_flags;
15793 + if (panel->desc->bus_flags)
15794 + connector->display_info.bus_flags = panel->desc->bus_flags;
15803 + if (p->power_invert) {
15804 + if (regulator_is_enabled(p->supply) > 0)
15805 + regulator_disable(p->supply);
15807 + err = regulator_enable(p->supply);
15819 + if (p->power_invert) {
15820 + if (!regulator_is_enabled(p->supply)) {
15821 + err = regulator_enable(p->supply);
15826 + regulator_disable(p->supply);
15839 + dev_err(panel->dev, "failed to enable supply: %d\n", err);
15843 + p->prepared = true;
15844 + p->enabled = true;
15853 @@ -252,9 +458,14 @@ static int panel_simple_unprepare(struct drm_panel *panel)
15854 if (!p->prepared)
15857 - gpiod_set_value_cansleep(p->enable_gpio, 0);
15858 + if (p->desc->exit_seq)
15859 + if (p->dsi)
15860 + panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq);
15862 + gpiod_direction_output(p->reset_gpio, 1);
15863 + gpiod_direction_output(p->enable_gpio, 0);
15865 - regulator_disable(p->supply);
15868 if (p->desc->delay.unprepare)
15869 msleep(p->desc->delay.unprepare);
15870 @@ -299,13 +510,23 @@ static int panel_simple_prepare(struct drm_panel *panel)
15871 if (p->prepared)
15874 - err = regulator_enable(p->supply);
15877 dev_err(panel->dev, "failed to enable supply: %d\n", err);
15881 - gpiod_set_value_cansleep(p->enable_gpio, 1);
15882 + gpiod_direction_output(p->enable_gpio, 1);
15884 + if (p->desc->delay.reset)
15885 + msleep(p->desc->delay.prepare);
15887 + gpiod_direction_output(p->reset_gpio, 1);
15889 + if (p->desc->delay.reset)
15890 + msleep(p->desc->delay.reset);
15892 + gpiod_direction_output(p->reset_gpio, 0);
15894 delay = p->desc->delay.prepare;
15895 if (p->no_hpd)
15896 @@ -333,6 +554,13 @@ static int panel_simple_prepare(struct drm_panel *panel)
15900 + if (p->desc->init_seq)
15901 + if (p->dsi)
15902 + panel_simple_xfer_dsi_cmd_seq(p, p->desc->init_seq);
15904 + if (p->desc->delay.init)
15905 + msleep(p->desc->delay.init);
15907 p->prepared = true;
15910 @@ -500,6 +728,52 @@ static void panel_simple_parse_panel_timing_node(struct device *dev,
15917 + struct mipi_dsi_device *dsi = p->dsi;
15920 + if (!p->prepared)
15923 + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
15925 + ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness);
15929 + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
15937 + struct mipi_dsi_device *dsi = p->dsi;
15938 + u16 brightness = bl->props.brightness;
15941 + if (!p->prepared)
15944 + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
15950 + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
15963 @@ -525,15 +799,25 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *de…
15966 panel->supply = devm_regulator_get(dev, "power");
15967 - if (IS_ERR(panel->supply))
15968 - return PTR_ERR(panel->supply);
15969 + if (IS_ERR(panel->supply)) {
15970 + err = PTR_ERR(panel->supply);
15975 - panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
15976 - GPIOD_OUT_LOW);
15977 + panel->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_ASIS);
15978 if (IS_ERR(panel->enable_gpio)) {
15979 err = PTR_ERR(panel->enable_gpio);
15980 if (err != -EPROBE_DEFER)
15981 - dev_err(dev, "failed to request GPIO: %d\n", err);
15986 + panel->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
15987 + if (IS_ERR(panel->reset_gpio)) {
15988 + err = PTR_ERR(panel->reset_gpio);
15989 + if (err != -EPROBE_DEFER)
15994 @@ -543,13 +827,18 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *de…
15998 + panel->power_invert = of_property_read_bool(dev->of_node, "power-invert");
16000 ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
16002 panel->ddc = of_find_i2c_adapter_by_node(ddc);
16005 - if (!panel->ddc)
16006 - return -EPROBE_DEFER;
16007 + if (!panel->ddc) {
16008 + err = -EPROBE_DEFER;
16009 + dev_err(dev, "failed to find ddc-i2c-bus: %d\n", err);
16015 @@ -566,7 +855,7 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
16019 - dev_warn(dev, "Specify missing connector_type\n");
16024 @@ -621,8 +910,10 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *des…
16025 drm_panel_init(&panel->base, dev, &panel_simple_funcs, connector_type);
16027 err = drm_panel_of_backlight(&panel->base);
16028 - if (err)
16034 drm_panel_add(&panel->base);
16036 @@ -3902,6 +4193,9 @@ static const struct panel_desc arm_rtsm = {
16040 + .compatible = "simple-panel",
16043 .compatible = "ampire,am-1280800n3tzqw-t00h",
16046 @@ -4310,15 +4604,132 @@ static const struct of_device_id platform_of_match[] = {
16064 + struct device_node *np = dev->of_node;
16070 + if (of_child_node_is_present(np, "display-timings")) {
16075 + return -ENOMEM;
16079 + desc->modes = mode;
16080 + desc->num_modes = 1;
16081 + desc->bus_flags = bus_flags;
16083 + } else if (of_child_node_is_present(np, "panel-timing")) {
16089 + return -ENOMEM;
16091 + if (!of_get_display_timing(np, "panel-timing", timing)) {
16092 + desc->timings = timing;
16093 + desc->num_timings = 1;
16096 + vm.flags = timing->flags;
16098 + desc->bus_flags = bus_flags;
16102 + if (desc->num_modes || desc->num_timings) {
16103 + of_property_read_u32(np, "bpc", &desc->bpc);
16104 + of_property_read_u32(np, "bus-format", &desc->bus_format);
16105 + of_property_read_u32(np, "width-mm", &desc->size.width);
16106 + of_property_read_u32(np, "height-mm", &desc->size.height);
16109 + of_property_read_u32(np, "prepare-delay-ms", &desc->delay.prepare);
16110 + of_property_read_u32(np, "enable-delay-ms", &desc->delay.enable);
16111 + of_property_read_u32(np, "disable-delay-ms", &desc->delay.disable);
16112 + of_property_read_u32(np, "unprepare-delay-ms", &desc->delay.unprepare);
16113 + of_property_read_u32(np, "reset-delay-ms", &desc->delay.reset);
16114 + of_property_read_u32(np, "init-delay-ms", &desc->delay.init);
16116 + data = of_get_property(np, "panel-init-sequence", &len);
16118 + desc->init_seq = devm_kzalloc(dev, sizeof(*desc->init_seq),
16120 + if (!desc->init_seq)
16121 + return -ENOMEM;
16124 + desc->init_seq);
16131 + data = of_get_property(np, "panel-exit-sequence", &len);
16133 + desc->exit_seq = devm_kzalloc(dev, sizeof(*desc->exit_seq),
16135 + if (!desc->exit_seq)
16136 + return -ENOMEM;
16139 + desc->exit_seq);
16151 + struct device *dev = &pdev->dev;
16157 id = of_match_node(platform_of_match, pdev->dev.of_node);
16159 return -ENODEV;
16161 - return panel_simple_probe(&pdev->dev, id->data);
16162 + if (!id->data) {
16165 + return -ENOMEM;
16174 + desc = id->data ? id->data : d;
16176 + return panel_simple_probe(&pdev->dev, desc);
16180 @@ -4553,6 +4964,9 @@ static const struct panel_desc_dsi osd101t2045_53ts = {
16184 + .compatible = "simple-panel-dsi",
16190 @@ -4579,9 +4993,33 @@ static const struct of_device_id dsi_of_match[] = {
16197 + struct device_node *np = dev->of_node;
16201 + err = panel_simple_of_get_desc_data(dev, &desc->desc);
16206 + desc->flags = val;
16208 + desc->format = val;
16210 + desc->lanes = val;
16218 + struct device *dev = &dsi->dev;
16224 @@ -4589,12 +5027,47 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
16226 return -ENODEV;
16228 - desc = id->data;
16229 + if (!id->data) {
16232 + return -ENOMEM;
16241 + desc = id->data ? id->data : d;
16243 err = panel_simple_probe(&dsi->dev, &desc->desc);
16248 + panel->dsi = dsi;
16250 + if (!panel->base.backlight) {
16258 + panel->base.backlight =
16259 + devm_backlight_device_register(dev, "dcs-backlight",
16262 + if (IS_ERR(panel->base.backlight)) {
16263 + err = PTR_ERR(panel->base.backlight);
16270 dsi->mode_flags = desc->flags;
16271 dsi->format = desc->format;
16272 dsi->lanes = desc->lanes;
16273 diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
16275 --- a/drivers/gpu/drm/panfrost/panfrost_device.h
16277 @@ -120,12 +120,8 @@ struct panfrost_device {
16281 - struct panfrost_device *pfdev;
16282 - struct kref refcount;
16285 - struct drm_mm mm;
16286 - spinlock_t mm_lock;
16290 @@ -136,7 +132,9 @@ struct panfrost_file_priv {
16294 - struct panfrost_mmu *mmu;
16301 diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
16303 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
16305 @@ -417,7 +417,7 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
16308 if (!list_is_singular(&bo->mappings.list) ||
16309 - WARN_ON_ONCE(first->mmu != priv->mmu)) {
16310 + WARN_ON_ONCE(first->mmu != &priv->mmu)) {
16311 ret = -EINVAL;
16314 @@ -449,6 +449,32 @@ int panfrost_unstable_ioctl_check(void)
16319 +#define PFN_4G_MASK (PFN_4G - 1)
16334 + (*end)--;
16337 + if (next_seg - *start <= PFN_16M)
16340 + *end = min(*end, ALIGN(*start, PFN_4G) - 1);
16347 @@ -463,11 +489,15 @@ panfrost_open(struct drm_device *dev, struct drm_file *file)
16348 panfrost_priv->pfdev = pfdev;
16349 file->driver_priv = panfrost_priv;
16351 - panfrost_priv->mmu = panfrost_mmu_ctx_create(pfdev);
16352 - if (IS_ERR(panfrost_priv->mmu)) {
16353 - ret = PTR_ERR(panfrost_priv->mmu);
16354 - goto err_free;
16355 - }
16356 + spin_lock_init(&panfrost_priv->mm_lock);
16358 + /* 4G enough for now. can be 48-bit */
16359 + drm_mm_init(&panfrost_priv->mm, SZ_32M >> PAGE_SHIFT, (SZ_4G - SZ_32M) >> PAGE_SHIFT);
16360 + panfrost_priv->mm.color_adjust = panfrost_drm_mm_color_adjust;
16368 @@ -476,8 +506,9 @@ panfrost_open(struct drm_device *dev, struct drm_file *file)
16372 - panfrost_mmu_ctx_put(panfrost_priv->mmu);
16373 -err_free:
16376 + drm_mm_takedown(&panfrost_priv->mm);
16380 @@ -490,7 +521,8 @@ panfrost_postclose(struct drm_device *dev, struct drm_file *file)
16384 - panfrost_mmu_ctx_put(panfrost_priv->mmu);
16386 + drm_mm_takedown(&panfrost_priv->mm);
16390 diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
16392 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c
16394 @@ -60,7 +60,7 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo,
16396 mutex_lock(&bo->mappings.lock);
16397 list_for_each_entry(iter, &bo->mappings.list, node) {
16398 - if (iter->mmu == priv->mmu) {
16399 + if (iter->mmu == &priv->mmu) {
16400 kref_get(&iter->refcount);
16403 @@ -74,13 +74,16 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo,
16409 if (mapping->active)
16412 - spin_lock(&mapping->mmu->mm_lock);
16413 + priv = container_of(mapping->mmu, struct panfrost_file_priv, mmu);
16414 + spin_lock(&priv->mm_lock);
16415 if (drm_mm_node_allocated(&mapping->mmnode))
16416 drm_mm_remove_node(&mapping->mmnode);
16417 - spin_unlock(&mapping->mmu->mm_lock);
16418 + spin_unlock(&priv->mm_lock);
16422 @@ -91,7 +94,6 @@ static void panfrost_gem_mapping_release(struct kref *kref)
16425 drm_gem_object_put(&mapping->obj->base.base);
16426 - panfrost_mmu_ctx_put(mapping->mmu);
16430 @@ -141,11 +143,11 @@ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)
16434 - mapping->mmu = panfrost_mmu_ctx_get(priv->mmu);
16435 - spin_lock(&mapping->mmu->mm_lock);
16436 - ret = drm_mm_insert_node_generic(&mapping->mmu->mm, &mapping->mmnode,
16437 + mapping->mmu = &priv->mmu;
16438 + spin_lock(&priv->mm_lock);
16439 + ret = drm_mm_insert_node_generic(&priv->mm, &mapping->mmnode,
16441 - spin_unlock(&mapping->mmu->mm_lock);
16442 + spin_unlock(&priv->mm_lock);
16446 @@ -174,7 +176,7 @@ void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
16448 mutex_lock(&bo->mappings.lock);
16449 list_for_each_entry(iter, &bo->mappings.list, node) {
16450 - if (iter->mmu == priv->mmu) {
16451 + if (iter->mmu == &priv->mmu) {
16453 list_del(&iter->node);
16455 diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
16457 --- a/drivers/gpu/drm/panfrost/panfrost_job.c
16459 @@ -165,7 +165,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
16463 - cfg = panfrost_mmu_as_get(pfdev, job->file_priv->mmu);
16464 + cfg = panfrost_mmu_as_get(pfdev, &job->file_priv->mmu);
16468 @@ -524,7 +524,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void *data)
16470 pfdev->jobs[j] = NULL;
16472 - panfrost_mmu_as_put(pfdev, job->file_priv->mmu);
16473 + panfrost_mmu_as_put(pfdev, &job->file_priv->mmu);
16474 panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
16476 dma_fence_signal_locked(job->done_fence);
16477 diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
16479 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
16481 @@ -1,8 +1,5 @@
16482 // SPDX-License-Identifier: GPL-2.0
16484 -
16485 -#include <drm/panfrost_drm.h>
16486 -
16490 @@ -55,16 +52,25 @@ static int write_cmd(struct panfrost_device *pfdev, u32 as_nr, u32 cmd)
16494 - u64 iova, u64 size)
16499 -
16500 - /* The size is encoded as ceil(log2) minus(1), which may be calculated
16501 - * with fls. The size must be clamped to hardware bounds.
16509 - size = max_t(u64, size, AS_LOCK_REGION_MIN_SIZE);
16510 - region_width = fls64(size - 1) - 1;
16515 + if ((size >> PAGE_SHIFT) != (1ul << (region_width - 11))) {
16522 @@ -75,7 +81,7 @@ static void lock_region(struct panfrost_device *pfdev, u32 as_nr,
16526 - u64 iova, u64 size, u32 op)
16531 @@ -92,7 +98,7 @@ static int mmu_hw_do_operation_locked(struct panfrost_device *pfdev, int as_nr,
16535 - u64 iova, u64 size, u32 op)
16540 @@ -109,7 +115,7 @@ static void panfrost_mmu_enable(struct panfrost_device *pfdev, struct panfrost_m
16541 u64 transtab = cfg->arm_mali_lpae_cfg.transtab;
16542 u64 memattr = cfg->arm_mali_lpae_cfg.memattr;
16544 - mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
16549 @@ -125,7 +131,7 @@ static void panfrost_mmu_enable(struct panfrost_device *pfdev, struct panfrost_m
16553 - mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
16558 @@ -225,7 +231,7 @@ static size_t get_pgsize(u64 addr, size_t size)
16562 - u64 iova, u64 size)
16565 if (mmu->as < 0)
16567 @@ -331,7 +337,7 @@ static void mmu_tlb_inv_context_s1(void *cookie)
16571 - //struct panfrost_mmu *mmu = cookie;
16576 @@ -341,22 +347,62 @@ static void mmu_tlb_flush_walk(unsigned long iova, size_t size, size_t granul…
16580 -static void mmu_tlb_flush_leaf(unsigned long iova, size_t size, size_t granule,
16581 - void *cookie)
16582 -{
16583 - mmu_tlb_sync_context(cookie);
16584 -}
16585 -
16589 - .tlb_flush_leaf = mmu_tlb_flush_leaf,
16594 + struct panfrost_mmu *mmu = &priv->mmu;
16595 + struct panfrost_device *pfdev = priv->pfdev;
16597 + INIT_LIST_HEAD(&mmu->list);
16598 + mmu->as = -1;
16600 + mmu->pgtbl_cfg = (struct io_pgtable_cfg) {
16602 + .ias = FIELD_GET(0xff, pfdev->features.mmu_features),
16603 + .oas = FIELD_GET(0xff00, pfdev->features.mmu_features),
16604 + .coherent_walk = pfdev->coherent,
16606 + .iommu_dev = pfdev->dev,
16609 + mmu->pgtbl_ops = alloc_io_pgtable_ops(ARM_MALI_LPAE, &mmu->pgtbl_cfg,
16611 + if (!mmu->pgtbl_ops)
16612 + return -EINVAL;
16619 + struct panfrost_device *pfdev = priv->pfdev;
16620 + struct panfrost_mmu *mmu = &priv->mmu;
16622 + spin_lock(&pfdev->as_lock);
16623 + if (mmu->as >= 0) {
16624 + pm_runtime_get_noresume(pfdev->dev);
16625 + if (pm_runtime_active(pfdev->dev))
16626 + panfrost_mmu_disable(pfdev, mmu->as);
16627 + pm_runtime_put_autosuspend(pfdev->dev);
16629 + clear_bit(mmu->as, &pfdev->as_alloc_mask);
16630 + clear_bit(mmu->as, &pfdev->as_in_use_mask);
16631 + list_del(&mmu->list);
16633 + spin_unlock(&pfdev->as_lock);
16635 + free_io_pgtable_ops(mmu->pgtbl_ops);
16646 @@ -369,10 +415,11 @@ addr_to_mapping(struct panfrost_device *pfdev, int as, u64 addr)
16652 - spin_lock(&mmu->mm_lock);
16653 + spin_lock(&priv->mm_lock);
16655 - drm_mm_for_each_node(node, &mmu->mm) {
16656 + drm_mm_for_each_node(node, &priv->mm) {
16657 if (offset >= node->start &&
16658 offset < (node->start + node->size)) {
16660 @@ -382,7 +429,7 @@ addr_to_mapping(struct panfrost_device *pfdev, int as, u64 addr)
16664 - spin_unlock(&mmu->mm_lock);
16665 + spin_unlock(&priv->mm_lock);
16667 spin_unlock(&pfdev->as_lock);
16669 @@ -495,107 +542,6 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
16673 -static void panfrost_mmu_release_ctx(struct kref *kref)
16674 -{
16675 - struct panfrost_mmu *mmu = container_of(kref, struct panfrost_mmu,
16676 - refcount);
16677 - struct panfrost_device *pfdev = mmu->pfdev;
16678 -
16679 - spin_lock(&pfdev->as_lock);
16680 - if (mmu->as >= 0) {
16681 - pm_runtime_get_noresume(pfdev->dev);
16682 - if (pm_runtime_active(pfdev->dev))
16683 - panfrost_mmu_disable(pfdev, mmu->as);
16684 - pm_runtime_put_autosuspend(pfdev->dev);
16685 -
16686 - clear_bit(mmu->as, &pfdev->as_alloc_mask);
16687 - clear_bit(mmu->as, &pfdev->as_in_use_mask);
16688 - list_del(&mmu->list);
16689 - }
16690 - spin_unlock(&pfdev->as_lock);
16691 -
16692 - free_io_pgtable_ops(mmu->pgtbl_ops);
16693 - drm_mm_takedown(&mmu->mm);
16694 - kfree(mmu);
16695 -}
16696 -
16697 -void panfrost_mmu_ctx_put(struct panfrost_mmu *mmu)
16698 -{
16699 - kref_put(&mmu->refcount, panfrost_mmu_release_ctx);
16700 -}
16701 -
16702 -struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu)
16703 -{
16704 - kref_get(&mmu->refcount);
16705 -
16706 - return mmu;
16707 -}
16708 -
16709 -#define PFN_4G (SZ_4G >> PAGE_SHIFT)
16710 -#define PFN_4G_MASK (PFN_4G - 1)
16711 -#define PFN_16M (SZ_16M >> PAGE_SHIFT)
16712 -
16713 -static void panfrost_drm_mm_color_adjust(const struct drm_mm_node *node,
16714 - unsigned long color,
16715 - u64 *start, u64 *end)
16716 -{
16717 - /* Executable buffers can't start or end on a 4GB boundary */
16718 - if (!(color & PANFROST_BO_NOEXEC)) {
16719 - u64 next_seg;
16720 -
16721 - if ((*start & PFN_4G_MASK) == 0)
16722 - (*start)++;
16723 -
16724 - if ((*end & PFN_4G_MASK) == 0)
16725 - (*end)--;
16726 -
16727 - next_seg = ALIGN(*start, PFN_4G);
16728 - if (next_seg - *start <= PFN_16M)
16729 - *start = next_seg + 1;
16730 -
16731 - *end = min(*end, ALIGN(*start, PFN_4G) - 1);
16732 - }
16733 -}
16734 -
16735 -struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev)
16736 -{
16737 - struct panfrost_mmu *mmu;
16738 -
16739 - mmu = kzalloc(sizeof(*mmu), GFP_KERNEL);
16740 - if (!mmu)
16741 - return ERR_PTR(-ENOMEM);
16742 -
16743 - mmu->pfdev = pfdev;
16744 - spin_lock_init(&mmu->mm_lock);
16745 -
16746 - /* 4G enough for now. can be 48-bit */
16747 - drm_mm_init(&mmu->mm, SZ_32M >> PAGE_SHIFT, (SZ_4G - SZ_32M) >> PAGE_SHIFT);
16748 - mmu->mm.color_adjust = panfrost_drm_mm_color_adjust;
16749 -
16750 - INIT_LIST_HEAD(&mmu->list);
16751 - mmu->as = -1;
16752 -
16753 - mmu->pgtbl_cfg = (struct io_pgtable_cfg) {
16754 - .pgsize_bitmap = SZ_4K | SZ_2M,
16755 - .ias = FIELD_GET(0xff, pfdev->features.mmu_features),
16756 - .oas = FIELD_GET(0xff00, pfdev->features.mmu_features),
16757 - .coherent_walk = pfdev->coherent,
16758 - .tlb = &mmu_tlb_ops,
16759 - .iommu_dev = pfdev->dev,
16760 - };
16761 -
16762 - mmu->pgtbl_ops = alloc_io_pgtable_ops(ARM_MALI_LPAE, &mmu->pgtbl_cfg,
16763 - mmu);
16764 - if (!mmu->pgtbl_ops) {
16765 - kfree(mmu);
16766 - return ERR_PTR(-EINVAL);
16767 - }
16768 -
16769 - kref_init(&mmu->refcount);
16770 -
16771 - return mmu;
16772 -}
16773 -
16777 diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.h b/drivers/gpu/drm/panfrost/panfrost_mmu.h
16779 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.h
16781 @@ -18,8 +18,7 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev);
16785 -struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu);
16786 -void panfrost_mmu_ctx_put(struct panfrost_mmu *mmu);
16787 -struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev);
16792 diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h b/drivers/gpu/drm/panfrost/panfrost_regs.h
16794 --- a/drivers/gpu/drm/panfrost/panfrost_regs.h
16796 @@ -318,8 +318,6 @@
16800 -#define AS_LOCK_REGION_MIN_SIZE (1ULL << 15)
16801 -
16802 #define gpu_write(dev, reg, data) writel(data, dev->iomem + reg)
16803 #define gpu_read(dev, reg) readl(dev->iomem + reg)
16805 diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
16807 --- a/drivers/gpu/drm/rockchip/Kconfig
16809 @@ -1,7 +1,7 @@
16810 # SPDX-License-Identifier: GPL-2.0-only
16813 - depends on DRM && ROCKCHIP_IOMMU
16818 @@ -20,6 +20,53 @@ config DRM_ROCKCHIP
16872 @@ -29,7 +76,6 @@ config ROCKCHIP_ANALOGIX_DP
16876 - depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m)
16880 @@ -53,6 +99,12 @@ config ROCKCHIP_DW_MIPI_DSI
16893 @@ -62,7 +114,6 @@ config ROCKCHIP_INNO_HDMI
16897 - depends on DRM_ROCKCHIP
16901 @@ -72,7 +123,6 @@ config ROCKCHIP_LVDS
16905 - depends on DRM_ROCKCHIP
16909 @@ -82,9 +132,22 @@ config ROCKCHIP_RGB
16913 - depends on DRM_ROCKCHIP
16933 diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
16935 --- a/drivers/gpu/drm/rockchip/Makefile
16937 @@ -4,16 +4,30 @@
16940 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
16941 - rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o
16944 +rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o
16945 +rockchipdrm-$(CONFIG_ROCKCHIP_VOP2) += rockchip_drm_vop2.o rockchip_vop2_reg.o
16947 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
16948 +rockchipdrm-$(CONFIG_ROCKCHIP_DRM_DEBUG) += rockchip_drm_debugfs.o
16949 +rockchipdrm-$(CONFIG_ROCKCHIP_DRM_DIRECT_SHOW) += rockchip_drm_direct_show.o
16950 +rockchipdrm-$(CONFIG_ROCKCHIP_DRM_SELF_TEST) += rockchip_drm_display_pattern.o \
16953 rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
16954 rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
16955 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
16956 -rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
16957 +rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o \
16958 + dw-mipi-dsi2-rockchip.o
16959 +rockchipdrm-$(CONFIG_ROCKCHIP_DW_DP) += dw-dp.o
16960 rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
16961 rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
16962 rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
16963 rockchipdrm-$(CONFIG_ROCKCHIP_RK3066_HDMI) += rk3066_hdmi.o
16964 +rockchipdrm-$(CONFIG_ROCKCHIP_VCONN) += rockchip_drm_vconn.o
16965 +rockchipdrm-$(CONFIG_DRM_ROCKCHIP_VVOP) += rockchip_drm_vvop.o
16967 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
16969 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/gpu/drm/
16971 diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp…
16973 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
16974 +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
16975 @@ -16,6 +16,7 @@
16983 @@ -31,29 +32,44 @@
16987 -#define RK3288_GRF_SOC_CON6 0x25c
16988 -#define RK3288_EDP_LCDC_SEL BIT(5)
16989 -#define RK3399_GRF_SOC_CON20 0x6250
16990 -#define RK3399_EDP_LCDC_SEL BIT(5)
16991 -
16992 -#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
16993 -
17013 * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
17014 - * @lcdsel_grf_reg: grf register offset of lcdc select
17015 - * @lcdsel_big: reg value of selecting vop big for eDP
17016 - * @lcdsel_lit: reg value of selecting vop little for eDP
17027 - u32 lcdsel_grf_reg;
17028 - u32 lcdsel_big;
17029 - u32 lcdsel_lit;
17041 @@ -62,23 +78,116 @@ struct rockchip_dp_device {
17045 - struct clk *pclk;
17046 - struct clk *grfclk;
17072 + if (!field->valid)
17075 + mask = GENMASK(field->msb, field->lsb);
17076 + val <<= field->lsb;
17078 + return rockchip_grf_write(grf, field->reg, mask, val);
17087 + rockchip_grf_field_write(dp->grf, &dp->data->spdif_sel,
17088 + daifmt->fmt == HDMI_SPDIF);
17089 + rockchip_grf_field_write(dp->grf, &dp->data->i2s_sel,
17090 + daifmt->fmt == HDMI_I2S);
17092 + return analogix_dp_audio_hw_params(dp->adp, daifmt, params);
17099 + analogix_dp_audio_shutdown(dp->adp);
17101 + rockchip_grf_field_write(dp->grf, &dp->data->spdif_sel, 0);
17102 + rockchip_grf_field_write(dp->grf, &dp->data->i2s_sel, 0);
17109 + return analogix_dp_audio_startup(dp->adp);
17117 + return analogix_dp_audio_get_eld(dp->adp, buf, len);
17132 + return dp->id == *id;
17149 reset_control_assert(dp->rst);
17151 reset_control_deassert(dp->rst);
17153 + reset_control_assert(dp->apb_reset);
17155 + reset_control_deassert(dp->apb_reset);
17160 @@ -87,29 +196,20 @@ static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data)
17164 - ret = clk_prepare_enable(dp->pclk);
17165 - if (ret < 0) {
17166 - DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
17167 - return ret;
17168 - }
17169 -
17172 DRM_DEV_ERROR(dp->dev, "failed to dp pre init %d\n", ret);
17173 - clk_disable_unprepare(dp->pclk);
17177 - return ret;
17178 + return rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
17185 - clk_disable_unprepare(dp->pclk);
17186 -
17187 - return 0;
17188 + return rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 0);
17192 @@ -129,6 +229,69 @@ static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data,
17199 + struct analogix_dp_plat_data *plat_data = &dp->plat_data;
17204 + if (plat_data->panel)
17205 + panel_simple_loader_protect(plat_data->panel);
17207 + analogix_dp_loader_protect(dp->adp);
17215 + if (of_device_is_compatible(bridge->of_node, "dp-connector"))
17226 + struct rockchip_drm_sub_dev *sdev = &dp->sub_dev;
17229 + if (plat_data->bridge) {
17230 + ret = drm_bridge_attach(&dp->encoder, plat_data->bridge, bridge,
17240 + sdev->connector = connector;
17241 + sdev->of_node = dp->dev->of_node;
17242 + sdev->loader_protect = rockchip_dp_loader_protect;
17253 + struct rockchip_drm_sub_dev *sdev = &dp->sub_dev;
17255 + if (sdev->connector)
17262 @@ -170,7 +333,6 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
17266 - u32 val;
17270 @@ -185,24 +347,11 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
17274 - if (ret)
17275 - val = dp->data->lcdsel_lit;
17276 - else
17277 - val = dp->data->lcdsel_big;
17278 -
17279 DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
17281 - ret = clk_prepare_enable(dp->grfclk);
17282 - if (ret < 0) {
17283 - DRM_DEV_ERROR(dp->dev, "failed to enable grfclk %d\n", ret);
17284 - return;
17285 - }
17286 -
17287 - ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
17288 + ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
17290 DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
17291 -
17292 - clk_disable_unprepare(dp->grfclk);
17296 @@ -233,9 +382,15 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
17302 struct drm_display_info *di = &conn_state->connector->display_info;
17304 + if (di->num_bus_formats)
17305 + s->bus_format = di->bus_formats[0];
17307 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
17312 @@ -246,7 +401,18 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
17314 s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
17315 s->output_type = DRM_MODE_CONNECTOR_eDP;
17316 + if (dp->plat_data.split_mode) {
17317 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
17318 + s->output_flags |= dp->id ? ROCKCHIP_OUTPUT_DATA_SWAP : 0;
17319 + s->output_if |= VOP_OUTPUT_IF_eDP0 | VOP_OUTPUT_IF_eDP1;
17321 + s->output_if |= dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0;
17323 s->output_bpc = di->bpc;
17324 + s->bus_flags = di->bus_flags;
17325 + s->tv_state = &conn_state->tv;
17326 + s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
17327 + s->color_space = V4L2_COLORSPACE_DEFAULT;
17331 @@ -264,26 +430,12 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
17332 struct device *dev = dp->dev;
17333 struct device_node *np = dev->of_node;
17335 - dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
17336 - if (IS_ERR(dp->grf)) {
17337 - DRM_DEV_ERROR(dev, "failed to get rockchip,grf property\n");
17338 - return PTR_ERR(dp->grf);
17339 - }
17340 -
17341 - dp->grfclk = devm_clk_get(dev, "grf");
17342 - if (PTR_ERR(dp->grfclk) == -ENOENT) {
17343 - dp->grfclk = NULL;
17344 - } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) {
17345 - return -EPROBE_DEFER;
17346 - } else if (IS_ERR(dp->grfclk)) {
17347 - DRM_DEV_ERROR(dev, "failed to get grf clock\n");
17348 - return PTR_ERR(dp->grfclk);
17349 - }
17350 -
17351 - dp->pclk = devm_clk_get(dev, "pclk");
17352 - if (IS_ERR(dp->pclk)) {
17353 - DRM_DEV_ERROR(dev, "failed to get pclk property\n");
17354 - return PTR_ERR(dp->pclk);
17356 + dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
17357 + if (IS_ERR(dp->grf)) {
17359 + return PTR_ERR(dp->grf);
17363 dp->rst = devm_reset_control_get(dev, "dp");
17364 @@ -292,6 +444,12 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
17365 return PTR_ERR(dp->rst);
17368 + dp->apb_reset = devm_reset_control_get_optional(dev, "apb");
17369 + if (IS_ERR(dp->apb_reset)) {
17371 + return PTR_ERR(dp->apb_reset);
17377 @@ -302,8 +460,8 @@ static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
17378 struct device *dev = dp->dev;
17381 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
17382 - dev->of_node);
17383 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
17384 + dev->of_node);
17385 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
17388 @@ -327,19 +485,44 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
17390 dp->drm_dev = drm_dev;
17392 - ret = rockchip_dp_drm_create_encoder(dp);
17393 - if (ret) {
17394 - DRM_ERROR("failed to create drm encoder\n");
17395 - return ret;
17396 + if (!dp->plat_data.left) {
17403 + dp->plat_data.encoder = &dp->encoder;
17406 - dp->plat_data.encoder = &dp->encoder;
17407 + if (dp->data->audio) {
17415 + dp->audio_pdev =
17420 + if (IS_ERR(dp->audio_pdev)) {
17421 + ret = PTR_ERR(dp->audio_pdev);
17426 ret = analogix_dp_bind(dp->adp, drm_dev);
17428 - goto err_cleanup_encoder;
17434 + if (dp->audio_pdev)
17435 + platform_device_unregister(dp->audio_pdev);
17437 dp->encoder.funcs->destroy(&dp->encoder);
17439 @@ -350,6 +533,8 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
17443 + if (dp->audio_pdev)
17444 + platform_device_unregister(dp->audio_pdev);
17445 analogix_dp_unbind(dp->adp);
17446 dp->encoder.funcs->destroy(&dp->encoder);
17448 @@ -364,29 +549,51 @@ static int rockchip_dp_probe(struct platform_device *pdev)
17449 struct device *dev = &pdev->dev;
17454 - int ret;
17459 return -ENODEV;
17461 - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
17462 - if (ret < 0)
17463 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, &bridge);
17464 + if (ret < 0 && ret != -ENODEV)
17469 return -ENOMEM;
17471 + id = of_alias_get_id(dev->of_node, "edp");
17481 + return -ENODEV;
17484 dp->dev = dev;
17485 + dp->id = id;
17486 dp->adp = ERR_PTR(-ENODEV);
17487 - dp->data = dp_data;
17488 + dp->data = &dp_data[id];
17489 + dp->plat_data.ssc = dp->data->ssc;
17490 dp->plat_data.panel = panel;
17491 dp->plat_data.dev_type = dp->data->chip_type;
17492 dp->plat_data.power_on_start = rockchip_dp_poweron_start;
17493 dp->plat_data.power_off = rockchip_dp_powerdown;
17494 dp->plat_data.get_modes = rockchip_dp_get_modes;
17495 + dp->plat_data.attach = rockchip_dp_bridge_attach;
17496 + dp->plat_data.detach = rockchip_dp_bridge_detach;
17497 + dp->plat_data.convert_to_split_mode = drm_mode_convert_to_split_mode;
17498 + dp->plat_data.convert_to_origin_mode = drm_mode_convert_to_origin_mode;
17499 + dp->plat_data.skip_connector = rockchip_dp_skip_connector(bridge);
17500 + dp->plat_data.bridge = bridge;
17504 @@ -398,6 +605,18 @@ static int rockchip_dp_probe(struct platform_device *pdev)
17505 if (IS_ERR(dp->adp))
17506 return PTR_ERR(dp->adp);
17508 + if (dp->data->split_mode && device_property_read_bool(dev, "split-mode")) {
17510 + rockchip_dp_find_by_id(dev->driver, !dp->id);
17512 + return -EPROBE_DEFER;
17514 + dp->plat_data.right = secondary->adp;
17515 + dp->plat_data.split_mode = true;
17516 + secondary->plat_data.left = dp->adp;
17517 + secondary->plat_data.split_mode = true;
17523 @@ -411,8 +630,7 @@ static int rockchip_dp_remove(struct platform_device *pdev)
17527 -#ifdef CONFIG_PM_SLEEP
17528 -static int rockchip_dp_suspend(struct device *dev)
17533 @@ -422,7 +640,7 @@ static int rockchip_dp_suspend(struct device *dev)
17534 return analogix_dp_suspend(dp->adp);
17537 -static int rockchip_dp_resume(struct device *dev)
17542 @@ -431,27 +649,49 @@ static int rockchip_dp_resume(struct device *dev)
17544 return analogix_dp_resume(dp->adp);
17546 -#endif
17552 + if (IS_ERR(dp->adp))
17555 + return analogix_dp_runtime_suspend(dp->adp);
17562 + if (IS_ERR(dp->adp))
17565 + return analogix_dp_runtime_resume(dp->adp);
17569 -#ifdef CONFIG_PM_SLEEP
17570 - .suspend_late = rockchip_dp_suspend,
17571 - .resume_early = rockchip_dp_resume,
17572 -#endif
17578 -static const struct rockchip_dp_chip_data rk3399_edp = {
17579 - .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
17580 - .lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL),
17581 - .lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL),
17582 - .chip_type = RK3399_EDP,
17592 -static const struct rockchip_dp_chip_data rk3288_dp = {
17593 - .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
17594 - .lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL),
17595 - .lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL),
17596 - .chip_type = RK3288_DP,
17607 diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
17609 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
17610 +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
17611 @@ -6,7 +6,6 @@
17615 -#include <linux/extcon.h>
17619 @@ -143,24 +142,7 @@ static void cdn_dp_clk_disable(struct cdn_dp_device *dp)
17623 - struct extcon_dev *edev = port->extcon;
17624 - union extcon_property_value property;
17625 - int dptx;
17626 - u8 lanes;
17627 -
17628 - dptx = extcon_get_state(edev, EXTCON_DISP_DP);
17629 - if (dptx > 0) {
17630 - extcon_get_property(edev, EXTCON_DISP_DP,
17631 - EXTCON_PROP_USB_SS, &property);
17632 - if (property.intval)
17633 - lanes = 2;
17634 - else
17635 - lanes = 4;
17636 - } else {
17637 - lanes = 0;
17638 - }
17639 -
17640 - return lanes;
17641 + return phy_get_bus_width(port->phy);
17645 @@ -194,7 +176,6 @@ static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
17649 - struct cdn_dp_port *port;
17652 if (dp->active_port < 0 || dp->active_port >= dp->ports) {
17653 @@ -202,8 +183,6 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
17657 - port = dp->port[dp->active_port];
17658 -
17662 @@ -211,9 +190,6 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
17666 - if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
17667 - return false;
17668 -
17672 @@ -244,6 +220,13 @@ static void cdn_dp_connector_destroy(struct drm_connector *connector)
17680 + schedule_delayed_work(&dp->event_work, msecs_to_jiffies(100));
17686 @@ -382,7 +365,6 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
17690 - union extcon_property_value property;
17693 if (!port->phy_enabled) {
17694 @@ -409,15 +391,8 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *por…
17698 - ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
17699 - EXTCON_PROP_USB_TYPEC_POLARITY, &property);
17700 - if (ret) {
17701 - DRM_DEV_ERROR(dp->dev, "get property failed\n");
17702 - goto err_power_on;
17703 - }
17704 -
17705 port->lanes = cdn_dp_get_port_lanes(port);
17706 - ret = cdn_dp_set_host_cap(dp, port->lanes, property.intval);
17707 + ret = cdn_dp_set_host_cap(dp, port->lanes, 0);
17709 DRM_DEV_ERROR(dp->dev, "set host capabilities failed: %d\n",
17711 @@ -669,7 +644,7 @@ static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
17712 * run the event_work to re-connect it.
17714 if (!dp->connected && cdn_dp_connected_port(dp))
17715 - schedule_work(&dp->event_work);
17716 + schedule_delayed_work(&dp->event_work, 0);
17720 @@ -680,6 +655,7 @@ static int cdn_dp_encoder_atomic_check(struct drm_encoder *encoder,
17722 s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
17723 s->output_type = DRM_MODE_CONNECTOR_DisplayPort;
17724 + s->tv_state = &conn_state->tv;
17728 @@ -912,7 +888,7 @@ static int cdn_dp_request_firmware(struct cdn_dp_device *dp)
17732 - struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
17735 struct drm_connector *connector = &dp->connector;
17737 @@ -985,31 +961,13 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
17738 drm_kms_helper_hotplug_event(dp->drm_dev);
17741 -static int cdn_dp_pd_event(struct notifier_block *nb,
17742 - unsigned long event, void *priv)
17743 -{
17744 - struct cdn_dp_port *port = container_of(nb, struct cdn_dp_port,
17745 - event_nb);
17746 - struct cdn_dp_device *dp = port->dp;
17747 -
17748 - /*
17749 - * It would be nice to be able to just do the work inline right here.
17750 - * However, we need to make a bunch of calls that might sleep in order
17751 - * to turn on the block/phy, so use a worker instead.
17752 - */
17753 - schedule_work(&dp->event_work);
17754 -
17755 - return NOTIFY_DONE;
17756 -}
17757 -
17763 - struct cdn_dp_port *port;
17765 - int ret, i;
17770 @@ -1021,12 +979,12 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
17771 dp->active_port = -1;
17772 dp->fw_loaded = false;
17774 - INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
17775 + INIT_DELAYED_WORK(&dp->event_work, cdn_dp_pd_event_work);
17777 encoder = &dp->encoder;
17779 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
17780 - dev->of_node);
17781 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
17782 + dev->of_node);
17783 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
17786 @@ -1058,23 +1016,14 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *dat…
17790 - for (i = 0; i < dp->ports; i++) {
17791 - port = dp->port[i];
17792 -
17793 - port->event_nb.notifier_call = cdn_dp_pd_event;
17794 - ret = devm_extcon_register_notifier(dp->dev, port->extcon,
17795 - EXTCON_DISP_DP,
17796 - &port->event_nb);
17797 - if (ret) {
17798 - DRM_DEV_ERROR(dev,
17799 - "register EXTCON_DISP_DP notifier err\n");
17800 - goto err_free_connector;
17801 - }
17802 - }
17803 + dp->sub_dev.connector = &dp->connector;
17804 + dp->sub_dev.of_node = dev->of_node;
17805 + dp->sub_dev.oob_hotplug_event = cdn_dp_oob_hotplug_event;
17806 + rockchip_drm_register_sub_dev(&dp->sub_dev);
17810 - schedule_work(&dp->event_work);
17811 + schedule_delayed_work(&dp->event_work, 0);
17815 @@ -1091,7 +1040,7 @@ static void cdn_dp_unbind(struct device *dev, struct device *master, void *da…
17816 struct drm_encoder *encoder = &dp->encoder;
17817 struct drm_connector *connector = &dp->connector;
17819 - cancel_work_sync(&dp->event_work);
17820 + cancel_delayed_work_sync(&dp->event_work);
17822 encoder->funcs->destroy(encoder);
17823 connector->funcs->destroy(connector);
17824 @@ -1122,14 +1071,14 @@ static int cdn_dp_suspend(struct device *dev)
17828 -static __maybe_unused int cdn_dp_resume(struct device *dev)
17833 mutex_lock(&dp->lock);
17834 dp->suspended = false;
17835 if (dp->fw_loaded)
17836 - schedule_work(&dp->event_work);
17837 + schedule_delayed_work(&dp->event_work, 0);
17838 mutex_unlock(&dp->lock);
17841 @@ -1142,7 +1091,6 @@ static int cdn_dp_probe(struct platform_device *pdev)
17845 - struct extcon_dev *extcon;
17849 @@ -1155,21 +1103,18 @@ static int cdn_dp_probe(struct platform_device *pdev)
17850 dp_data = (struct cdn_dp_data *)match->data;
17852 for (i = 0; i < dp_data->max_phy; i++) {
17853 - extcon = extcon_get_edev_by_phandle(dev, i);
17854 phy = devm_of_phy_get_by_index(dev, dev->of_node, i);
17856 - if (PTR_ERR(extcon) == -EPROBE_DEFER ||
17857 - PTR_ERR(phy) == -EPROBE_DEFER)
17858 + if (PTR_ERR(phy) == -EPROBE_DEFER)
17859 return -EPROBE_DEFER;
17861 - if (IS_ERR(extcon) || IS_ERR(phy))
17867 return -ENOMEM;
17869 - port->extcon = extcon;
17870 port->phy = phy;
17871 port->dp = dp;
17872 port->id = i;
17873 @@ -1177,7 +1122,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
17876 if (!dp->ports) {
17877 - DRM_DEV_ERROR(dev, "missing extcon or phy\n");
17879 return -EINVAL;
17882 diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
17884 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
17885 +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
17886 @@ -53,8 +53,6 @@ struct cdn_firmware_header {
17890 - struct notifier_block event_nb;
17891 - struct extcon_dev *extcon;
17895 @@ -68,8 +66,9 @@ struct cdn_dp_device {
17899 - struct work_struct event_work;
17906 diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi…
17908 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
17909 +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
17910 @@ -16,8 +16,9 @@
17916 -
17921 @@ -140,6 +141,7 @@
17929 @@ -172,6 +174,12 @@
17942 @@ -198,6 +206,19 @@ enum {
17962 @@ -213,25 +234,42 @@ struct rockchip_dw_dsi_chip_data {
17976 -
17997 /* dual-channel */
18006 @@ -243,6 +281,9 @@ struct dw_mipi_dsi_rockchip {
18016 @@ -365,10 +406,27 @@ static inline unsigned int ns2ui(struct dw_mipi_dsi_rockchip *dsi, int ns)
18017 return DIV_ROUND_UP(ns * dsi->lane_mbps, 1000);
18022 + if (dsi->cdata->lanecfg1_grf_reg)
18023 + regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
18024 + dsi->cdata->lanecfg1);
18026 + if (dsi->cdata->lanecfg2_grf_reg)
18027 + regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg2_grf_reg,
18028 + dsi->cdata->lanecfg2);
18030 + if (dsi->cdata->enable_grf_reg)
18031 + regmap_write(dsi->grf_regmap, dsi->cdata->enable_grf_reg,
18032 + dsi->cdata->enable);
18038 - int ret, i, vco;
18043 if (dsi->phy)
18045 @@ -395,12 +453,6 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
18049 - ret = clk_prepare_enable(dsi->phy_cfg_clk);
18050 - if (ret) {
18051 - DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk\n");
18052 - return ret;
18053 - }
18054 -
18058 @@ -453,7 +505,7 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
18062 - TLP_PROGRAM_EN | ns2bc(dsi, 500));
18067 @@ -466,7 +518,7 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
18071 - TLP_PROGRAM_EN | ns2bc(dsi, 500));
18076 @@ -476,31 +528,29 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
18080 - clk_disable_unprepare(dsi->phy_cfg_clk);
18081 -
18082 - return ret;
18089 - int ret;
18091 - ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
18092 - if (ret) {
18093 - DRM_DEV_ERROR(dsi->dev, "failed to set phy mode: %d\n", ret);
18094 + if (dsi->phy_enabled)
18096 - }
18098 - phy_configure(dsi->phy, &dsi->phy_opts);
18099 phy_power_on(dsi->phy);
18100 + dsi->phy_enabled = true;
18107 + if (!dsi->phy_enabled)
18110 phy_power_off(dsi->phy);
18111 + dsi->phy_enabled = false;
18115 @@ -509,17 +559,22 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mod…
18119 + struct device *dev = dsi->dev;
18123 - unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
18135 + max_mbps = dsi->cdata->max_bit_rate_per_lane / USEC_PER_SEC;
18136 dsi->format = format;
18137 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
18139 @@ -529,23 +584,40 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mod…
18143 - mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
18144 - if (mpclk) {
18145 - /* take 1 / 0.8, since mbps must big than bandwidth of RGB */
18146 - tmp = mpclk * (bpp / lanes) * 10 / 8;
18147 - if (tmp < max_mbps)
18148 - target_mbps = tmp;
18149 - else
18150 - DRM_DEV_ERROR(dsi->dev,
18151 - "DPHY clock frequency is out of range\n");
18153 + if (!of_property_read_u32(dev->of_node, "rockchip,lane-rate", &value)) {
18156 + mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
18163 + DRM_DEV_ERROR(dsi->dev,
18171 if (dsi->phy) {
18172 - phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
18176 &dsi->phy_opts.mipi_dphy);
18177 - dsi->lane_mbps = target_mbps;
18178 + ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
18180 + DRM_DEV_ERROR(dsi->dev,
18185 + phy_configure(dsi->phy, &dsi->phy_opts);
18186 + hs_clk_rate = dsi->phy_opts.mipi_dphy.hs_clk_rate;
18187 + dsi->lane_mbps = DIV_ROUND_UP(hs_clk_rate, USEC_PER_SEC);
18188 *lane_mbps = dsi->lane_mbps;
18191 @@ -611,74 +683,18 @@ struct hstt {
18195 -#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \
18196 -{ \
18197 - .maxfreq = _maxfreq, \
18198 - .timing = { \
18199 - .clk_lp2hs = _c_lp2hs, \
18200 - .clk_hs2lp = _c_hs2lp, \
18201 - .data_lp2hs = _d_lp2hs, \
18202 - .data_hs2lp = _d_hs2lp, \
18203 - } \
18204 -}
18205 -
18206 -/* Table A-3 High-Speed Transition Times */
18207 -struct hstt hstt_table[] = {
18208 - HSTT( 90, 32, 20, 26, 13),
18209 - HSTT( 100, 35, 23, 28, 14),
18210 - HSTT( 110, 32, 22, 26, 13),
18211 - HSTT( 130, 31, 20, 27, 13),
18212 - HSTT( 140, 33, 22, 26, 14),
18213 - HSTT( 150, 33, 21, 26, 14),
18214 - HSTT( 170, 32, 20, 27, 13),
18215 - HSTT( 180, 36, 23, 30, 15),
18216 - HSTT( 200, 40, 22, 33, 15),
18217 - HSTT( 220, 40, 22, 33, 15),
18218 - HSTT( 240, 44, 24, 36, 16),
18219 - HSTT( 250, 48, 24, 38, 17),
18220 - HSTT( 270, 48, 24, 38, 17),
18221 - HSTT( 300, 50, 27, 41, 18),
18222 - HSTT( 330, 56, 28, 45, 18),
18223 - HSTT( 360, 59, 28, 48, 19),
18224 - HSTT( 400, 61, 30, 50, 20),
18225 - HSTT( 450, 67, 31, 55, 21),
18226 - HSTT( 500, 73, 31, 59, 22),
18227 - HSTT( 550, 79, 36, 63, 24),
18228 - HSTT( 600, 83, 37, 68, 25),
18229 - HSTT( 650, 90, 38, 73, 27),
18230 - HSTT( 700, 95, 40, 77, 28),
18231 - HSTT( 750, 102, 40, 84, 28),
18232 - HSTT( 800, 106, 42, 87, 30),
18233 - HSTT( 850, 113, 44, 93, 31),
18234 - HSTT( 900, 118, 47, 98, 32),
18235 - HSTT( 950, 124, 47, 102, 34),
18236 - HSTT(1000, 130, 49, 107, 35),
18237 - HSTT(1050, 135, 51, 111, 37),
18238 - HSTT(1100, 139, 51, 114, 38),
18239 - HSTT(1150, 146, 54, 120, 40),
18240 - HSTT(1200, 153, 57, 125, 41),
18241 - HSTT(1250, 158, 58, 130, 42),
18242 - HSTT(1300, 163, 58, 135, 44),
18243 - HSTT(1350, 168, 60, 140, 45),
18244 - HSTT(1400, 172, 64, 144, 47),
18245 - HSTT(1450, 176, 65, 148, 48),
18246 - HSTT(1500, 181, 66, 153, 50)
18258 - int i;
18259 -
18260 - for (i = 0; i < ARRAY_SIZE(hstt_table); i++)
18261 - if (lane_mbps < hstt_table[i].maxfreq)
18262 - break;
18263 -
18264 - if (i == ARRAY_SIZE(hstt_table))
18265 - i--;
18266 -
18267 - *timing = hstt_table[i].timing;
18272 @@ -691,26 +707,25 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
18276 -static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi)
18279 - if (dsi->cdata->lanecfg1_grf_reg)
18280 - regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
18281 - dsi->cdata->lanecfg1);
18284 - if (dsi->cdata->lanecfg2_grf_reg)
18285 - regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg2_grf_reg,
18286 - dsi->cdata->lanecfg2);
18287 + mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node,
18288 + &dsi->encoder);
18292 - if (dsi->cdata->enable_grf_reg)
18293 - regmap_write(dsi->grf_regmap, dsi->cdata->enable_grf_reg,
18294 - dsi->cdata->enable);
18295 -}
18296 + if (dsi->cdata->lcdsel_grf_reg) {
18297 + regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
18298 + mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
18300 -static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi,
18301 - int mux)
18302 -{
18303 - regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
18304 - mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
18305 + if (dsi->slave && dsi->slave->cdata->lcdsel_grf_reg)
18306 + regmap_write(dsi->slave->grf_regmap,
18307 + dsi->slave->cdata->lcdsel_grf_reg,
18308 + mux ? dsi->slave->cdata->lcdsel_lit :
18309 + dsi->slave->cdata->lcdsel_big);
18314 @@ -720,6 +735,8 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
18318 + struct drm_connector *connector = conn_state->connector;
18319 + struct drm_display_info *info = &connector->display_info;
18321 switch (dsi->format) {
18323 @@ -736,9 +753,42 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
18324 return -EINVAL;
18327 + if (info->num_bus_formats)
18328 + s->bus_format = info->bus_formats[0];
18330 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
18333 + if (dsi->cdata->soc_type == RK3568) {
18334 + s->bus_flags &= ~DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
18335 + s->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
18338 s->output_type = DRM_MODE_CONNECTOR_DSI;
18339 - if (dsi->slave)
18340 - s->output_flags = ROCKCHIP_OUTPUT_DSI_DUAL;
18341 + s->color_space = V4L2_COLORSPACE_DEFAULT;
18342 + s->output_if = dsi->id ? VOP_OUTPUT_IF_MIPI1 : VOP_OUTPUT_IF_MIPI0;
18343 + if (dsi->slave) {
18344 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
18345 + s->output_if |= VOP_OUTPUT_IF_MIPI1;
18349 + if (dsi->id && dsi->cdata->soc_type == RK3399)
18350 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
18352 + if (dsi->dsc_enable) {
18353 + s->dsc_enable = 1;
18354 + s->dsc_sink_cap.version_major = dsi->version_major;
18355 + s->dsc_sink_cap.version_minor = dsi->version_minor;
18356 + s->dsc_sink_cap.slice_width = dsi->slice_width;
18357 + s->dsc_sink_cap.slice_height = dsi->slice_height;
18359 + s->dsc_sink_cap.target_bits_per_pixel_x16 = 8 << 4;
18360 + s->dsc_sink_cap.block_pred = dsi->block_pred_enable;
18361 + s->dsc_sink_cap.native_420 = 0;
18363 + memcpy(&s->pps, dsi->pps, sizeof(struct drm_dsc_picture_parameter_set));
18368 @@ -746,42 +796,43 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
18372 - int ret, mux;
18374 - mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node,
18375 - &dsi->encoder);
18376 - if (mux < 0)
18377 - return;
18381 - pm_runtime_get_sync(dsi->dev);
18382 - if (dsi->slave)
18383 - pm_runtime_get_sync(dsi->slave->dev);
18388 - /*
18389 - * For the RK3399, the clk of grf must be enabled before writing grf
18390 - * register. And for RK3288 or other soc, this grf_clk must be NULL,
18391 - * the clk_prepare_enable return true directly.
18392 - */
18393 - ret = clk_prepare_enable(dsi->grf_clk);
18394 - if (ret) {
18395 - DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
18396 - return;
18400 + pm_runtime_get_sync(dsi->dev);
18401 + phy_init(dsi->phy);
18402 + dsi->phy_enabled = true;
18403 + if (dsi->phy)
18404 + dsi->phy->power_count++;
18406 + pm_runtime_put(dsi->dev);
18407 + phy_exit(dsi->phy);
18408 + dsi->phy_enabled = false;
18409 + if (dsi->phy)
18410 + dsi->phy->power_count--;
18413 - dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux);
18414 if (dsi->slave)
18415 - dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux);
18416 -
18417 - clk_disable_unprepare(dsi->grf_clk);
18418 + dw_mipi_dsi_rockchip_loader_protect(dsi->slave, on);
18421 -static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
18427 - if (dsi->slave)
18428 - pm_runtime_put(dsi->slave->dev);
18429 - pm_runtime_put(dsi->dev);
18430 + if (dsi->panel)
18431 + panel_simple_loader_protect(dsi->panel);
18437 @@ -797,8 +848,8 @@ static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
18438 struct drm_encoder *encoder = &dsi->encoder;
18441 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
18442 - dsi->dev->of_node);
18443 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
18444 + dsi->dev->of_node);
18448 @@ -814,61 +865,90 @@ static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
18452 - const struct of_device_id *match;
18453 - struct device_node *node = NULL, *local;
18454 -
18455 - match = of_match_device(dsi->dev->driver->of_match_table, dsi->dev);
18456 -
18457 - local = of_graph_get_remote_node(dsi->dev->of_node, 1, 0);
18458 - if (!local)
18459 - return NULL;
18460 -
18461 - while ((node = of_find_compatible_node(node, NULL,
18462 - match->compatible))) {
18463 - struct device_node *remote;
18468 + node = of_parse_phandle(dsi->dev->of_node, "rockchip,dual-channel", 0);
18472 + return ERR_PTR(-EPROBE_DEFER);
18477 + return ERR_PTR(-EPROBE_DEFER);
18480 - /* found ourself */
18481 - if (node == dsi->dev->of_node)
18482 - continue;
18483 + return &pdev->dev;
18486 - remote = of_graph_get_remote_node(node, 1, 0);
18487 - if (!remote)
18488 - continue;
18492 - /* same display device in port1-ep0 for both */
18493 - if (remote == local) {
18494 - struct dw_mipi_dsi_rockchip *dsi2;
18495 - struct platform_device *pdev;
18509 + return -ENODEV;
18512 + np = panel->dev->of_node;
18514 + np = bridge->of_node;
18516 + dsi->c_option = of_property_read_bool(np, "phy-c-option");
18517 + dsi->scrambling_en = of_property_read_bool(np, "scrambling-enable");
18518 + dsi->dsc_enable = of_property_read_bool(np, "compressed-data");
18519 + dsi->block_pred_enable = of_property_read_bool(np, "blk-pred-enable");
18520 + of_property_read_u32(np, "slice-width", &dsi->slice_width);
18521 + of_property_read_u32(np, "slice-height", &dsi->slice_height);
18522 + of_property_read_u32(np, "slice-per-pkt", &dsi->slice_per_pkt);
18523 + of_property_read_u8(np, "version-major", &dsi->version_major);
18524 + of_property_read_u8(np, "version-minor", &dsi->version_minor);
18526 + data = of_get_property(np, "panel-init-sequence", &len);
18528 + return -EINVAL;
18530 - pdev = of_find_device_by_node(node);
18531 + d = devm_kmemdup(dsi->dev, data, len, GFP_KERNEL);
18533 + return -ENOMEM;
18535 - /*
18536 - * we have found the second, so will either return it
18537 - * or return with an error. In any case won't need the
18538 - * nodes anymore nor continue the loop.
18539 - */
18540 - of_node_put(remote);
18541 - of_node_put(node);
18542 - of_node_put(local);
18546 + len -= sizeof(*header);
18548 - if (!pdev)
18549 - return ERR_PTR(-EPROBE_DEFER);
18550 + if (header->payload_length > len)
18551 + return -EINVAL;
18553 - dsi2 = platform_get_drvdata(pdev);
18554 - if (!dsi2) {
18555 - platform_device_put(pdev);
18556 - return ERR_PTR(-EPROBE_DEFER);
18557 - }
18558 + if (header->cmd_type == MIPI_DSI_PICTURE_PARAMETER_SET) {
18559 + dsc_packed_pps = devm_kmemdup(dsi->dev, d,
18560 + header->payload_length, GFP_KERNEL);
18562 + return -ENOMEM;
18564 - return &pdev->dev;
18569 - of_node_put(remote);
18570 + d += header->payload_length;
18571 + len -= header->payload_length;
18573 + dsi->pps = pps;
18575 - of_node_put(local);
18576 -
18577 - return NULL;
18582 @@ -878,7 +958,6 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18586 - bool master1, master2;
18590 @@ -886,27 +965,7 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18594 - master1 = of_property_read_bool(dsi->dev->of_node,
18595 - "clock-master");
18596 - master2 = of_property_read_bool(second->of_node,
18597 - "clock-master");
18598 -
18599 - if (master1 && master2) {
18600 - DRM_DEV_ERROR(dsi->dev, "only one clock-master allowed\n");
18601 - return -EINVAL;
18602 - }
18603 -
18604 - if (!master1 && !master2) {
18605 - DRM_DEV_ERROR(dsi->dev, "no clock-master defined\n");
18606 - return -EINVAL;
18607 - }
18608 -
18609 /* we are the slave in dual-DSI */
18610 - if (!master1) {
18611 - dsi->is_slave = true;
18612 - return 0;
18613 - }
18614 -
18615 dsi->slave = dev_get_drvdata(second);
18616 if (!dsi->slave) {
18618 @@ -918,30 +977,15 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18622 + if (dsi->is_slave)
18625 ret = clk_prepare_enable(dsi->pllref_clk);
18631 - /*
18632 - * With the GRF clock running, write lane and dual-mode configurations
18633 - * that won't change immediately. If we waited until enable() to do
18634 - * this, things like panel preparation would not be able to send
18635 - * commands over DSI.
18636 - */
18637 - ret = clk_prepare_enable(dsi->grf_clk);
18638 - if (ret) {
18639 - DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
18640 - return ret;
18641 - }
18642 -
18643 - dw_mipi_dsi_rockchip_config(dsi);
18644 - if (dsi->slave)
18645 - dw_mipi_dsi_rockchip_config(dsi->slave);
18646 -
18647 - clk_disable_unprepare(dsi->grf_clk);
18648 -
18652 @@ -954,6 +998,20 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18656 + ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0,
18657 + &dsi->panel, NULL);
18659 + dev_err(dsi->dev, "failed to find panel\n");
18661 + dw_mipi_dsi_get_dsc_info_from_sink(dsi, dsi->panel, NULL);
18663 + dsi->sub_dev.connector = dw_mipi_dsi_get_connector(dsi->dmd);
18664 + if (dsi->sub_dev.connector) {
18665 + dsi->sub_dev.of_node = dev->of_node;
18666 + dsi->sub_dev.loader_protect = dw_mipi_dsi_rockchip_encoder_loader_protect;
18667 + rockchip_drm_register_sub_dev(&dsi->sub_dev);
18673 @@ -966,6 +1024,9 @@ static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
18674 if (dsi->is_slave)
18677 + if (dsi->sub_dev.connector)
18678 + rockchip_drm_unregister_sub_dev(&dsi->sub_dev);
18680 dw_mipi_dsi_unbind(dsi->dmd);
18682 clk_disable_unprepare(dsi->pllref_clk);
18683 @@ -1051,6 +1112,7 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
18685 if (cdata[i].reg == res->start) {
18686 dsi->cdata = &cdata[i];
18687 + dsi->id = i;
18691 @@ -1070,6 +1132,13 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
18695 + dsi->pclk = devm_clk_get(dev, "pclk");
18696 + if (IS_ERR(dsi->pclk)) {
18697 + ret = PTR_ERR(dsi->pclk);
18702 dsi->pllref_clk = devm_clk_get(dev, "ref");
18703 if (IS_ERR(dsi->pllref_clk)) {
18704 if (dsi->phy) {
18705 @@ -1106,6 +1175,15 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
18709 + if (dsi->cdata->flags & DW_MIPI_NEEDS_HCLK) {
18710 + dsi->hclk = devm_clk_get(dev, "hclk");
18711 + if (IS_ERR(dsi->hclk)) {
18712 + ret = PTR_ERR(dsi->hclk);
18718 dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
18719 if (IS_ERR(dsi->grf_regmap)) {
18720 DRM_DEV_ERROR(dsi->dev, "Unable to get rockchip,grf\n");
18721 @@ -1140,11 +1218,43 @@ static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev)
18725 + if (dsi->devcnt == 0)
18726 + component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops);
18728 dw_mipi_dsi_remove(dsi->dmd);
18737 + clk_disable_unprepare(dsi->grf_clk);
18738 + clk_disable_unprepare(dsi->pclk);
18739 + clk_disable_unprepare(dsi->hclk);
18740 + clk_disable_unprepare(dsi->phy_cfg_clk);
18749 + clk_prepare_enable(dsi->phy_cfg_clk);
18750 + clk_prepare_enable(dsi->hclk);
18751 + clk_prepare_enable(dsi->pclk);
18752 + clk_prepare_enable(dsi->grf_clk);
18765 @@ -1159,6 +1269,8 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
18774 @@ -1171,6 +1283,8 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
18783 @@ -1179,6 +1293,8 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
18792 @@ -1199,6 +1315,8 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
18801 @@ -1225,6 +1343,38 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
18840 @@ -1239,6 +1389,9 @@ static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
18842 .compatible = "rockchip,rk3399-mipi-dsi",
18845 + .compatible = "rockchip,rk3568-mipi-dsi",
18850 @@ -1249,6 +1402,7 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = {
18855 .name = "dw-mipi-dsi-rockchip",
18858 diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchi…
18860 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
18861 +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
18862 @@ -4,21 +4,31 @@
18894 @@ -29,8 +39,11 @@
18898 -#define RK3328_GRF_SOC_CON2 0x0408
18907 @@ -50,109 +63,350 @@
18911 -#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
18970 * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
18999 - struct clk *vpll_clk;
19095 - 27000000, {
19096 - { 0x00b3, 0x0000},
19097 - { 0x2153, 0x0000},
19098 - { 0x40f3, 0x0000}
19099 - },
19100 - }, {
19101 - 36000000, {
19102 - { 0x00b3, 0x0000},
19103 - { 0x2153, 0x0000},
19104 - { 0x40f3, 0x0000}
19105 - },
19106 - }, {
19107 - 40000000, {
19108 - { 0x00b3, 0x0000},
19109 - { 0x2153, 0x0000},
19110 - { 0x40f3, 0x0000}
19111 - },
19112 - }, {
19113 - 54000000, {
19114 - { 0x0072, 0x0001},
19115 - { 0x2142, 0x0001},
19116 - { 0x40a2, 0x0001},
19117 - },
19118 - }, {
19119 - 65000000, {
19120 - { 0x0072, 0x0001},
19121 - { 0x2142, 0x0001},
19122 - { 0x40a2, 0x0001},
19123 - },
19124 - }, {
19125 - 66000000, {
19126 - { 0x013e, 0x0003},
19127 - { 0x217e, 0x0002},
19128 - { 0x4061, 0x0002}
19129 - },
19130 - }, {
19131 - 74250000, {
19132 - { 0x0072, 0x0001},
19133 - { 0x2145, 0x0002},
19134 - { 0x4061, 0x0002}
19135 - },
19136 - }, {
19137 - 83500000, {
19138 - { 0x0072, 0x0001},
19139 - },
19140 - }, {
19141 - 108000000, {
19142 - { 0x0051, 0x0002},
19143 - { 0x2145, 0x0002},
19144 - { 0x4061, 0x0002}
19145 - },
19146 - }, {
19147 - 106500000, {
19148 - { 0x0051, 0x0002},
19149 - { 0x2145, 0x0002},
19150 - { 0x4061, 0x0002}
19151 - },
19152 - }, {
19153 - 146250000, {
19154 - { 0x0051, 0x0002},
19155 - { 0x2145, 0x0002},
19156 - { 0x4061, 0x0002}
19157 - },
19158 - }, {
19159 - 148500000, {
19160 - { 0x0051, 0x0003},
19161 - { 0x214c, 0x0003},
19162 - { 0x4064, 0x0003}
19163 - },
19164 - }, {
19324 - { 0x00a0, 0x000a },
19325 - { 0x2001, 0x000f },
19326 - { 0x4002, 0x000f },
19333 @@ -160,171 +414,2177 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
19337 - 40000000, { 0x0018, 0x0018, 0x0018 },
19338 - }, {
19339 - 65000000, { 0x0028, 0x0028, 0x0028 },
19340 - }, {
19341 - 66000000, { 0x0038, 0x0038, 0x0038 },
19342 - }, {
19343 - 74250000, { 0x0028, 0x0038, 0x0038 },
19344 - }, {
19345 - 83500000, { 0x0028, 0x0038, 0x0038 },
19346 - }, {
19347 - 146250000, { 0x0038, 0x0038, 0x0038 },
19348 - }, {
19349 - 148500000, { 0x0000, 0x0038, 0x0038 },
19350 - }, {
19357 -static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
19361 - { 148500000, 0x802b, 0x0004, 0x028d},
19364 - { ~0UL, 0x0000, 0x0000, 0x0000}
19370 -static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
19589 - struct device_node *np = hdmi->dev->of_node;
19602 - hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
19603 - if (IS_ERR(hdmi->regmap)) {
19604 - DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,grf\n");
19605 - return PTR_ERR(hdmi->regmap);
19633 - hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
19634 - if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
19635 - hdmi->vpll_clk = NULL;
19636 - } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
19637 - return -EPROBE_DEFER;
19638 - } else if (IS_ERR(hdmi->vpll_clk)) {
19639 - DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
19640 - return PTR_ERR(hdmi->vpll_clk);
19655 - hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
19656 - if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
19657 - hdmi->grf_clk = NULL;
19658 - } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
19659 - return -EPROBE_DEFER;
19660 - } else if (IS_ERR(hdmi->grf_clk)) {
19661 - DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
19662 - return PTR_ERR(hdmi->grf_clk);
19699 + hdmi_bus_fmt_color_depth(hdmi->output_bus_format);
19701 + if (!hdmi_bus_fmt_is_yuv422(hdmi->output_bus_format)) {
19725 + return hdmi->id == *id;
19749 + drm_mode_copy(&mode, &crtc_state->mode);
19750 + if (hdmi->plat_data->split_mode)
19753 + max_lanes = hdmi->max_lanes;
19754 + max_rate_per_lane = hdmi->max_frl_rate_per_lane;
19757 + hdmi->link_cfg.dsc_mode = false;
19758 + hdmi->link_cfg.frl_lanes = max_lanes;
19759 + hdmi->link_cfg.rate_per_lane = max_rate_per_lane;
19762 + dev_info(hdmi->dev, "use tmds mode\n");
19763 + hdmi->link_cfg.frl_mode = false;
19767 + hdmi->link_cfg.frl_mode = true;
19769 + if (!hdmi->dsc_cap.v_1p2)
19772 + max_dsc_lanes = hdmi->dsc_cap.max_lanes;
19774 + hdmi->dsc_cap.max_frl_rate_per_lane;
19777 + !hdmi_bus_fmt_is_yuv420(hdmi->bus_format) &&
19778 + !hdmi_bus_fmt_is_yuv422(hdmi->bus_format)) {
19779 + hdmi->link_cfg.dsc_mode = true;
19780 + hdmi->link_cfg.frl_lanes = max_dsc_lanes;
19781 + hdmi->link_cfg.rate_per_lane = max_dsc_rate_per_lane;
19783 + hdmi->link_cfg.dsc_mode = false;
19784 + hdmi->link_cfg.frl_lanes = max_lanes;
19785 + hdmi->link_cfg.rate_per_lane = max_rate_per_lane;
19832 + int pixel_clock = crtc_state->mode.clock;
19843 + if (hdmi_bus_fmt_is_yuv444(hdmi->output_bus_format) ||
19844 + hdmi_bus_fmt_is_rgb(hdmi->output_bus_format))
19867 + * clock per slice (in MHz) as read from HF-VSDB.
19897 + slice_width = DIV_ROUND_UP(crtc_state->mode.hdisplay, target_slices);
19908 + int hdmi_throughput = hdmi->dsc_cap.clk_per_slice;
19909 + int hdmi_max_slices = hdmi->dsc_cap.max_slices;
19985 + bpp_target_x16 -= bpp_decrement_x16;
19997 + bool hdmi_all_bpp = hdmi->dsc_cap.all_bpp;
19999 + int hdmi_max_chunk_bytes = hdmi->dsc_cap.total_chunk_kbytes * 1024;
20020 + hdmi_bus_fmt_is_rgb(hdmi->output_bus_format) == pps_datas[i].convert_rgb)
20024 + dev_err(hdmi->dev, "can't find pps cfg!\n");
20025 + return -EINVAL;
20028 + memcpy(hdmi->link_cfg.pps_payload, pps_datas[i].raw_pps, 128);
20029 + hdmi->link_cfg.hcactive = DIV_ROUND_UP(slice_width * (bits_per_pixel / 16), 8) *
20045 + unsigned int depth = hdmi_bus_fmt_color_depth(hdmi->output_bus_format);
20050 + hdmi_is_dsc_1_2 = hdmi->dsc_cap.v_1p2;
20055 + slice_height = hdmi_dsc_get_slice_height(crtc_state->mode.vdisplay);
20063 + slice_width = DIV_ROUND_UP(crtc_state->mode.hdisplay, slice_count);
20069 + ret = dw_hdmi_qp_set_link_cfg(hdmi, crtc_state->mode.hdisplay,
20070 + crtc_state->mode.vdisplay, slice_width,
20074 + dev_err(hdmi->dev, "set vdsc cfg failed\n");
20077 + dev_info(hdmi->dev, "dsc_enable\n");
20078 + s->dsc_enable = 1;
20079 + s->dsc_sink_cap.version_major = 1;
20080 + s->dsc_sink_cap.version_minor = 2;
20081 + s->dsc_sink_cap.slice_width = slice_width;
20082 + s->dsc_sink_cap.slice_height = slice_height;
20083 + s->dsc_sink_cap.target_bits_per_pixel_x16 = bits_per_pixel;
20084 + s->dsc_sink_cap.block_pred = 1;
20085 + s->dsc_sink_cap.native_420 = 0;
20087 + memcpy(&s->pps, hdmi->link_cfg.pps_payload, 128);
20098 + dev_err(hdmi->dev, "phy table array number is out of range\n");
20099 + return -E2BIG;
20120 + change = drm_helper_hpd_irq_event(hdmi->drm_dev);
20122 + dev_dbg(hdmi->dev, "hpd stat changed:%d\n", hdmi->hpd_stat);
20123 + dw_hdmi_qp_cec_set_hpd(hdmi->hdmi_qp, hdmi->hpd_stat, change);
20132 + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
20135 + dev_dbg(hdmi->dev, "hpd irq %#x\n", intr_stat);
20137 + if (!hdmi->id)
20143 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
20157 + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
20162 + if (!hdmi->id) {
20178 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
20181 + hdmi->hpd_stat = true;
20184 + hdmi->hpd_stat = false;
20187 + mod_delayed_work(hdmi->workqueue, &hdmi->work, msecs_to_jiffies(msecs));
20189 + if (!hdmi->id) {
20199 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
20206 + hdmi->workqueue = create_workqueue("hpd_queue");
20207 + INIT_DELAYED_WORK(&hdmi->work, repo_hpd_event);
20214 + struct device_node *np = hdmi->dev->of_node;
20216 + hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
20217 + if (IS_ERR(hdmi->regmap)) {
20218 + DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,grf\n");
20219 + return PTR_ERR(hdmi->regmap);
20222 + if (hdmi->is_hdmi_qp) {
20223 + hdmi->vo1_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,vo1_grf");
20224 + if (IS_ERR(hdmi->vo1_regmap)) {
20225 + DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,vo1_grf\n");
20226 + return PTR_ERR(hdmi->vo1_regmap);
20230 + hdmi->phyref_clk = devm_clk_get(hdmi->dev, "vpll");
20231 + if (PTR_ERR(hdmi->phyref_clk) == -ENOENT)
20232 + hdmi->phyref_clk = devm_clk_get(hdmi->dev, "ref");
20234 + if (PTR_ERR(hdmi->phyref_clk) == -ENOENT) {
20235 + hdmi->phyref_clk = NULL;
20236 + } else if (PTR_ERR(hdmi->phyref_clk) == -EPROBE_DEFER) {
20237 + return -EPROBE_DEFER;
20238 + } else if (IS_ERR(hdmi->phyref_clk)) {
20239 + DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
20240 + return PTR_ERR(hdmi->phyref_clk);
20243 + hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
20244 + if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
20245 + hdmi->grf_clk = NULL;
20246 + } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
20247 + return -EPROBE_DEFER;
20248 + } else if (IS_ERR(hdmi->grf_clk)) {
20249 + DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
20250 + return PTR_ERR(hdmi->grf_clk);
20253 + hdmi->hclk_vio = devm_clk_get(hdmi->dev, "hclk_vio");
20254 + if (PTR_ERR(hdmi->hclk_vio) == -ENOENT) {
20255 + hdmi->hclk_vio = NULL;
20256 + } else if (PTR_ERR(hdmi->hclk_vio) == -EPROBE_DEFER) {
20257 + return -EPROBE_DEFER;
20258 + } else if (IS_ERR(hdmi->hclk_vio)) {
20259 + dev_err(hdmi->dev, "failed to get hclk_vio clock\n");
20260 + return PTR_ERR(hdmi->hclk_vio);
20263 + hdmi->hclk_vop = devm_clk_get(hdmi->dev, "hclk");
20264 + if (PTR_ERR(hdmi->hclk_vop) == -ENOENT) {
20265 + hdmi->hclk_vop = NULL;
20266 + } else if (PTR_ERR(hdmi->hclk_vop) == -EPROBE_DEFER) {
20267 + return -EPROBE_DEFER;
20268 + } else if (IS_ERR(hdmi->hclk_vop)) {
20269 + dev_err(hdmi->dev, "failed to get hclk_vop clock\n");
20270 + return PTR_ERR(hdmi->hclk_vop);
20273 + hdmi->aud_clk = devm_clk_get_optional(hdmi->dev, "aud");
20274 + if (IS_ERR(hdmi->aud_clk)) {
20275 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->aud_clk),
20277 + return PTR_ERR(hdmi->aud_clk);
20280 + hdmi->hpd_clk = devm_clk_get_optional(hdmi->dev, "hpd");
20281 + if (IS_ERR(hdmi->hpd_clk)) {
20282 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hpd_clk),
20284 + return PTR_ERR(hdmi->hpd_clk);
20287 + hdmi->hclk_vo1 = devm_clk_get_optional(hdmi->dev, "hclk_vo1");
20288 + if (IS_ERR(hdmi->hclk_vo1)) {
20289 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hclk_vo1),
20291 + return PTR_ERR(hdmi->hclk_vo1);
20294 + hdmi->earc_clk = devm_clk_get_optional(hdmi->dev, "earc");
20295 + if (IS_ERR(hdmi->earc_clk)) {
20296 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->earc_clk),
20298 + return PTR_ERR(hdmi->earc_clk);
20301 + hdmi->hdmitx_ref = devm_clk_get_optional(hdmi->dev, "hdmitx_ref");
20302 + if (IS_ERR(hdmi->hdmitx_ref)) {
20303 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hdmitx_ref),
20305 + return PTR_ERR(hdmi->hdmitx_ref);
20308 + hdmi->pclk = devm_clk_get_optional(hdmi->dev, "pclk");
20309 + if (IS_ERR(hdmi->pclk)) {
20310 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->pclk),
20312 + return PTR_ERR(hdmi->pclk);
20315 + hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable",
20317 + if (IS_ERR(hdmi->enable_gpio)) {
20318 + ret = PTR_ERR(hdmi->enable_gpio);
20319 + dev_err(hdmi->dev, "failed to request enable GPIO: %d\n", ret);
20323 + hdmi->skip_check_420_mode =
20324 + of_property_read_bool(np, "skip-check-420-mode");
20326 + if (of_get_property(np, "rockchip,phy-table", &val)) {
20330 + dev_err(hdmi->dev, "kmalloc phy table failed\n");
20332 + return -ENOMEM;
20335 + of_property_read_u32_array(np, "rockchip,phy-table",
20345 + dev_dbg(hdmi->dev, "use default hdmi phy table\n");
20356 + struct drm_encoder *encoder = connector->encoder;
20358 + struct drm_device *dev = connector->dev;
20359 + struct rockchip_drm_private *priv = dev->dev_private;
20368 + if (mode->clock > INT_MAX / 1000)
20374 + funcs = connector->helper_private;
20375 + if (funcs->atomic_best_encoder)
20376 + encoder = funcs->atomic_best_encoder(connector,
20377 + connector->state);
20379 + encoder = funcs->best_encoder(connector);
20382 + if (!encoder || !encoder->possible_crtcs)
20392 + if (!hdmi->skip_check_420_mode) {
20393 + if (mode->clock > 340000 &&
20394 + connector->display_info.max_tmds_clock < 340000 &&
20395 + (!drm_mode_is_420(&connector->display_info, mode) ||
20396 + !connector->ycbcr_420_allowed))
20399 + if (hdmi->max_tmdsclk <= 340000 && mode->clock > 340000 &&
20400 + !drm_mode_is_420(&connector->display_info, mode))
20404 + if (hdmi->phy) {
20405 + if (hdmi->is_hdmi_qp)
20406 + phy_set_bus_width(hdmi->phy, mode->clock * 10);
20408 + phy_set_bus_width(hdmi->phy, 8);
20416 + drm_for_each_crtc(crtc, connector->dev) {
20419 + priv->crtc_funcs[pipe];
20421 + if (!(encoder->possible_crtcs & drm_crtc_mask(crtc)))
20423 + if (!funcs || !funcs->mode_valid)
20426 + status = funcs->mode_valid(crtc, mode,
20438 + struct drm_crtc *crtc = encoder->crtc;
20439 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
20441 + if (crtc->state->active_changed) {
20442 + if (hdmi->plat_data->split_mode) {
20443 + s->output_if &= ~(VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1);
20445 + if (!hdmi->id)
20446 + s->output_if &= ~VOP_OUTPUT_IF_HDMI1;
20448 + s->output_if &= ~VOP_OUTPUT_IF_HDMI0;
20455 + if (hdmi->phy)
20456 + phy_set_bus_width(hdmi->phy, 8);
20462 + struct drm_crtc *crtc = encoder->crtc;
20467 + if (WARN_ON(!crtc || !crtc->state))
20470 + if (hdmi->phy)
20471 + phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
20473 + clk_set_rate(hdmi->phyref_clk,
20474 + crtc->state->adjusted_mode.crtc_clock * 1000);
20476 + if (hdmi->chip_data->lcdsel_grf_reg < 0)
20479 + mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
20481 + val = hdmi->chip_data->lcdsel_lit;
20483 + val = hdmi->chip_data->lcdsel_big;
20485 + ret = clk_prepare_enable(hdmi->grf_clk);
20487 + DRM_DEV_ERROR(hdmi->dev, "failed to enable grfclk %d\n", ret);
20491 + ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
20493 + DRM_DEV_ERROR(hdmi->dev, "Could not write to GRF: %d\n", ret);
20495 + if (hdmi->chip_data->lcdsel_grf_reg == RK3288_GRF_SOC_CON6) {
20497 + to_rockchip_crtc_state(crtc->state);
20501 + if (s->output_mode == ROCKCHIP_OUT_MODE_YUV420)
20506 + regmap_write(hdmi->regmap, RK3288_GRF_SOC_CON16, val);
20509 + clk_disable_unprepare(hdmi->grf_clk);
20510 + DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
20519 + if (!hdmi->id)
20524 + if (!hdmi->link_cfg.frl_mode) {
20527 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON4, val);
20529 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON7, val);
20533 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20535 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20542 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON4, val);
20544 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON7, val);
20546 + if (hdmi->link_cfg.dsc_mode) {
20550 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20552 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20556 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20558 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20581 + dev_err(hdmi->dev, "can't set correct color format\n");
20585 + if (hdmi->link_cfg.dsc_mode)
20593 + if (!hdmi->id)
20594 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20596 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20605 + color_depth = hdmi_bus_fmt_color_depth(hdmi->bus_format);
20606 + rk3588_set_color_format(hdmi, hdmi->bus_format, color_depth);
20620 + struct drm_display_info *info = &conn_state->connector->display_info;
20628 + u32 max_tmds_clock = info->max_tmds_clock;
20631 + drm_mode_copy(&mode, &crtc_state->mode);
20633 + if (hdmi->plat_data->split_mode) {
20640 + if (!hdmi->is_hdmi_qp)
20641 + sink_is_hdmi = dw_hdmi_get_output_whether_hdmi(hdmi->hdmi);
20645 + switch (hdmi->hdmi_output) {
20647 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
20649 + else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20651 + else if (conn_state->connector->ycbcr_420_allowed &&
20653 + (pixclock >= 594000 && !hdmi->is_hdmi_qp))
20657 + if (conn_state->connector->ycbcr_420_allowed &&
20660 + else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20662 + else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
20666 + if (conn_state->connector->ycbcr_420_allowed &&
20671 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20675 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
20684 + info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
20687 + info->edid_hdmi_dc_modes &
20693 + info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
20696 + if (hdmi->colordepth > 8 && support_dc)
20707 + if (conn_state->hdr_output_metadata) {
20709 + conn_state->hdr_output_metadata->data;
20710 + output_eotf = hdr_metadata->hdmi_metadata_type1.eotf;
20716 + hdmi->colorimetry = conn_state->colorspace;
20719 + conn_state->connector->hdr_sink_metadata.hdmi_type1.eotf &
20720 + BIT(*eotf)) || ((hdmi->colorimetry >= DRM_MODE_COLORIMETRY_BT2020_CYCC) &&
20721 + (hdmi->colorimetry <= DRM_MODE_COLORIMETRY_BT2020_YCC)))
20733 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20735 + if (hdmi->is_hdmi_qp) {
20736 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB420) {
20765 + max_tmds_clock = min(max_tmds_clock, hdmi->max_tmdsclk);
20767 + if ((tmdsclock > max_tmds_clock) && !hdmi->is_hdmi_qp) {
20780 + if (mode.clock >= 340000 && hdmi->is_hdmi_qp)
20794 + !hdmi->unsupported_yuv_input)
20800 + !hdmi->unsupported_yuv_input)
20811 + hdmi->bus_format = *bus_format;
20815 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY12_1X24;
20817 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY10_1X20;
20819 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY8_1X16;
20821 + hdmi->output_bus_format = *bus_format;
20829 + struct drm_crtc_state *crtc_state = conn_state->crtc->state;
20832 + unsigned long output_bus_format = hdmi->output_bus_format;
20833 + unsigned long enc_out_encoding = hdmi->enc_out_encoding;
20840 + &hdmi->enc_out_encoding, &eotf);
20842 + if (output_bus_format != hdmi->output_bus_format ||
20843 + enc_out_encoding != hdmi->enc_out_encoding)
20868 + drm_mode_copy(&mode, &crtc_state->mode);
20870 + hdmi->vp_id = s->vp_id;
20871 + if (hdmi->plat_data->split_mode)
20877 + &hdmi->enc_out_encoding, &s->eotf);
20879 + s->bus_format = bus_format;
20880 + if (hdmi->is_hdmi_qp) {
20882 + tmdsclk = hdmi_get_tmdsclock(hdmi, crtc_state->mode.clock);
20883 + if (hdmi_bus_fmt_is_yuv420(hdmi->output_bus_format))
20887 + if (hdmi->link_cfg.frl_mode) {
20888 + gpiod_set_value(hdmi->enable_gpio, 0);
20890 + if (hdmi->link_cfg.rate_per_lane >= 10) {
20891 + hdmi->link_cfg.frl_lanes = 4;
20892 + hdmi->link_cfg.rate_per_lane = 10;
20894 + bus_width = hdmi->link_cfg.frl_lanes *
20895 + hdmi->link_cfg.rate_per_lane * 1000000;
20903 + gpiod_set_value(hdmi->enable_gpio, 1);
20905 + if (hdmi_bus_fmt_is_yuv420(hdmi->output_bus_format))
20913 + hdmi->phy_bus_width = bus_width;
20915 + if (hdmi->phy)
20916 + phy_set_bus_width(hdmi->phy, bus_width);
20918 + s->output_type = DRM_MODE_CONNECTOR_HDMIA;
20919 + s->tv_state = &conn_state->tv;
20921 + if (hdmi->plat_data->split_mode) {
20922 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
20923 + if (hdmi->plat_data->right && hdmi->id)
20924 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
20925 + s->output_if |= VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1;
20927 + if (!hdmi->id)
20928 + s->output_if |= VOP_OUTPUT_IF_HDMI0;
20930 + s->output_if |= VOP_OUTPUT_IF_HDMI1;
20933 + s->output_mode = output_mode;
20934 + hdmi->bus_format = s->bus_format;
20936 + if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_BT2020)
20937 + s->color_space = V4L2_COLORSPACE_BT2020;
20939 + s->color_space = V4L2_COLORSPACE_DEFAULT;
20940 + else if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_709)
20941 + s->color_space = V4L2_COLORSPACE_REC709;
20943 + s->color_space = V4L2_COLORSPACE_SMPTE170M;
20945 + if (hdmi->plat_data->split_mode && !secondary) {
20946 + hdmi = rockchip_hdmi_find_by_id(hdmi->dev->driver, !hdmi->id);
20960 + return hdmi->bus_format;
20968 + return hdmi->output_bus_format;
20976 + return hdmi->enc_out_encoding;
20984 + return hdmi->enc_out_encoding;
20992 + return hdmi->hdmi_quant_range;
21000 + return hdmi->hdr_panel_metadata_property;
21008 + return hdmi->hdr_panel_blob_ptr;
21017 + if (hdmi->color_changed)
21019 + hdmi->color_changed = 0;
21029 + return -EINVAL;
21040 + return -EINVAL;
21042 + return rockchip_drm_parse_cea_ext(&hdmi->dsc_cap,
21043 + &hdmi->max_frl_rate_per_lane,
21044 + &hdmi->max_lanes, edid);
21053 + struct next_hdr_sink_data *sink_data = &hdmi->next_hdr_data;
21055 + struct drm_property *property = hdmi->next_hdr_sink_data_property;
21056 + struct drm_property_blob *blob = hdmi->hdr_panel_blob_ptr;
21059 + return -EINVAL;
21063 + ret = drm_property_replace_global_blob(connector->dev, &blob, size, sink_data,
21064 + &connector->base, property);
21074 + return &hdmi->link_cfg;
21084 + snprintf(clk_name, sizeof(clk_name), "dclk_vp%d", hdmi->vp_id);
21086 + dclk = devm_clk_get(hdmi->dev, clk_name);
21088 + DRM_DEV_ERROR(hdmi->dev, "failed to get %s\n", clk_name);
21095 + DRM_DEV_ERROR(hdmi->dev, "failed to enable dclk for video port%d - %d\n",
21096 + hdmi->vp_id, ret);
21144 + struct rockchip_drm_private *private = connector->dev->dev_private;
21148 + hdmi->hdmi_output = RK_IF_FORMAT_RGB;
21149 + hdmi->colordepth = 10;
21152 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR444;
21153 + hdmi->colordepth = 8;
21156 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR444;
21157 + hdmi->colordepth = 10;
21160 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR422;
21161 + hdmi->colordepth = 10;
21164 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR422;
21165 + hdmi->colordepth = 8;
21168 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR420;
21169 + hdmi->colordepth = 8;
21172 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR420;
21173 + hdmi->colordepth = 10;
21176 + hdmi->hdmi_output = RK_IF_FORMAT_RGB;
21177 + hdmi->colordepth = 8;
21180 + hdmi->bus_format = color;
21182 + if (hdmi->hdmi_output == RK_IF_FORMAT_YCBCR422) {
21183 + if (hdmi->colordepth == 12)
21184 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY12_1X24;
21185 + else if (hdmi->colordepth == 10)
21186 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY10_1X20;
21188 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY8_1X16;
21190 + hdmi->output_bus_format = hdmi->bus_format;
21194 + if (!hdmi->color_depth_property && !hdmi->unsupported_deep_color) {
21195 + prop = drm_property_create_enum(connector->dev, 0,
21200 + hdmi->color_depth_property = prop;
21201 + drm_object_attach_property(&connector->base, prop, 0);
21205 + prop = drm_property_create_enum(connector->dev, 0, RK_IF_PROP_COLOR_FORMAT,
21209 + hdmi->hdmi_output_property = prop;
21210 + drm_object_attach_property(&connector->base, prop, 0);
21213 + prop = drm_property_create_range(connector->dev, 0,
21217 + hdmi->colordepth_capacity = prop;
21218 + drm_object_attach_property(&connector->base, prop, 0);
21221 + prop = drm_property_create_range(connector->dev, 0,
21225 + hdmi->outputmode_capacity = prop;
21226 + drm_object_attach_property(&connector->base, prop, 0);
21229 + prop = drm_property_create(connector->dev,
21234 + hdmi->hdr_panel_metadata_property = prop;
21235 + drm_object_attach_property(&connector->base, prop, 0);
21238 + prop = drm_property_create(connector->dev,
21243 + hdmi->next_hdr_sink_data_property = prop;
21244 + drm_object_attach_property(&connector->base, prop, 0);
21247 + prop = drm_property_create_bool(connector->dev, DRM_MODE_PROP_IMMUTABLE,
21250 + hdmi->user_split_mode_prop = prop;
21251 + drm_object_attach_property(&connector->base, prop,
21252 + hdmi->user_split_mode ? 1 : 0);
21255 + if (!hdmi->is_hdmi_qp) {
21256 + prop = drm_property_create_enum(connector->dev, 0,
21261 + hdmi->output_hdmi_dvi = prop;
21262 + drm_object_attach_property(&connector->base, prop, 0);
21265 + prop = drm_property_create_enum(connector->dev, 0,
21270 + hdmi->output_type_capacity = prop;
21271 + drm_object_attach_property(&connector->base, prop, 0);
21274 + prop = drm_property_create_enum(connector->dev, 0,
21279 + hdmi->quant_range = prop;
21280 + drm_object_attach_property(&connector->base, prop, 0);
21284 + prop = connector->dev->mode_config.hdr_output_metadata_property;
21285 + if (version >= 0x211a || hdmi->is_hdmi_qp)
21286 + drm_object_attach_property(&connector->base, prop, 0);
21289 + drm_object_attach_property(&connector->base,
21290 + connector->colorspace_property, 0);
21291 + drm_object_attach_property(&connector->base, private->connector_id_prop, hdmi->id);
21300 + if (hdmi->color_depth_property) {
21301 + drm_property_destroy(connector->dev,
21302 + hdmi->color_depth_property);
21303 + hdmi->color_depth_property = NULL;
21306 + if (hdmi->hdmi_output_property) {
21307 + drm_property_destroy(connector->dev,
21308 + hdmi->hdmi_output_property);
21309 + hdmi->hdmi_output_property = NULL;
21312 + if (hdmi->colordepth_capacity) {
21313 + drm_property_destroy(connector->dev,
21314 + hdmi->colordepth_capacity);
21315 + hdmi->colordepth_capacity = NULL;
21318 + if (hdmi->outputmode_capacity) {
21319 + drm_property_destroy(connector->dev,
21320 + hdmi->outputmode_capacity);
21321 + hdmi->outputmode_capacity = NULL;
21324 + if (hdmi->quant_range) {
21325 + drm_property_destroy(connector->dev,
21326 + hdmi->quant_range);
21327 + hdmi->quant_range = NULL;
21330 + if (hdmi->hdr_panel_metadata_property) {
21331 + drm_property_destroy(connector->dev,
21332 + hdmi->hdr_panel_metadata_property);
21333 + hdmi->hdr_panel_metadata_property = NULL;
21336 + if (hdmi->next_hdr_sink_data_property) {
21337 + drm_property_destroy(connector->dev,
21338 + hdmi->next_hdr_sink_data_property);
21339 + hdmi->next_hdr_sink_data_property = NULL;
21342 + if (hdmi->output_hdmi_dvi) {
21343 + drm_property_destroy(connector->dev,
21344 + hdmi->output_hdmi_dvi);
21345 + hdmi->output_hdmi_dvi = NULL;
21348 + if (hdmi->output_type_capacity) {
21349 + drm_property_destroy(connector->dev,
21350 + hdmi->output_type_capacity);
21351 + hdmi->output_type_capacity = NULL;
21354 - return 0;
21355 + if (hdmi->user_split_mode_prop) {
21356 + drm_property_destroy(connector->dev,
21357 + hdmi->user_split_mode_prop);
21358 + hdmi->user_split_mode_prop = NULL;
21362 -static enum drm_mode_status
21363 -dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
21364 - const struct drm_display_info *info,
21365 - const struct drm_display_mode *mode)
21373 - const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
21374 - int pclk = mode->clock * 1000;
21375 - bool valid = false;
21376 - int i;
21377 -
21378 - for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
21379 - if (pclk == mpll_cfg[i].mpixelclock) {
21380 - valid = true;
21381 - break;
21382 - }
21384 + struct drm_mode_config *config = &connector->dev->mode_config;
21386 + if (property == hdmi->color_depth_property) {
21387 + hdmi->colordepth = val;
21388 + /* If hdmi is disconnected, state->crtc is null */
21389 + if (!state->crtc)
21392 + hdmi->color_changed++;
21394 + } else if (property == hdmi->hdmi_output_property) {
21395 + hdmi->hdmi_output = val;
21396 + if (!state->crtc)
21399 + hdmi->color_changed++;
21401 + } else if (property == hdmi->quant_range) {
21402 + u64 quant_range = hdmi->hdmi_quant_range;
21404 + hdmi->hdmi_quant_range = val;
21405 + if (quant_range != hdmi->hdmi_quant_range)
21406 + dw_hdmi_set_quant_range(hdmi->hdmi);
21408 + } else if (property == config->hdr_output_metadata_property) {
21410 + } else if (property == hdmi->output_hdmi_dvi) {
21411 + if (hdmi->force_output != val)
21412 + hdmi->color_changed++;
21413 + hdmi->force_output = val;
21414 + dw_hdmi_set_output_type(hdmi->hdmi, val);
21416 + } else if (property == hdmi->colordepth_capacity) {
21418 + } else if (property == hdmi->outputmode_capacity) {
21420 + } else if (property == hdmi->output_type_capacity) {
21424 - return (valid) ? MODE_OK : MODE_BAD;
21425 -}
21427 + property->base.id, property->name);
21429 -static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
21430 -{
21431 + return -EINVAL;
21434 -static bool
21435 -dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
21436 - const struct drm_display_mode *mode,
21437 - struct drm_display_mode *adj_mode)
21445 - return true;
21446 -}
21448 + struct drm_display_info *info = &connector->display_info;
21449 + struct drm_mode_config *config = &connector->dev->mode_config;
21451 + if (property == hdmi->color_depth_property) {
21452 + *val = hdmi->colordepth;
21454 + } else if (property == hdmi->hdmi_output_property) {
21455 + *val = hdmi->hdmi_output;
21457 + } else if (property == hdmi->colordepth_capacity) {
21460 + if (hdmi->unsupported_deep_color)
21462 + if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
21464 + if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36)
21466 + if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_48)
21468 + if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
21470 + if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
21472 + if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
21475 + } else if (property == hdmi->outputmode_capacity) {
21477 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
21479 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
21481 + if (connector->ycbcr_420_allowed &&
21482 + info->color_formats & DRM_COLOR_FORMAT_YCRCB420)
21485 + } else if (property == hdmi->quant_range) {
21486 + *val = hdmi->hdmi_quant_range;
21488 + } else if (property == config->hdr_output_metadata_property) {
21489 + *val = state->hdr_output_metadata ?
21490 + state->hdr_output_metadata->base.id : 0;
21492 + } else if (property == hdmi->output_hdmi_dvi) {
21493 + *val = hdmi->force_output;
21495 + } else if (property == hdmi->output_type_capacity) {
21496 + *val = dw_hdmi_get_output_type_cap(hdmi->hdmi);
21498 + } else if (property == hdmi->user_split_mode_prop) {
21499 + *val = hdmi->user_split_mode;
21503 -static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
21504 - struct drm_display_mode *mode,
21505 - struct drm_display_mode *adj_mode)
21506 -{
21507 - struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
21509 + property->base.id, property->name);
21511 - clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
21512 + return -EINVAL;
21515 -static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
21528 - u32 val;
21529 - int ret;
21533 - if (hdmi->chip_data->lcdsel_grf_reg < 0)
21534 + if (!encoder->crtc)
21536 + crtc = encoder->crtc;
21538 - ret = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
21539 - if (ret)
21540 - val = hdmi->chip_data->lcdsel_lit;
21541 - else
21542 - val = hdmi->chip_data->lcdsel_big;
21543 -
21544 - ret = clk_prepare_enable(hdmi->grf_clk);
21545 - if (ret < 0) {
21546 - DRM_DEV_ERROR(hdmi->dev, "failed to enable grfclk %d\n", ret);
21547 + if (!crtc->state)
21549 - }
21550 + s = to_rockchip_crtc_state(crtc->state);
21552 - ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
21553 - if (ret != 0)
21554 - DRM_DEV_ERROR(hdmi->dev, "Could not write to GRF: %d\n", ret);
21555 -
21556 - clk_disable_unprepare(hdmi->grf_clk);
21557 - DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
21558 - ret ? "LIT" : "BIG");
21559 -}
21563 -static int
21564 -dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
21565 - struct drm_crtc_state *crtc_state,
21566 - struct drm_connector_state *conn_state)
21567 -{
21568 - struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
21569 + if (hdmi->is_hdmi_qp) {
21570 + s->dsc_enable = 0;
21571 + if (hdmi->link_cfg.dsc_mode)
21572 + dw_hdmi_qp_dsc_configure(hdmi, s, crtc->state);
21574 - s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
21575 - s->output_type = DRM_MODE_CONNECTOR_HDMIA;
21576 + phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
21579 - return 0;
21580 + clk_set_rate(hdmi->phyref_clk, adj->crtc_clock * 1000);
21584 - .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
21585 - .mode_set = dw_hdmi_rockchip_encoder_mode_set,
21592 -static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
21593 - const struct drm_display_info *display,
21594 - const struct drm_display_mode *mode)
21600 - return phy_power_on(hdmi->phy);
21601 + while (hdmi->phy->power_count > 0)
21602 + phy_power_off(hdmi->phy);
21605 -static void dw_hdmi_rockchip_genphy_disable(struct dw_hdmi *dw_hdmi, void *data)
21613 - phy_power_off(hdmi->phy);
21616 + return phy_power_on(hdmi->phy);
21620 @@ -391,6 +2651,90 @@ static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
21629 + while (hdmi->phy->power_count > 0)
21630 + phy_power_off(hdmi->phy);
21640 + return phy_power_on(hdmi->phy);
21650 + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val);
21652 + if (!hdmi->id) {
21654 + hdmi->hpd_stat = true;
21657 + hdmi->hpd_stat = false;
21662 + hdmi->hpd_stat = true;
21665 + hdmi->hpd_stat = false;
21678 + if (!hdmi->id) {
21688 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
21696 + if (!hdmi->phy)
21701 + hdmi->phy_bus_width |= mode_mask;
21703 + hdmi->phy_bus_width &= ~mode_mask;
21705 + phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
21711 @@ -412,6 +2756,8 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
21720 @@ -423,9 +2769,13 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = {
21734 @@ -450,6 +2800,24 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
21743 + .lcdsel_grf_reg = -1,
21759 @@ -461,10 +2829,52 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = {
21772 + .lcdsel_grf_reg = -1,
21796 + .lcdsel_grf_reg = -1,
21812 @@ -477,9 +2887,19 @@ static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
21813 { .compatible = "rockchip,rk3328-dw-hdmi",
21817 + .compatible = "rockchip,rk3368-dw-hdmi",
21820 { .compatible = "rockchip,rk3399-dw-hdmi",
21823 + { .compatible = "rockchip,rk3568-dw-hdmi",
21826 + { .compatible = "rockchip,rk3588-dw-hdmi",
21832 @@ -488,40 +2908,108 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
21836 - struct dw_hdmi_plat_data *plat_data;
21837 - const struct of_device_id *match;
21845 if (!pdev->dev.of_node)
21846 return -ENODEV;
21848 - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
21851 return -ENOMEM;
21853 - match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
21854 - plat_data = devm_kmemdup(&pdev->dev, match->data,
21855 - sizeof(*plat_data), GFP_KERNEL);
21856 - if (!plat_data)
21857 - return -ENOMEM;
21858 + plat_data = hdmi->plat_data;
21859 + hdmi->drm_dev = drm;
21861 - hdmi->dev = &pdev->dev;
21862 - hdmi->chip_data = plat_data->phy_data;
21863 plat_data->phy_data = hdmi;
21864 - encoder = &hdmi->encoder;
21865 + plat_data->get_input_bus_format =
21867 + plat_data->get_output_bus_format =
21869 + plat_data->get_enc_in_encoding =
21871 + plat_data->get_enc_out_encoding =
21873 + plat_data->get_quant_range =
21875 + plat_data->get_hdr_property =
21877 + plat_data->get_hdr_blob =
21879 + plat_data->get_color_changed =
21881 + plat_data->get_yuv422_format =
21883 + plat_data->get_edid_dsc_info =
21885 + plat_data->get_next_hdr_data =
21887 + plat_data->get_link_cfg = dw_hdmi_rockchip_get_link_cfg;
21888 + plat_data->set_grf_cfg = rk3588_set_grf_cfg;
21889 + plat_data->convert_to_split_mode = drm_mode_convert_to_split_mode;
21890 + plat_data->convert_to_origin_mode = drm_mode_convert_to_origin_mode;
21891 + plat_data->dclk_set = dw_hdmi_dclk_set;
21893 + plat_data->property_ops = &dw_hdmi_rockchip_property_ops;
21896 + if (hdmi->chip_data->split_mode && (hdmi->hdmi_num == 2)) {
21898 + rockchip_hdmi_find_by_id(dev->driver, !hdmi->id);
21901 + return -EPROBE_DEFER;
21905 + * last bind hdmi in split mode, or hdmi->hdmi_qp will not be initialized
21906 + * and plat_data->left/right will be null pointer. we must check if split
21909 + if (device_property_read_bool(dev, "split-mode") ||
21910 + device_property_read_bool(secondary->dev, "split-mode")) {
21911 + plat_data->split_mode = true;
21912 + secondary->plat_data->split_mode = true;
21913 + if (!secondary->plat_data->first_screen)
21914 + plat_data->first_screen = true;
21917 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
21918 - /*
21919 - * If we failed to find the CRTC(s) which this encoder is
21920 - * supposed to be connected to, it's because the CRTC has
21921 - * not been registered yet. Defer probing, and hope that
21922 - * the required CRTC is added later.
21923 - */
21924 - if (encoder->possible_crtcs == 0)
21925 - return -EPROBE_DEFER;
21926 + if (device_property_read_bool(dev, "user-split-mode") ||
21927 + device_property_read_bool(secondary->dev, "user-split-mode")) {
21928 + hdmi->user_split_mode = true;
21929 + secondary->user_split_mode = true;
21933 + if (!plat_data->first_screen) {
21934 + encoder = &hdmi->encoder;
21935 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm, dev->of_node);
21942 + if (encoder->possible_crtcs == 0)
21943 + return -EPROBE_DEFER;
21949 + if (!plat_data->max_tmdsclk)
21950 + hdmi->max_tmdsclk = 594000;
21952 + hdmi->max_tmdsclk = plat_data->max_tmdsclk;
21954 + hdmi->is_hdmi_qp = plat_data->is_hdmi_qp;
21956 + hdmi->unsupported_yuv_input = plat_data->unsupported_yuv_input;
21957 + hdmi->unsupported_deep_color = plat_data->unsupported_deep_color;
21961 @@ -529,27 +3017,167 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
21965 - ret = clk_prepare_enable(hdmi->vpll_clk);
21966 + ret = clk_prepare_enable(hdmi->aud_clk);
21968 + dev_err(hdmi->dev, "Failed to enable HDMI aud_clk: %d\n", ret);
21972 + ret = clk_prepare_enable(hdmi->hpd_clk);
21974 + dev_err(hdmi->dev, "Failed to enable HDMI hpd_clk: %d\n", ret);
21978 + ret = clk_prepare_enable(hdmi->hclk_vo1);
21980 + dev_err(hdmi->dev, "Failed to enable HDMI hclk_vo1: %d\n", ret);
21984 + ret = clk_prepare_enable(hdmi->earc_clk);
21986 + dev_err(hdmi->dev, "Failed to enable HDMI earc_clk: %d\n", ret);
21990 + ret = clk_prepare_enable(hdmi->hdmitx_ref);
21992 + dev_err(hdmi->dev, "Failed to enable HDMI hdmitx_ref: %d\n",
21997 + ret = clk_prepare_enable(hdmi->pclk);
21999 + dev_err(hdmi->dev, "Failed to enable HDMI pclk: %d\n", ret);
22003 + if (hdmi->chip_data->ddc_en_reg == RK3568_GRF_VO_CON1) {
22004 + regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
22011 + if (hdmi->is_hdmi_qp) {
22012 + if (!hdmi->id) {
22017 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
22021 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
22025 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
22031 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
22035 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
22039 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
22044 + ret = clk_prepare_enable(hdmi->phyref_clk);
22046 DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
22051 + ret = clk_prepare_enable(hdmi->hclk_vio);
22053 + dev_err(hdmi->dev, "Failed to enable HDMI hclk_vio: %d\n",
22058 + ret = clk_prepare_enable(hdmi->hclk_vop);
22060 + dev_err(hdmi->dev, "Failed to enable HDMI hclk_vop: %d\n",
22065 + if (!hdmi->id)
22069 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
22071 + if (hdmi->is_hdmi_qp) {
22072 + hdmi->hpd_irq = platform_get_irq(pdev, 4);
22073 + if (hdmi->hpd_irq < 0)
22074 + return hdmi->hpd_irq;
22076 + ret = devm_request_threaded_irq(hdmi->dev, hdmi->hpd_irq,
22079 + IRQF_SHARED, "dw-hdmi-qp-hpd",
22085 hdmi->phy = devm_phy_optional_get(dev, "hdmi");
22086 if (IS_ERR(hdmi->phy)) {
22087 - ret = PTR_ERR(hdmi->phy);
22088 - if (ret != -EPROBE_DEFER)
22089 - DRM_DEV_ERROR(hdmi->dev, "failed to get phy\n");
22090 - return ret;
22091 + hdmi->phy = devm_phy_optional_get(dev, "hdmi_phy");
22092 + if (IS_ERR(hdmi->phy)) {
22093 + ret = PTR_ERR(hdmi->phy);
22094 + if (ret != -EPROBE_DEFER)
22095 + DRM_DEV_ERROR(hdmi->dev, "failed to get phy\n");
22100 - drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
22101 - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
22102 + if (hdmi->is_hdmi_qp) {
22103 + hdmi->hdmi_qp = dw_hdmi_qp_bind(pdev, &hdmi->encoder, plat_data);
22105 - platform_set_drvdata(pdev, hdmi);
22106 + if (IS_ERR(hdmi->hdmi_qp)) {
22107 + ret = PTR_ERR(hdmi->hdmi_qp);
22108 + drm_encoder_cleanup(&hdmi->encoder);
22111 + if (plat_data->connector) {
22112 + hdmi->sub_dev.connector = plat_data->connector;
22113 + hdmi->sub_dev.of_node = dev->of_node;
22114 + rockchip_drm_register_sub_dev(&hdmi->sub_dev);
22117 + if (plat_data->split_mode) {
22119 + rockchip_hdmi_find_by_id(dev->driver, !hdmi->id);
22121 + if (device_property_read_bool(dev, "split-mode")) {
22122 + plat_data->right = secondary->hdmi_qp;
22123 + secondary->plat_data->left = hdmi->hdmi_qp;
22125 + plat_data->left = secondary->hdmi_qp;
22126 + secondary->plat_data->right = hdmi->hdmi_qp;
22133 - hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
22134 + hdmi->hdmi = dw_hdmi_bind(pdev, &hdmi->encoder, plat_data);
22138 @@ -557,8 +3185,21 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
22140 if (IS_ERR(hdmi->hdmi)) {
22141 ret = PTR_ERR(hdmi->hdmi);
22142 - drm_encoder_cleanup(encoder);
22143 - clk_disable_unprepare(hdmi->vpll_clk);
22144 + drm_encoder_cleanup(&hdmi->encoder);
22145 + clk_disable_unprepare(hdmi->aud_clk);
22146 + clk_disable_unprepare(hdmi->phyref_clk);
22147 + clk_disable_unprepare(hdmi->hclk_vop);
22148 + clk_disable_unprepare(hdmi->hpd_clk);
22149 + clk_disable_unprepare(hdmi->hclk_vo1);
22150 + clk_disable_unprepare(hdmi->earc_clk);
22151 + clk_disable_unprepare(hdmi->hdmitx_ref);
22152 + clk_disable_unprepare(hdmi->pclk);
22155 + if (plat_data->connector) {
22156 + hdmi->sub_dev.connector = plat_data->connector;
22157 + hdmi->sub_dev.of_node = dev->of_node;
22158 + rockchip_drm_register_sub_dev(&hdmi->sub_dev);
22162 @@ -569,8 +3210,27 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
22166 - dw_hdmi_unbind(hdmi->hdmi);
22167 - clk_disable_unprepare(hdmi->vpll_clk);
22168 + if (hdmi->is_hdmi_qp) {
22169 + cancel_delayed_work(&hdmi->work);
22170 + flush_workqueue(hdmi->workqueue);
22171 + destroy_workqueue(hdmi->workqueue);
22174 + if (hdmi->sub_dev.connector)
22175 + rockchip_drm_unregister_sub_dev(&hdmi->sub_dev);
22177 + if (hdmi->is_hdmi_qp)
22178 + dw_hdmi_qp_unbind(hdmi->hdmi_qp);
22180 + dw_hdmi_unbind(hdmi->hdmi);
22181 + clk_disable_unprepare(hdmi->aud_clk);
22182 + clk_disable_unprepare(hdmi->phyref_clk);
22183 + clk_disable_unprepare(hdmi->hclk_vop);
22184 + clk_disable_unprepare(hdmi->hpd_clk);
22185 + clk_disable_unprepare(hdmi->hclk_vo1);
22186 + clk_disable_unprepare(hdmi->earc_clk);
22187 + clk_disable_unprepare(hdmi->hdmitx_ref);
22188 + clk_disable_unprepare(hdmi->pclk);
22192 @@ -580,32 +3240,132 @@ static const struct component_ops dw_hdmi_rockchip_ops = {
22201 + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
22203 + return -ENOMEM;
22205 + id = of_alias_get_id(pdev->dev.of_node, "hdmi");
22209 + hdmi->hdmi_num++;
22210 + hdmi->id = id;
22211 + hdmi->dev = &pdev->dev;
22213 + match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
22214 + plat_data = devm_kmemdup(&pdev->dev, match->data,
22217 + return -ENOMEM;
22219 + hdmi->plat_data = plat_data;
22220 + hdmi->chip_data = plat_data->phy_data;
22223 + pm_runtime_enable(&pdev->dev);
22224 + pm_runtime_get_sync(&pdev->dev);
22226 return component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
22231 + struct rockchip_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
22236 + if (hdmi->is_hdmi_qp) {
22237 + cancel_delayed_work(&hdmi->work);
22238 + flush_workqueue(hdmi->workqueue);
22239 + dw_hdmi_qp_suspend(hdmi->dev, hdmi->hdmi_qp);
22241 + dw_hdmi_suspend(hdmi->hdmi);
22243 + pm_runtime_put_sync(&pdev->dev);
22248 component_del(&pdev->dev, &dw_hdmi_rockchip_ops);
22249 + pm_runtime_disable(&pdev->dev);
22258 + if (hdmi->is_hdmi_qp)
22259 + dw_hdmi_qp_suspend(dev, hdmi->hdmi_qp);
22261 + dw_hdmi_suspend(hdmi->hdmi);
22267 -static int __maybe_unused dw_hdmi_rockchip_resume(struct device *dev)
22273 + if (hdmi->is_hdmi_qp) {
22274 + if (!hdmi->id) {
22279 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
22283 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
22287 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
22293 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
22297 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
22301 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
22304 - dw_hdmi_resume(hdmi->hdmi);
22305 + dw_hdmi_qp_resume(dev, hdmi->hdmi_qp);
22306 + drm_helper_hpd_irq_event(hdmi->drm_dev);
22308 + dw_hdmi_resume(hdmi->hdmi);
22316 - SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_rockchip_resume)
22326 .name = "dwhdmi-rockchip",
22328 diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
22330 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c
22332 @@ -602,7 +602,7 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
22333 struct drm_encoder *encoder = &hdmi->encoder;
22334 struct device *dev = hdmi->dev;
22336 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
22337 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm, dev->of_node);
22341 diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
22343 --- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
22345 @@ -542,7 +542,7 @@ rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi)
22346 struct device *dev = hdmi->dev;
22348 encoder->possible_crtcs =
22349 - drm_of_find_possible_crtcs(drm, dev->of_node);
22350 + rockchip_drm_of_find_possible_crtcs(drm, dev->of_node);
22354 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_dr…
22356 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
22358 @@ -6,17 +6,24 @@
22362 +#include <linux/dma-buf-cache.h>
22363 #include <linux/dma-mapping.h>
22364 #include <linux/dma-iommu.h>
22383 @@ -27,16 +34,856 @@
22394 -#define DRIVER_MAJOR 1
22422 + return -ENODEV;
22425 + return -EINVAL;
22427 + priv = crtc->dev->dev_private;
22430 + if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->wait_vact_end)
22431 + ret = priv->crtc_funcs[pipe]->wait_vact_end(crtc, mstimeout);
22441 + hactive = mode->hdisplay;
22442 + hfp = mode->hsync_start - mode->hdisplay;
22443 + hsync = mode->hsync_end - mode->hsync_start;
22444 + hbp = mode->htotal - mode->hsync_end;
22446 + mode->clock *= 2;
22447 + mode->hdisplay = hactive * 2;
22448 + mode->hsync_start = mode->hdisplay + hfp * 2;
22449 + mode->hsync_end = mode->hsync_start + hsync * 2;
22450 + mode->htotal = mode->hsync_end + hbp * 2;
22459 + hactive = mode->hdisplay;
22460 + hfp = mode->hsync_start - mode->hdisplay;
22461 + hsync = mode->hsync_end - mode->hsync_start;
22462 + hbp = mode->htotal - mode->hsync_end;
22464 + mode->clock /= 2;
22465 + mode->hdisplay = hactive / 2;
22466 + mode->hsync_start = mode->hdisplay + hfp / 2;
22467 + mode->hsync_end = mode->hsync_start + hsync / 2;
22468 + mode->htotal = mode->hsync_end + hbp / 2;
22473 + * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
22477 + * driver / device. An example of this is some USB Type-C setups where the hardware
22478 + * muxes the DisplayPort data and aux-lines but does not pass the altmode HPD
22481 + * This function can be used to report these out-of-band events after obtaining
22488 + if (!connector_fwnode || !connector_fwnode->dev)
22491 + sub_dev = rockchip_drm_get_sub_dev(dev_of_node(connector_fwnode->dev));
22493 + if (sub_dev && sub_dev->connector && sub_dev->oob_hotplug_event)
22494 + sub_dev->oob_hotplug_event(sub_dev->connector);
22501 + if (info->cpp[0])
22502 + return info->cpp[0] * 8;
22504 + switch (info->format) {
22521 + * rockchip_drm_of_find_possible_crtcs - find the possible CRTCs for an active
22563 + list_add_tail(&sub_dev->list, &rockchip_drm_sub_dev_list);
22571 + list_del(&sub_dev->list);
22583 + if (sub_dev->of_node == node) {
22601 + if (sub_dev->connector->encoder) {
22602 + connector_type = sub_dev->connector->connector_type;
22614 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
22617 + if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->te_handler)
22618 + priv->crtc_funcs[pipe]->te_handler(crtc);
22623 + /* 4 - 1280x720@60Hz 16:9 */
22628 + /* 16 - 1920x1080@60Hz 16:9 */
22633 + /* 31 - 1920x1080@50Hz 16:9 */
22638 + /* 19 - 1280x720@50Hz 16:9 */
22643 + /* 0x10 - 1024x768@60Hz */
22647 + /* 17 - 720x576@50Hz 4:3 */
22652 + /* 2 - 720x480@60Hz 4:3 */
22661 + struct drm_device *dev = connector->dev;
22674 + mode->type = DRM_MODE_TYPE_PREFERRED;
22737 + /* DisplayID CTA extension blocks and top-level CEA EDID
22748 + * Byte number (decimal) within this block where the 18-byte
22749 + * DTDs begin. If no non-DTD data is present in this extension
22752 + * no non-DTD data.
22768 + return -ERANGE;
22770 + return -EOPNOTSUPP;
22783 + if (edid == NULL || edid->extensions == 0)
22787 + for (i = *ext_index; i < edid->extensions; i++) {
22793 + if (i >= edid->extensions)
22810 + base->rev, base->bytes, base->prod_id, base->ext_count);
22813 + dispid_length = sizeof(*base) + base->bytes + 1;
22814 + if (dispid_length > length - idx)
22815 + return -EINVAL;
22821 + return -EINVAL;
22839 + *length = EDID_LENGTH - 1;
22847 + *length = *idx + sizeof(*base) + base->bytes;
22877 + if (block->tag == 0x81)
22894 + return -EINVAL;
22896 + info = &connector->display_info;
22900 + return -EINVAL;
22903 + info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
22975 + dsc_cap->v_1p2 = hf_vsdb[11] & EDID_DSC_1P2;
22977 + if (!dsc_cap->v_1p2)
22980 + dsc_cap->native_420 = hf_vsdb[11] & EDID_DSC_NATIVE_420;
22981 + dsc_cap->all_bpp = hf_vsdb[11] & EDID_DSC_ALL_BPP;
22984 + dsc_cap->bpc_supported = 16;
22986 + dsc_cap->bpc_supported = 12;
22988 + dsc_cap->bpc_supported = 10;
22990 + dsc_cap->bpc_supported = 0;
22993 + get_max_frl_rate(dsc_max_frl_rate, &dsc_cap->max_lanes,
22994 + &dsc_cap->max_frl_rate_per_lane);
22995 + dsc_cap->total_chunk_kbytes = hf_vsdb[13] & EDID_DSC_TOTAL_CHUNK_KBYTES;
23000 + dsc_cap->max_slices = 1;
23001 + dsc_cap->clk_per_slice = 340;
23004 + dsc_cap->max_slices = 2;
23005 + dsc_cap->clk_per_slice = 340;
23008 + dsc_cap->max_slices = 4;
23009 + dsc_cap->clk_per_slice = 340;
23012 + dsc_cap->max_slices = 8;
23013 + dsc_cap->clk_per_slice = 340;
23016 + dsc_cap->max_slices = 8;
23017 + dsc_cap->clk_per_slice = 400;
23020 + dsc_cap->max_slices = 12;
23021 + dsc_cap->clk_per_slice = 400;
23024 + dsc_cap->max_slices = 16;
23025 + dsc_cap->clk_per_slice = 400;
23029 + dsc_cap->max_slices = 0;
23030 + dsc_cap->clk_per_slice = 0;
23057 + return -ENOENT;
23063 + hdr->yuv422_12bit = data[5] & BIT(0);
23064 + hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
23065 + hdr->global_dimming = (data[5] & BIT(2)) >> 2;
23067 + hdr->dm_major_ver = (data[21] & 0xf0) >> 4;
23068 + hdr->dm_minor_ver = data[21] & 0xf;
23070 + hdr->t_min_pq = (data[19] << 4) | ((data[18] & 0xf0) >> 4);
23071 + hdr->t_max_pq = (data[20] << 4) | (data[18] & 0xf);
23073 + hdr->rx = (data[7] << 4) | ((data[6] & 0xf0) >> 4);
23074 + hdr->ry = (data[8] << 4) | (data[6] & 0xf);
23075 + hdr->gx = (data[10] << 4) | ((data[9] & 0xf0) >> 4);
23076 + hdr->gy = (data[11] << 4) | (data[9] & 0xf);
23077 + hdr->bx = (data[13] << 4) | ((data[12] & 0xf0) >> 4);
23078 + hdr->by = (data[14] << 4) | (data[12] & 0xf);
23079 + hdr->wx = (data[16] << 4) | ((data[15] & 0xf0) >> 4);
23080 + hdr->wy = (data[17] << 4) | (data[15] & 0xf);
23085 + hdr->yuv422_12bit = data[5] & BIT(0);
23086 + hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
23087 + hdr->global_dimming = data[6] & BIT(0);
23089 + hdr->dm_version = (data[5] & 0x1c) >> 2;
23091 + hdr->colorimetry = data[7] & BIT(0);
23093 + hdr->t_max_lum = (data[6] & 0xfe) >> 1;
23094 + hdr->t_min_lum = (data[7] & 0xfe) >> 1;
23096 + hdr->rx = data[9];
23097 + hdr->ry = data[10];
23098 + hdr->gx = data[11];
23099 + hdr->gy = data[12];
23100 + hdr->bx = data[13];
23101 + hdr->by = data[14];
23106 + hdr->yuv422_12bit = data[5] & BIT(0);
23107 + hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
23108 + hdr->global_dimming = data[6] & BIT(0);
23110 + hdr->dm_version = (data[5] & 0x1c) >> 2;
23112 + hdr->colorimetry = data[7] & BIT(0);
23114 + hdr->t_max_lum = (data[6] & 0xfe) >> 1;
23115 + hdr->t_min_lum = (data[7] & 0xfe) >> 1;
23117 + hdr->low_latency = data[8] & 0x3;
23119 + hdr->unique_rx = (data[11] & 0xf8) >> 3;
23120 + hdr->unique_ry = (data[11] & 0x7) << 2 | (data[10] & BIT(0)) << 1 |
23122 + hdr->unique_gx = (data[9] & 0xfe) >> 1;
23123 + hdr->unique_gy = (data[10] & 0xfe) >> 1;
23124 + hdr->unique_bx = (data[8] & 0xe0) >> 5;
23125 + hdr->unique_by = (data[8] & 0x1c) >> 2;
23130 + hdr->yuv422_12bit = data[5] & BIT(0);
23131 + hdr->backlt_ctrl = (data[5] & BIT(1)) >> 1;
23132 + hdr->global_dimming = (data[6] & BIT(2)) >> 2;
23134 + hdr->dm_version = (data[5] & 0x1c) >> 2;
23135 + hdr->backlt_min_luma = data[6] & 0x3;
23136 + hdr->interface = data[7] & 0x3;
23137 + hdr->yuv444_10b_12b = (data[8] & BIT(0)) << 1 | (data[9] & BIT(0));
23139 + hdr->t_min_pq_v2 = (data[6] & 0xf8) >> 3;
23140 + hdr->t_max_pq_v2 = (data[7] & 0xf8) >> 3;
23142 + hdr->unique_rx = (data[10] & 0xf8) >> 3;
23143 + hdr->unique_ry = (data[11] & 0xf8) >> 3;
23144 + hdr->unique_gx = (data[8] & 0xfe) >> 1;
23145 + hdr->unique_gy = (data[9] & 0xfe) >> 1;
23146 + hdr->unique_bx = data[10] & 0x7;
23147 + hdr->unique_by = data[11] & 0x7;
23160 + sink_data->version = version;
23164 + parse_ver_26_v0_data(&sink_data->ver_26_v0, next_hdr_db);
23167 + parse_ver_15_v1_data(&sink_data->ver_15_v1, next_hdr_db);
23170 + parse_ver_12_v1_data(&sink_data->ver_12_v1, next_hdr_db);
23173 + parse_ver_12_v2_data(&sink_data->ver_12_v2, next_hdr_db);
23188 + return -EINVAL;
23192 + return -EINVAL;
23195 + return -EINVAL;
23216 + return -EINVAL;
23222 + return -EINVAL;
23225 + return -EINVAL;
23241 @@ -72,6 +919,66 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
23247 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23251 + priv->crtc_funcs[pipe] &&
23252 + priv->crtc_funcs[pipe]->crtc_standby)
23253 + priv->crtc_funcs[pipe]->crtc_standby(crtc, standby);
23260 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23263 + return -EINVAL;
23265 + priv->crtc_funcs[pipe] = crtc_funcs;
23273 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23278 + priv->crtc_funcs[pipe] = NULL;
23286 + struct rockchip_drm_private *priv = drm_dev->dev_private;
23293 + if (priv->crtc_funcs[pipe] &&
23294 + priv->crtc_funcs[pipe]->regs_dump)
23295 + priv->crtc_funcs[pipe]->regs_dump(crtc, NULL);
23297 + if (priv->crtc_funcs[pipe] &&
23298 + priv->crtc_funcs[pipe]->debugfs_dump)
23299 + priv->crtc_funcs[pipe]->debugfs_dump(crtc, NULL);
23307 struct rockchip_drm_private *private = drm_dev->dev_private;
23308 @@ -94,6 +1001,9 @@ static int rockchip_drm_init_iommu(struct drm_device *drm_dev)
23309 drm_mm_init(&private->mm, start, end - start + 1);
23310 mutex_init(&private->mm_lock);
23312 + iommu_set_fault_handler(private->domain, rockchip_drm_fault_handler,
23318 @@ -108,6 +1018,229 @@ static void rockchip_iommu_cleanup(struct drm_device *drm_dev)
23319 iommu_domain_free(private->domain);
23325 + struct drm_info_node *node = s->private;
23326 + struct drm_minor *minor = node->minor;
23327 + struct drm_device *drm_dev = minor->dev;
23328 + struct rockchip_drm_private *priv = drm_dev->dev_private;
23331 + if (!priv->domain)
23333 + mutex_lock(&priv->mm_lock);
23334 + drm_mm_print(&priv->mm, &p);
23335 + mutex_unlock(&priv->mm_lock);
23342 + struct drm_info_node *node = s->private;
23343 + struct drm_minor *minor = node->minor;
23344 + struct drm_device *drm_dev = minor->dev;
23345 + struct rockchip_drm_private *priv = drm_dev->dev_private;
23351 + if (priv->crtc_funcs[pipe] &&
23352 + priv->crtc_funcs[pipe]->debugfs_dump)
23353 + priv->crtc_funcs[pipe]->debugfs_dump(crtc, s);
23366 + struct drm_device *dev = minor->dev;
23367 + struct rockchip_drm_private *priv = dev->dev_private;
23372 + minor->debugfs_root, minor);
23377 + if (priv->crtc_funcs[pipe] &&
23378 + priv->crtc_funcs[pipe]->debugfs_init)
23379 + priv->crtc_funcs[pipe]->debugfs_init(minor, crtc);
23387 + struct rockchip_drm_private *private = dev->dev_private;
23392 + return -ENOMEM;
23393 + private->eotf_prop = prop;
23398 + return -ENOMEM;
23399 + private->color_space_prop = prop;
23404 + return -ENOMEM;
23405 + private->async_commit_prop = prop;
23410 + return -ENOMEM;
23411 + private->share_id_prop = prop;
23416 + return -ENOMEM;
23417 + private->connector_id_prop = prop;
23422 + private->soc_id_prop = prop;
23427 + private->port_id_prop = prop;
23429 + private->aclk_prop = drm_property_create_range(dev, 0, "ACLK", 0, UINT_MAX);
23430 + private->bg_prop = drm_property_create_range(dev, 0, "BACKGROUND", 0, UINT_MAX);
23431 + private->line_flag_prop = drm_property_create_range(dev, 0, "LINE_FLAG1", 0, UINT_MAX);
23439 + struct drm_mode_config *conf = &drm->mode_config;
23442 + mutex_lock(&drm->mode_config.mutex);
23445 + drm_object_attach_property(&connector->base, prop, v)
23449 + ROCKCHIP_PROP_ATTACH(conf->tv_brightness_property, 50);
23450 + ROCKCHIP_PROP_ATTACH(conf->tv_contrast_property, 50);
23451 + ROCKCHIP_PROP_ATTACH(conf->tv_saturation_property, 50);
23452 + ROCKCHIP_PROP_ATTACH(conf->tv_hue_property, 50);
23457 + mutex_unlock(&drm->mode_config.mutex);
23463 + struct drm_mode_config *conf = &drm->mode_config;
23470 + state = drm_atomic_helper_duplicate_state(drm, conf->acquire_ctx);
23475 + state->acquire_ctx = conf->acquire_ctx;
23484 + DRM_ERROR("Connector[%d]: Failed to get state\n", connector->base.id);
23488 + connector_state->tv.brightness = 50;
23489 + connector_state->tv.contrast = 50;
23490 + connector_state->tv.saturation = 50;
23491 + connector_state->tv.hue = 50;
23496 + WARN_ON(ret == -EDEADLK);
23507 + struct rockchip_drm_private *private = drm->dev_private;
23508 + struct device_node *np = drm->dev->of_node;
23514 + node = of_parse_phandle(np, "secure-memory-region", 0);
23516 + return -ENXIO;
23524 + return -ENOMEM;
23526 + private->secure_buffer_pool = gen_pool_create(PAGE_SHIFT, -1);
23527 + if (!private->secure_buffer_pool)
23528 + return -ENOMEM;
23530 + gen_pool_add(private->secure_buffer_pool, start, size, -1);
23537 + struct rockchip_drm_private *private = drm->dev_private;
23539 + if (!private->secure_buffer_pool)
23542 + gen_pool_destroy(private->secure_buffer_pool);
23548 @@ -126,10 +1259,32 @@ static int rockchip_drm_bind(struct device *dev)
23552 + mutex_init(&private->ovl_lock);
23554 drm_dev->dev_private = private;
23556 INIT_LIST_HEAD(&private->psr_list);
23557 mutex_init(&private->psr_list_lock);
23558 + mutex_init(&private->commit_lock);
23560 + private->hdmi_pll.pll = devm_clk_get_optional(dev, "hdmi-tmds-pll");
23561 + if (PTR_ERR(private->hdmi_pll.pll) == -EPROBE_DEFER) {
23562 + ret = -EPROBE_DEFER;
23564 + } else if (IS_ERR(private->hdmi_pll.pll)) {
23565 + dev_err(dev, "failed to get hdmi-tmds-pll\n");
23566 + ret = PTR_ERR(private->hdmi_pll.pll);
23569 + private->default_pll.pll = devm_clk_get_optional(dev, "default-vop-pll");
23570 + if (PTR_ERR(private->default_pll.pll) == -EPROBE_DEFER) {
23571 + ret = -EPROBE_DEFER;
23573 + } else if (IS_ERR(private->default_pll.pll)) {
23575 + ret = PTR_ERR(private->default_pll.pll);
23581 @@ -140,17 +1295,19 @@ static int rockchip_drm_bind(struct device *dev)
23585 -
23590 - goto err_iommu_cleanup;
23594 ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
23603 @@ -158,12 +1315,21 @@ static int rockchip_drm_bind(struct device *dev)
23605 drm_dev->irq_enabled = true;
23611 + ret = of_reserved_mem_device_init(drm_dev->dev);
23621 - /* init kms poll for handling hpd */
23622 - drm_kms_helper_poll_init(drm_dev);
23623 + drm_dev->mode_config.allow_fb_modifiers = true;
23627 @@ -171,13 +1337,18 @@ static int rockchip_drm_bind(struct device *dev)
23641 + drm_dev->dev_private = NULL;
23646 @@ -189,15 +1360,121 @@ static void rockchip_drm_unbind(struct device *dev)
23658 + drm_dev->dev_private = NULL;
23666 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23670 + priv->crtc_funcs[pipe] &&
23671 + priv->crtc_funcs[pipe]->cancel_pending_vblank)
23672 + priv->crtc_funcs[pipe]->cancel_pending_vblank(crtc, file_priv);
23680 + crtc->primary->fb = NULL;
23690 + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
23696 + struct rockchip_drm_private *priv = dev->dev_private;
23698 + if (!priv->logo)
23699 + drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev_helper);
23707 + struct drm_device *dev = crtc->dev;
23714 + e->pipe = drm_crtc_index(crtc);
23715 + e->event.base.type = DRM_EVENT_ROCKCHIP_CRTC_VCNT;
23716 + e->event.base.length = sizeof(e->event.vbl);
23717 + e->event.vbl.crtc_id = crtc->base.id;
23718 + e->event.vbl.user_data = vblwait->request.signal;
23720 + spin_lock_irqsave(&dev->event_lock, flags);
23721 + drm_event_reserve_init_locked(dev, file_priv, &e->base, &e->event.base);
23722 + spin_unlock_irqrestore(&dev->event_lock, flags);
23730 + struct rockchip_drm_private *priv = dev->dev_private;
23736 + flags = vblwait->request.type & (_DRM_VBLANK_FLAGS_MASK | _DRM_ROCKCHIP_VCNT_EVENT);
23737 + pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
23747 + priv->vcnt[pipe].event = e;
23768 @@ -209,19 +1486,160 @@ static const struct file_operations rockchip_drm_driver_fops = {
23775 + struct drm_gem_object *obj = dma_buf->priv;
23783 + struct drm_gem_object *obj = dma_buf->priv;
23793 + struct drm_gem_object *obj = dma_buf->priv;
23803 + struct drm_gem_object *obj = dma_buf->priv;
23834 + if (dma_buf->ops == &rockchip_drm_gem_prime_dmabuf_ops) {
23835 + obj = dma_buf->priv;
23836 + if (obj->dev == dev) {
23846 + if (!dev->driver->gem_prime_import_sg_table)
23847 + return ERR_PTR(-EINVAL);
23861 + obj = dev->driver->gem_prime_import_sg_table(dev, attach, sgt);
23867 + obj->import_attach = attach;
23868 + obj->resv = dma_buf->resv;
23884 + return rockchip_drm_gem_prime_import_dev(dev, dma_buf, dev->dev);
23890 + struct drm_device *dev = obj->dev;
23893 + .owner = dev->driver->fops->owner,
23895 + .size = obj->size,
23898 + .resv = obj->resv,
23905 - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
23906 - .lastclose = drm_fb_helper_lastclose,
23931 @@ -371,7 +1789,7 @@ static int rockchip_drm_platform_of_probe(struct device *dev)
23934 iommu = of_parse_phandle(port->parent, "iommus", 0);
23935 - if (!iommu || !of_device_is_available(iommu->parent)) {
23938 "no iommu attached for %pOF, using non-iommu buffers\n",
23939 port->parent);
23940 @@ -409,8 +1827,10 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
23951 @@ -422,6 +1842,10 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
23962 @@ -470,7 +1894,12 @@ static int __init rockchip_drm_init(void)
23966 - ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP);
23976 @@ -480,10 +1909,15 @@ static int __init rockchip_drm_init(void)
23992 @@ -493,6 +1927,8 @@ static int __init rockchip_drm_init(void)
24001 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_dr…
24003 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
24005 @@ -9,32 +9,375 @@
24009 -#include <drm/drm_fb_helper.h>
24015 -
24022 +#include "panel/panel-simple.h"
24028 -#define ROCKCHIP_MAX_CRTC 2
24056 +#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */
24384 @@ -43,13 +386,55 @@ struct rockchip_crtc_state {
24385 * @mm_lock: protect drm_mm on multi-threads.
24388 - struct drm_fb_helper fbdev_helper;
24441 @@ -57,14 +442,51 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
24493 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
24495 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
24497 @@ -5,6 +5,7 @@
24505 @@ -13,18 +14,47 @@
24518 + return fb->flags & ROCKCHIP_DRM_MODE_LOGO_FB ? true : false;
24531 + rockchip_free_loader_memory(fb->dev);
24536 + if (fb->obj[i])
24537 + drm_gem_object_put(fb->obj[i]);
24545 - .destroy = drm_gem_fb_destroy,
24548 - .dirty = drm_atomic_helper_dirtyfb,
24551 -static struct drm_framebuffer *
24556 @@ -53,8 +83,103 @@ rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cm
24570 + return ERR_PTR(-ENOMEM);
24571 + fb = &rockchip_logo_fb->fb;
24577 + DRM_DEV_ERROR(dev->dev,
24584 + fb->flags |= ROCKCHIP_DRM_MODE_LOGO_FB;
24585 + rockchip_logo_fb->logo = logo;
24586 + rockchip_logo_fb->fb.obj[0] = &rockchip_logo_fb->rk_obj.base;
24587 + rockchip_logo_fb->rk_obj.dma_addr = logo->dma_addr;
24588 + rockchip_logo_fb->rk_obj.kvaddr = logo->kvaddr;
24589 + logo->count++;
24591 + return &rockchip_logo_fb->fb;
24598 + struct rockchip_drm_private *priv = dev->dev_private;
24604 + vop_bw_info->line_bw_mbyte = 0;
24605 + vop_bw_info->frame_bw_mbyte = 0;
24606 + vop_bw_info->plane_num = 0;
24609 + funcs = priv->crtc_funcs[drm_crtc_index(crtc)];
24611 + if (funcs && funcs->bandwidth)
24612 + funcs->bandwidth(crtc, old_crtc_state, vop_bw_info);
24619 + * rockchip_drm_atomic_helper_commit_tail_rpm - commit atomic update to hardware
24630 + struct drm_device *dev = old_state->dev;
24631 + struct rockchip_drm_private *prv = dev->dev_private;
24642 + mutex_lock(&prv->ovl_lock);
24644 + mutex_unlock(&prv->ovl_lock);
24656 - .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
24661 @@ -81,7 +206,7 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
24664 if (drm_is_afbc(mode_cmd->modifier[0])) {
24665 - int ret, i;
24670 @@ -98,9 +223,18 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
24671 return &afbc_fb->base;
24676 + struct rockchip_drm_private *private = dev->dev_private;
24677 + struct drm_fb_helper *fb_helper = private->fbdev_helper;
24679 + if (fb_helper && dev->mode_config.poll_enabled && !private->loader_protect)
24685 - .output_poll_changed = drm_fb_helper_output_poll_changed,
24690 @@ -125,12 +259,13 @@ void rockchip_drm_mode_config_init(struct drm_device *dev)
24691 dev->mode_config.min_height = 0;
24694 - * set max width and height as default value(4096x4096).
24699 - dev->mode_config.max_width = 4096;
24700 - dev->mode_config.max_height = 4096;
24701 + dev->mode_config.max_width = 16384;
24702 + dev->mode_config.max_height = 16384;
24703 + dev->mode_config.async_page_flip = true;
24705 dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;
24706 dev->mode_config.helper_private = &rockchip_mode_config_helpers;
24707 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h
24709 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h
24711 @@ -7,6 +7,10 @@
24722 @@ -14,4 +18,19 @@ rockchip_drm_framebuffer_init(struct drm_device *dev,
24742 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_…
24744 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
24746 @@ -15,14 +15,12 @@
24750 -#define to_drm_private(x) \
24751 - container_of(x, struct rockchip_drm_private, fbdev_helper)
24756 struct drm_fb_helper *helper = info->par;
24757 - struct rockchip_drm_private *private = to_drm_private(helper);
24758 + struct rockchip_drm_private *private = helper->dev->dev_private;
24760 return rockchip_gem_mmap_buf(private->fbdev_bo, vma);
24762 @@ -39,7 +37,7 @@ static const struct fb_ops rockchip_drm_fbdev_ops = {
24766 - struct rockchip_drm_private *private = to_drm_private(helper);
24767 + struct rockchip_drm_private *private = helper->dev->dev_private;
24769 struct drm_device *dev = helper->dev;
24771 @@ -60,7 +58,7 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
24775 - rk_obj = rockchip_gem_create_object(dev, size, true);
24778 return -ENOMEM;
24780 @@ -120,7 +118,10 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
24781 if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
24782 return -EINVAL;
24784 - helper = &private->fbdev_helper;
24785 + helper = devm_kzalloc(dev->dev, sizeof(*helper), GFP_KERNEL);
24787 + return -ENOMEM;
24788 + private->fbdev_helper = helper;
24792 @@ -150,9 +151,10 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
24795 struct rockchip_drm_private *private = dev->dev_private;
24796 - struct drm_fb_helper *helper;
24797 + struct drm_fb_helper *helper = private->fbdev_helper;
24799 - helper = &private->fbdev_helper;
24805 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_ge…
24807 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
24809 @@ -4,7 +4,7 @@
24810 * Author:Mark Yao <mark.yao@rock-chips.com>
24813 -#include <linux/dma-buf.h>
24814 +#include <linux/dma-buf-cache.h>
24818 @@ -13,9 +13,25 @@
24843 struct drm_device *drm = rk_obj->base.dev;
24844 @@ -45,6 +61,8 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
24848 + iommu_flush_iotlb_all(private->domain);
24850 rk_obj->size = ret;
24853 @@ -73,25 +91,137 @@ static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
24864 + list_del(&info->list);
24876 + bank_bit_first = ddr_map_info->bank_bit_first;
24877 + bank_bit_mask = ddr_map_info->bank_bit_mask;
24883 struct drm_device *drm = rk_obj->base.dev;
24886 -
24887 - rk_obj->pages = drm_gem_get_pages(&rk_obj->base);
24888 - if (IS_ERR(rk_obj->pages))
24889 - return PTR_ERR(rk_obj->pages);
24907 + pages = drm_gem_get_pages(&rk_obj->base);
24911 + rk_obj->pages = pages;
24913 rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
24915 + n_pages = rk_obj->num_pages;
24920 + ret = -ENOMEM;
24933 + page_to_pfn(pages[j - 1]) + 1)
24937 + chunk_pages = j - cur_page;
24946 + ret = -ENOMEM;
24950 + INIT_LIST_HEAD(&info->list);
24951 + info->page = pages[cur_page + i];
24952 + phys = page_to_phys(info->page);
24954 + list_add_tail(&info->list, &lists[bit_index]);
24960 + remain -= chunk_pages;
24974 + dst_pages[end++] = info->page;
24975 + list_del(&info->list);
24983 rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->base.dev,
24984 - rk_obj->pages, rk_obj->num_pages);
24985 + dst_pages, rk_obj->num_pages);
24986 if (IS_ERR(rk_obj->sgt)) {
24987 ret = PTR_ERR(rk_obj->sgt);
24988 - goto err_put_pages;
24992 + rk_obj->pages = dst_pages;
24997 @@ -104,8 +234,13 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
24999 dma_sync_sgtable_for_device(drm->dev, rk_obj->sgt, DMA_TO_DEVICE);
25009 drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false);
25011 @@ -118,59 +253,164 @@ static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj)
25012 drm_gem_put_pages(&rk_obj->base, rk_obj->pages, true, true);
25015 -static int rockchip_gem_alloc_iommu(struct rockchip_gem_object *rk_obj,
25016 - bool alloc_kmap)
25023 - int ret;
25024 + struct drm_gem_object *obj = &rk_obj->base;
25025 + struct drm_device *drm = obj->dev;
25030 - ret = rockchip_gem_get_pages(rk_obj);
25031 - if (ret < 0)
25032 - return ret;
25033 + rk_obj->dma_attrs = DMA_ATTR_WRITE_COMBINE;
25035 - ret = rockchip_gem_iommu_map(rk_obj);
25036 - if (ret < 0)
25037 - goto err_free;
25038 -
25039 - if (alloc_kmap) {
25040 - rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP,
25041 - pgprot_writecombine(PAGE_KERNEL));
25042 - if (!rk_obj->kvaddr) {
25043 - DRM_ERROR("failed to vmap() buffer\n");
25044 - ret = -ENOMEM;
25045 - goto err_unmap;
25046 - }
25048 + rk_obj->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
25050 + rk_obj->kvaddr = dma_alloc_attrs(drm->dev, obj->size,
25051 + &rk_obj->dma_handle, GFP_KERNEL,
25052 + rk_obj->dma_attrs);
25053 + if (!rk_obj->kvaddr) {
25054 + DRM_ERROR("failed to allocate %zu byte dma buffer", obj->size);
25055 + return -ENOMEM;
25060 + ret = -ENOMEM;
25064 + ret = dma_get_sgtable_attrs(drm->dev, sgt, rk_obj->kvaddr,
25065 + rk_obj->dma_handle, obj->size,
25066 + rk_obj->dma_attrs);
25072 + for_each_sg(sgt->sgl, s, sgt->nents, i)
25075 + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
25077 + rk_obj->pages = drm_calloc_large(rk_obj->num_pages,
25078 + sizeof(*rk_obj->pages));
25079 + if (!rk_obj->pages) {
25084 + if (drm_prime_sg_to_page_addr_arrays(sgt, rk_obj->pages, NULL,
25085 + rk_obj->num_pages)) {
25087 + ret = -EINVAL;
25091 + rk_obj->sgt = sgt;
25095 -err_unmap:
25096 - rockchip_gem_iommu_unmap(rk_obj);
25097 -err_free:
25098 - rockchip_gem_put_pages(rk_obj);
25100 + drm_free_large(rk_obj->pages);
25106 + dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr,
25107 + rk_obj->dma_handle, rk_obj->dma_attrs);
25112 -static int rockchip_gem_alloc_dma(struct rockchip_gem_object *rk_obj,
25113 - bool alloc_kmap)
25133 struct drm_gem_object *obj = &rk_obj->base;
25134 struct drm_device *drm = obj->dev;
25135 + struct rockchip_drm_private *private = drm->dev_private;
25140 - rk_obj->dma_attrs = DMA_ATTR_WRITE_COMBINE;
25141 -
25142 - if (!alloc_kmap)
25143 - rk_obj->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
25144 + if (!private->secure_buffer_pool) {
25146 + return -ENOMEM;
25149 - rk_obj->kvaddr = dma_alloc_attrs(drm->dev, obj->size,
25150 - &rk_obj->dma_addr, GFP_KERNEL,
25151 - rk_obj->dma_attrs);
25152 - if (!rk_obj->kvaddr) {
25153 - DRM_ERROR("failed to allocate %zu byte dma buffer", obj->size);
25154 + paddr = gen_pool_alloc(private->secure_buffer_pool, rk_obj->base.size);
25157 return -ENOMEM;
25160 + rk_obj->dma_handle = paddr;
25161 + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
25163 + rk_obj->pages = drm_calloc_large(rk_obj->num_pages,
25164 + sizeof(*rk_obj->pages));
25165 + if (!rk_obj->pages) {
25167 + ret = -ENOMEM;
25172 + while (i < rk_obj->num_pages) {
25173 + rk_obj->pages[i] = phys_to_page(paddr);
25177 + sgt = drm_prime_pages_to_sg(obj->dev, rk_obj->pages, rk_obj->num_pages);
25183 + rk_obj->sgt = sgt;
25188 + drm_free_large(rk_obj->pages);
25190 + gen_pool_free(private->secure_buffer_pool, paddr, rk_obj->base.size);
25197 + struct drm_gem_object *obj = &rk_obj->base;
25198 + struct drm_device *drm = obj->dev;
25199 + struct rockchip_drm_private *private = drm->dev_private;
25201 + drm_free_large(rk_obj->pages);
25202 + sg_free_table(rk_obj->sgt);
25203 + kfree(rk_obj->sgt);
25204 + gen_pool_free(private->secure_buffer_pool, rk_obj->dma_handle,
25205 + rk_obj->base.size);
25209 @@ -179,18 +419,66 @@ static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
25210 struct drm_gem_object *obj = &rk_obj->base;
25211 struct drm_device *drm = obj->dev;
25212 struct rockchip_drm_private *private = drm->dev_private;
25215 + if (!private->domain)
25216 + rk_obj->flags |= ROCKCHIP_BO_CONTIG;
25218 + if (rk_obj->flags & ROCKCHIP_BO_SECURE) {
25219 + rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_SECURE;
25220 + rk_obj->flags |= ROCKCHIP_BO_CONTIG;
25223 + return -EINVAL;
25228 + } else if (rk_obj->flags & ROCKCHIP_BO_CONTIG) {
25229 + rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_CMA;
25234 + rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_SHMEM;
25240 + rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages,
25243 + if (!rk_obj->kvaddr) {
25245 + ret = -ENOMEM;
25251 + if (private->domain) {
25256 + WARN_ON(!rk_obj->dma_handle);
25257 + rk_obj->dma_addr = rk_obj->dma_handle;
25263 if (private->domain)
25264 - return rockchip_gem_alloc_iommu(rk_obj, alloc_kmap);
25267 + if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SECURE)
25269 + else if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_CMA)
25272 - return rockchip_gem_alloc_dma(rk_obj, alloc_kmap);
25273 -}
25274 -
25275 -static void rockchip_gem_free_iommu(struct rockchip_gem_object *rk_obj)
25276 -{
25277 - vunmap(rk_obj->kvaddr);
25278 - rockchip_gem_iommu_unmap(rk_obj);
25279 - rockchip_gem_put_pages(rk_obj);
25285 @@ -198,16 +486,29 @@ static void rockchip_gem_free_dma(struct rockchip_gem_object *rk_obj)
25286 struct drm_gem_object *obj = &rk_obj->base;
25287 struct drm_device *drm = obj->dev;
25289 - dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr, rk_obj->dma_addr,
25290 - rk_obj->dma_attrs);
25291 + drm_free_large(rk_obj->pages);
25292 + sg_free_table(rk_obj->sgt);
25293 + kfree(rk_obj->sgt);
25294 + dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr,
25295 + rk_obj->dma_handle, rk_obj->dma_attrs);
25300 - if (rk_obj->pages)
25301 - rockchip_gem_free_iommu(rk_obj);
25302 - else
25303 + struct drm_device *drm = rk_obj->base.dev;
25304 + struct rockchip_drm_private *private = drm->dev_private;
25306 + if (private->domain)
25309 + if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SHMEM) {
25310 + vunmap(rk_obj->kvaddr);
25312 + } else if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SECURE) {
25320 @@ -239,16 +540,24 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
25325 + if (rk_obj->flags & ROCKCHIP_BO_CACHABLE)
25326 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
25332 vma->vm_flags &= ~VM_PFNMAP;
25334 - if (rk_obj->pages)
25335 + if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SECURE) {
25337 + ret = -EINVAL;
25338 + } else if (rk_obj->pages) {
25340 - else
25347 @@ -298,9 +607,15 @@ static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj)
25363 @@ -311,12 +626,15 @@ static struct rockchip_gem_object *
25367 + mapping = file_inode(obj->filp)->i_mapping;
25375 - bool alloc_kmap)
25380 @@ -324,6 +642,7 @@ rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
25384 + rk_obj->flags = flags;
25388 @@ -336,6 +655,28 @@ rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
25393 + * rockchip_gem_destroy - destroy gem object
25395 + * The dma_buf_unmap_attachment and dma_buf_detach will be re-defined if
25405 + attach = obj->import_attach;
25408 + dma_buf = attach->dmabuf;
25409 + dma_buf_detach(attach->dmabuf, attach);
25415 * rockchip_gem_free_object - (struct drm_driver)->gem_free_object_unlocked
25417 @@ -353,7 +694,11 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
25418 dma_unmap_sgtable(drm->dev, rk_obj->sgt,
25421 - drm_prime_gem_destroy(obj, rk_obj->sgt);
25422 + drm_free_large(rk_obj->pages);
25424 + rockchip_gem_destroy(obj, rk_obj->sgt);
25426 + drm_prime_gem_destroy(obj, rk_obj->sgt);
25430 @@ -371,13 +716,14 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
25434 - unsigned int *handle)
25442 - rk_obj = rockchip_gem_create_object(drm, size, false);
25447 @@ -414,7 +760,7 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv,
25451 - int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
25452 + u32 min_pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
25456 @@ -423,7 +769,7 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv,
25457 args->size = args->pitch * args->height;
25459 rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
25460 - &args->handle);
25461 + &args->handle, args->flags);
25465 @@ -514,6 +860,21 @@ rockchip_gem_prime_import_sg_table(struct drm_device *drm,
25469 + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
25470 + rk_obj->pages = drm_calloc_large(rk_obj->num_pages, sizeof(*rk_obj->pages));
25471 + if (!rk_obj->pages) {
25473 + ret = -ENOMEM;
25477 + ret = drm_prime_sg_to_page_addr_arrays(sg, rk_obj->pages, NULL, rk_obj->num_pages);
25480 + drm_free_large(rk_obj->pages);
25484 return &rk_obj->base;
25487 @@ -546,3 +907,155 @@ void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
25498 + rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
25499 + &args->handle, args->flags);
25508 + return drm_gem_dumb_map_offset(file_priv, drm, args->handle,
25509 + &args->offset);
25520 + obj = drm_gem_object_lookup(file_priv, args->handle);
25523 + return -EINVAL;
25527 + if (!(rk_obj->flags & ROCKCHIP_BO_CONTIG)) {
25528 + DRM_ERROR("Can't get phys address from non-continue buf.\n");
25529 + ret = -EINVAL;
25533 + args->phy_addr = page_to_phys(rk_obj->pages[0]);
25545 + struct drm_device *drm = obj->dev;
25547 + if (!rk_obj->sgt)
25550 + dma_sync_sg_for_cpu(drm->dev, rk_obj->sgt->sgl,
25551 + rk_obj->sgt->nents, dir);
25559 + struct drm_device *drm = obj->dev;
25561 + if (!rk_obj->sgt)
25564 + dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
25565 + rk_obj->sgt->nents, dir);
25582 + len += sg->length;
25587 + sg_left = len - offset;
25588 + sg_offset = sg->length - sg_left;
25599 + length -= size;
25614 + struct drm_device *drm = obj->dev;
25616 + if (!rk_obj->sgt)
25619 + rockchip_gem_prime_sgl_sync_range(drm->dev, rk_obj->sgt->sgl,
25620 + rk_obj->sgt->nents,
25632 + struct drm_device *drm = obj->dev;
25634 + if (!rk_obj->sgt)
25637 + rockchip_gem_prime_sgl_sync_range(drm->dev, rk_obj->sgt->sgl,
25638 + rk_obj->sgt->nents,
25643 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_ge…
25645 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
25647 @@ -7,14 +7,24 @@
25651 +#include <linux/dma-direction.h>
25667 - dma_addr_t dma_addr;
25673 @@ -42,12 +52,43 @@ int rockchip_gem_mmap_buf(struct drm_gem_object *obj,
25677 - rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
25678 - bool alloc_kmap);
25719 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vo…
25721 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
25723 @@ -6,21 +6,28 @@
25729 +#include <linux/fixp-arith.h>
25752 @@ -32,6 +39,12 @@
25756 +#include <dt-bindings/soc/rockchip-system-status.h>
25759 +#include <soc/rockchip/rockchip-system-status.h>
25765 @@ -39,28 +52,65 @@
25769 -#define VOP_WIN_SET(vop, win, name, v) \
25770 - vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
25771 -#define VOP_SCL_SET(vop, win, name, v) \
25772 - vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
25773 -#define VOP_SCL_SET_EXT(vop, win, name, v) \
25774 - vop_reg_set(vop, &win->phy->scl->ext->name, \
25775 - win->base, ~0, v, #name)
25779 + (reg.major == VOP_MAJOR(vop->version) && \
25780 + reg.begin_minor <= VOP_MINOR(vop->version) && \
25781 + reg.end_minor >= VOP_MINOR(vop->version))))
25783 -#define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
25784 - do { \
25785 - if (win_yuv2yuv && win_yuv2yuv->name.mask) \
25786 - vop_reg_set(vop, &win_yuv2yuv->name, 0, ~0, v, #name); \
25787 - } while (0)
25789 + VOP_REG_SUPPORT(vop, win->phy->name)
25792 + (win->phy->scl->ext && \
25793 + VOP_REG_SUPPORT(vop, win->phy->scl->ext->name))
25795 -#define VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, win_yuv2yuv, name, v) \
25797 + VOP_REG_SUPPORT(vop, vop->data->ctrl->name)
25800 + VOP_REG_SUPPORT(vop, vop->data->intr->name)
25807 - if (win_yuv2yuv && win_yuv2yuv->phy->name.mask) \
25808 - vop_reg_set(vop, &win_yuv2yuv->phy->name, win_yuv2yuv->base, ~0, v, #name); \
25813 + dev_dbg(vop->dev, "Warning: not support "#name"\n"); \
25822 + REG_SET(x, name, win->offset, VOP_WIN_NAME(win, name), v, true)
25824 + REG_SET(x, name, 0, win->ext->name, v, true)
25826 + REG_SET(x, name, win->offset, win->phy->scl->name, v, true)
25828 + REG_SET(x, name, win->offset, win->phy->scl->ext->name, v, true)
25831 + REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
25834 + vop_read_reg(vop, 0, &vop->data->ctrl->name)
25837 + REG_SET(vop, name, 0, vop->data->intr->name, \
25840 - vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
25841 + REG_SET_MASK(vop, name, 0, vop->data->intr->name, \
25846 vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
25847 @@ -79,66 +129,132 @@
25849 vop_get_intr_type(vop, &vop->data->intr->name, type)
25851 -#define VOP_WIN_GET(vop, win, name) \
25852 - vop_read_reg(vop, win->base, &win->phy->name)
25854 + vop_read_reg(x, 0, &vop->data->ctrl->name)
25856 -#define VOP_WIN_HAS_REG(win, name) \
25857 - (!!(win->phy->name.mask))
25859 + vop_read_reg(vop, win->offset, &VOP_WIN_NAME(win, name))
25861 -#define VOP_WIN_GET_YRGBADDR(vop, win) \
25862 - vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
25864 + (vop_get_win_phy(win, &win->phy->name)->name)
25867 ((vop_win) - (vop_win)->vop->win)
25869 -#define VOP_AFBC_SET(vop, name, v) \
25872 - if ((vop)->data->afbc) \
25873 - vop_reg_set((vop), &(vop)->data->afbc->name, \
25874 - 0, ~0, v, #name); \
25875 + if (vop->data->grf_ctrl) { \
25876 + vop_grf_writel(vop, vop->data->grf_ctrl->reg, v); \
25880 -#define to_vop(x) container_of(x, struct vop, crtc)
25884 -#define AFBC_FMT_RGB565 0x0
25885 -#define AFBC_FMT_U8U8U8U8 0x5
25886 -#define AFBC_FMT_U8U8U8 0x4
25891 -#define AFBC_TILE_16x16 BIT(4)
25897 -/*
25898 - * The coefficients of the following matrix are all fixed points.
25899 - * The format is S2.10 for the 3x3 part of the matrix, and S9.12 for the offsets.
25900 - * They are all represented in two's complement.
25901 - */
25902 -static const uint32_t bt601_yuv2rgb[] = {
25903 - 0x4A8, 0x0, 0x662,
25904 - 0x4A8, 0x1E6F, 0x1CBF,
25905 - 0x4A8, 0x812, 0x0,
25906 - 0x321168, 0x0877CF, 0x2EB127
25933 -enum vop_pending {
25934 - VOP_PENDING_FB_UNREF,
25947 - const struct vop_win_data *data;
25948 - const struct vop_win_yuv2yuv_data *yuv2yuv_data;
25976 -struct rockchip_rgb;
25978 - struct drm_crtc crtc;
25991 -
26009 - unsigned int win_enabled;
26011 /* protected by dev->event_lock */
26013 @@ -149,14 +265,22 @@ struct vop {
26021 - void __iomem *lut_regs;
26037 @@ -172,16 +296,83 @@ struct vop {
26047 - /* optional internal rgb encoder */
26048 - struct rockchip_rgb *rgb;
26057 + * bus-format types.
26097 + mutex_lock(&vop->vop_lock);
26104 + mutex_unlock(&vop->vop_lock);
26111 + if (IS_ERR_OR_NULL(vop->grf))
26116 + regmap_write(vop->grf, reg.offset, val);
26122 writel(v, vop->regs + offset);
26123 @@ -199,23 +390,15 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
26124 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
26127 -static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
26128 - uint32_t _offset, uint32_t _mask, uint32_t v,
26129 - const char *reg_name)
26134 - int offset, mask, shift;
26135 -
26136 - if (!reg || !reg->mask) {
26137 - DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name);
26140 - }
26141 -
26142 - offset = reg->offset + _offset;
26143 - mask = reg->mask & _mask;
26144 - shift = reg->shift;
26146 - if (reg->write_mask) {
26147 - v = ((v << shift) & 0xffff) | (mask << (shift + 16));
26151 uint32_t cached_val = vop->regsbak[offset >> 2];
26153 @@ -223,12 +406,21 @@ static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
26154 vop->regsbak[offset >> 2] = v;
26157 - if (reg->relaxed)
26159 writel_relaxed(v, vop->regs + offset);
26161 writel(v, vop->regs + offset);
26167 + if (!reg->mask && win->parent)
26168 + return win->parent->phy;
26170 + return win->phy;
26176 @@ -243,9 +435,147 @@ static inline uint32_t vop_get_intr_type(struct vop *vop,
26183 + const struct vop_hdr_table *table = vop->data->hdr_table;
26187 + hdr2sdr_eetf_oetf_yn[i] = table->hdr2sdr_eetf_yn[i] +
26188 + (table->hdr2sdr_bt1886oetf_yn[i] << 16);
26190 + vop_writel(vop, table->hdr2sdr_eetf_oetf_y0_offset,
26194 + table->hdr2sdr_eetf_oetf_y1_offset + (i - 1) * 4,
26197 + vop_writel(vop, table->hdr2sdr_sat_y0_offset,
26198 + table->hdr2sdr_sat_yn[0]);
26200 + vop_writel(vop, table->hdr2sdr_sat_y1_offset + (i - 1) * 4,
26201 + table->hdr2sdr_sat_yn[i]);
26203 + VOP_CTRL_SET(vop, hdr2sdr_src_min, table->hdr2sdr_src_range_min);
26204 + VOP_CTRL_SET(vop, hdr2sdr_src_max, table->hdr2sdr_src_range_max);
26205 + VOP_CTRL_SET(vop, hdr2sdr_normfaceetf, table->hdr2sdr_normfaceetf);
26206 + VOP_CTRL_SET(vop, hdr2sdr_dst_min, table->hdr2sdr_dst_range_min);
26207 + VOP_CTRL_SET(vop, hdr2sdr_dst_max, table->hdr2sdr_dst_range_max);
26208 + VOP_CTRL_SET(vop, hdr2sdr_normfacgamma, table->hdr2sdr_normfacgamma);
26214 + const struct vop_hdr_table *table = vop->data->hdr_table;
26221 + table->sdr2hdr_bt1886eotf_yn_for_bt2020[i] +
26222 + (table->sdr2hdr_st2084oetf_yn_for_bt2020[i] << 18);
26225 + table->sdr2hdr_bt1886eotf_yn_for_hdr[i] +
26226 + (table->sdr2hdr_st2084oetf_yn_for_hdr[i] << 18);
26229 + table->sdr2hdr_bt1886eotf_yn_for_hlg_hdr[i] +
26230 + (table->sdr2hdr_st2084oetf_yn_for_hlg_hdr[i] << 18);
26232 + vop_writel(vop, table->sdr2hdr_eotf_oetf_y0_offset,
26235 + vop_writel(vop, table->sdr2hdr_eotf_oetf_y1_offset +
26236 + (i - 1) * 4, sdr2hdr_eotf_oetf_yn[i]);
26239 + sdr2hdr_oetf_dx_dxpow[i] = table->sdr2hdr_st2084oetf_dxn[i] +
26240 + (table->sdr2hdr_st2084oetf_dxn_pow2[i] << 16);
26241 + vop_writel(vop, table->sdr2hdr_oetf_dx_dxpow1_offset + i * 4,
26246 + vop_writel(vop, table->sdr2hdr_oetf_xn1_offset + i * 4,
26247 + table->sdr2hdr_st2084oetf_xn[i]);
26267 - VOP_REG_SET(vop, common, cfg_done, 1);
26275 + for (i = 0; i < vop->num_wins; i++) {
26276 + struct vop_win *win = &vop->win[i];
26291 + if (win->phy->scl && win->phy->scl->ext) {
26299 + if (win->area_id == 0)
26307 + for (i = 0; i < vop->num_wins; i++) {
26308 + struct vop_win *win = &vop->win[i];
26316 + writel(v, vop->lut_regs + offset);
26321 + return readl(vop->lut_regs + offset);
26325 @@ -276,11 +606,19 @@ static enum vop_data_format vop_convert_format(uint32_t format)
26344 return -EINVAL;
26345 @@ -294,13 +632,13 @@ static int vop_convert_afbc_format(uint32_t format)
26349 - return AFBC_FMT_U8U8U8U8;
26353 - return AFBC_FMT_U8U8U8;
26357 - return AFBC_FMT_RGB565;
26362 @@ -310,6 +648,133 @@ static int vop_convert_afbc_format(uint32_t format)
26363 return -EINVAL;
26486 + for (i = 0 ; i < plane->modifier_count; i++)
26487 + if (plane->modifiers[i] == modifier)
26490 + return (i < plane->modifier_count) ? true : false;
26496 @@ -344,29 +809,37 @@ static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
26500 -static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
26501 - uint32_t src_w, uint32_t src_h, uint32_t dst_w,
26502 - uint32_t dst_h, const struct drm_format_info *info)
26511 + uint8_t hsub = info->hsub;
26512 + uint8_t vsub = info->vsub;
26514 - uint16_t cbcr_src_w = src_w / info->hsub;
26515 - uint16_t cbcr_src_h = src_h / info->vsub;
26521 + const struct vop_data *vop_data = vop->data;
26524 - if (info->is_yuv)
26525 - is_yuv = true;
26526 -
26527 - if (dst_w > 3840) {
26528 - DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
26529 + if (!win->phy->scl)
26532 + if (!(vop_data->feature & VOP_FEATURE_ALPHA_SCALE)) {
26538 + if (info->is_yuv)
26541 if (!win->phy->scl->ext) {
26544 @@ -448,45 +921,411 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *…
26548 -static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
26552 + * HDR/SDR --> win0 --> HDR2SDR ----\
26553 + * \ MUX --\
26554 + * \ --> SDR2HDR/CSC--/ \
26556 + * SDR --> win1 -->pre_overlay ->SDR2HDR/CSC --> post_ovrlay-->post CSC-->output
26557 + * SDR --> win2 -/
26564 - unsigned long flags;
26565 + struct drm_atomic_state *state = crtc_state->state;
26575 - if (WARN_ON(!vop->is_enabled))
26576 - return;
26577 + if (!vop->data->hdr_table)
26588 + if (!pstate->fb)
26591 - spin_lock_irqsave(&vop->irq_lock, flags);
26592 + if (vop_plane_state->eotf > s->eotf)
26593 + if (win->feature & WIN_FEATURE_HDR2SDR)
26595 + if (vop_plane_state->eotf < s->eotf) {
26596 + if (win->feature & WIN_FEATURE_PRE_OVERLAY)
26604 - VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1);
26605 - VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1);
26614 - spin_unlock_irqrestore(&vop->irq_lock, flags);
26615 -}
26631 + if (!pstate->fb)
26634 -static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
26635 -{
26636 - unsigned long flags;
26637 + if (vop_plane_state->color_space == V4L2_COLORSPACE_BT2020 &&
26638 + vop_plane_state->color_space > s->color_space) {
26639 + if (win->feature & WIN_FEATURE_PRE_OVERLAY) {
26647 + if (s->color_space == V4L2_COLORSPACE_BT2020 &&
26648 + vop_plane_state->color_space < s->color_space) {
26649 + if (win->feature & WIN_FEATURE_PRE_OVERLAY) {
26660 - if (WARN_ON(!vop->is_enabled))
26661 - return;
26667 - spin_lock_irqsave(&vop->irq_lock, flags);
26669 + s->hdr.pre_overlay = pre_overlay;
26670 + s->hdr.hdr2sdr_en = hdr2sdr_en;
26671 + if (s->hdr.pre_overlay)
26672 + s->yuv_overlay = 0;
26674 - VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0);
26675 + s->hdr.sdr2hdr_state.bt1886eotf_pre_conv_en = !!pre_sdr2hdr_state;
26676 + s->hdr.sdr2hdr_state.rgb2rgb_pre_conv_en = !!pre_sdr2hdr_state;
26677 + s->hdr.sdr2hdr_state.rgb2rgb_pre_conv_mode = pre_sdr2hdr_mode;
26678 + s->hdr.sdr2hdr_state.st2084oetf_pre_conv_en = !!pre_sdr2hdr_state;
26680 - spin_unlock_irqrestore(&vop->irq_lock, flags);
26681 + s->hdr.sdr2hdr_state.bt1886eotf_post_conv_en = !!post_sdr2hdr_state;
26682 + s->hdr.sdr2hdr_state.rgb2rgb_post_conv_en = !!post_sdr2hdr_state;
26683 + s->hdr.sdr2hdr_state.rgb2rgb_post_conv_mode = post_sdr2hdr_mode;
26684 + s->hdr.sdr2hdr_state.st2084oetf_post_conv_en = !!post_sdr2hdr_state;
26685 + s->hdr.sdr2hdr_state.sdr2hdr_func = sdr2hdr_func;
26721 + dev_err(vop->dev, "wait win close timeout\n");
26725 - * (1) each frame starts at the start of the Vsync pulse which is signaled by
26726 - * the "FRAME_SYNC" interrupt.
26727 - * (2) the active data region of each frame ends at dsp_vact_end
26728 - * (3) we should program this same number (dsp_vact_end) into dsp_line_frag_num,
26729 - * to get "LINE_FLAG" interrupt at the end of the active on screen data.
26732 + * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
26733 + * RGB --> R2Y __/
26735 - * VOP_INTR_CTRL0.dsp_line_frag_num = VOP_DSP_VACT_ST_END.dsp_vact_end
26736 - * Interrupts
26737 - * LINE_FLAG -------------------------------+
26738 + * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020)
26739 + * RGB --> 709To2020->R2Y __/
26741 + * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709)
26742 + * RGB --> R2Y __/
26744 + * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
26745 + * RGB --> 709To2020->R2Y __/
26747 + * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709)
26748 + * RGB --> R2Y __/
26750 + * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601)
26751 + * RGB --> R2Y(601) __/
26753 + * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709)
26754 + * RGB --> bypass __/
26756 + * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020)
26758 + * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709)
26760 + * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601)
26762 + * 11. RGB --> bypass --> RGB_OUTPUT(709)
26783 + *y2r_table = csc_table->y2r_bt709;
26786 + *r2r_table = csc_table->r2r_bt709_to_bt2020;
26787 + *r2y_table = csc_table->r2y_bt2020;
26790 + *y2r_table = csc_table->y2r_bt2020;
26792 + *r2r_table = csc_table->r2r_bt2020_to_bt709;
26797 + *r2y_table = csc_table->r2y_bt709;
26801 + *r2y_table = csc_table->r2y_bt601_12_235; /* bt601 limit */
26803 + *r2y_table = csc_table->r2y_bt601; /* bt601 full */
26814 + return -EINVAL;
26817 + *y2r_table = csc_table->y2r_bt2020;
26821 + *y2r_table = csc_table->y2r_bt709;
26825 + *y2r_table = csc_table->y2r_bt601_12_235; /* bt601 limit */
26827 + *y2r_table = csc_table->y2r_bt601; /* bt601 full */
26833 + *r2r_table = csc_table->r2r_bt2020_to_bt709;
26856 + struct drm_atomic_state *state = crtc_state->state;
26858 + const struct vop_csc_table *csc_table = vop->data->csc_table;
26864 + is_output_yuv = is_yuv_output(s->bus_format);
26875 + if (!pstate->fb)
26877 + is_input_yuv = is_yuv_support(pstate->fb->format->format);
26878 + vop_plane_state->y2r_en = false;
26879 + vop_plane_state->r2r_en = false;
26880 + vop_plane_state->r2y_en = false;
26884 + vop_plane_state->color_space,
26885 + s->color_space,
26886 + &vop_plane_state->y2r_table,
26887 + &vop_plane_state->r2r_table,
26888 + &vop_plane_state->r2y_table);
26892 + vop_setup_csc_mode(is_input_yuv, s->yuv_overlay,
26893 + vop_plane_state->color_space, s->color_space,
26894 + &vop_plane_state->y2r_en,
26895 + &vop_plane_state->r2y_en,
26896 + &vop_plane_state->csc_mode);
26899 + vop_plane_state->y2r_en = !!vop_plane_state->y2r_table;
26900 + vop_plane_state->r2r_en = !!vop_plane_state->r2r_table;
26901 + vop_plane_state->r2y_en = !!vop_plane_state->r2y_table;
26907 + * hdr2sdr on rk3328, vop can't support per-pixel alpha * global
26910 + * UI(rgbx) -> yuv -> rgb ->hdr2sdr -> overlay -> output.
26912 + if (s->hdr.hdr2sdr_en &&
26913 + vop_plane_state->eotf == HDMI_EOTF_SMPTE_ST2084 &&
26914 + !is_yuv_support(pstate->fb->format->format))
26915 + vop_plane_state->r2y_en = true;
26916 + if (win->feature & WIN_FEATURE_PRE_OVERLAY)
26917 + vop_plane_state->r2r_en =
26918 + s->hdr.sdr2hdr_state.rgb2rgb_pre_conv_en;
26919 + else if (win->feature & WIN_FEATURE_HDR2SDR)
26920 + vop_plane_state->r2r_en =
26921 + s->hdr.sdr2hdr_state.rgb2rgb_post_conv_en;
26943 + if (WARN_ON(!vop->is_enabled))
26946 + spin_lock_irqsave(&vop->irq_lock, flags);
26951 + spin_unlock_irqrestore(&vop->irq_lock, flags);
26958 + if (WARN_ON(!vop->is_enabled))
26961 + spin_lock_irqsave(&vop->irq_lock, flags);
26965 + spin_unlock_irqrestore(&vop->irq_lock, flags);
26977 + * LINE_FLAG -------------------------------+
26978 * FRAME_SYNC ----+ |
26981 @@ -567,147 +1406,234 @@ static void vop_core_clks_disable(struct vop *vop)
26982 clk_disable(vop->hclk);
26985 -static void vop_win_disable(struct vop *vop, const struct vop_win *vop_win)
26988 - const struct vop_win_data *win = vop_win->data;
26992 - if (win->phy->scl && win->phy->scl->ext) {
26993 - VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
26994 - VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
26995 - VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
26996 - VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
26997 + if (!vop->is_enabled || !vop->lut || !vop->lut_regs)
27000 + if (WARN_ON(!drm_modeset_is_locked(&crtc->mutex)))
27004 + spin_lock(&vop->reg_lock);
27007 + spin_unlock(&vop->reg_lock);
27016 - VOP_WIN_SET(vop, win, enable, 0);
27017 - vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win));
27018 + for (i = 0; i < vop->lut_len; i++)
27019 + vop_write_lut(vop, i << 2, vop->lut[i]);
27021 + spin_lock(&vop->reg_lock);
27026 + vop->lut_active = true;
27028 + spin_unlock(&vop->reg_lock);
27042 -static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
27047 - int ret, i;
27048 + u32 lut_len = vop->lut_len;
27051 - ret = pm_runtime_get_sync(vop->dev);
27052 - if (ret < 0) {
27053 - DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
27054 - return ret;
27055 - }
27056 + if (regno >= lut_len || !vop->lut)
27059 - ret = vop_core_clks_enable(vop);
27060 - if (WARN_ON(ret < 0))
27061 - goto err_put_pm_runtime;
27062 + r = red * (lut_len - 1) / 0xffff;
27063 + g = green * (lut_len - 1) / 0xffff;
27064 + b = blue * (lut_len - 1) / 0xffff;
27065 + vop->lut[regno] = r * lut_len * lut_len + g * lut_len + b;
27068 - ret = clk_enable(vop->dclk);
27069 - if (WARN_ON(ret < 0))
27070 - goto err_disable_core;
27075 + u32 lut_len = vop->lut_len;
27078 - /*
27079 - * Slave iommu shares power, irq and clock with vop. It was associated
27080 - * automatically with this master device via common driver code.
27081 - * Now that we have enabled the clock we attach it to the shared drm
27082 - * mapping.
27083 - */
27084 - ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
27085 - if (ret) {
27086 - DRM_DEV_ERROR(vop->dev,
27087 - "failed to attach dma mapping, %d\n", ret);
27088 - goto err_disable_dclk;
27089 - }
27090 + if (regno >= lut_len || !vop->lut)
27093 - spin_lock(&vop->reg_lock);
27094 - for (i = 0; i < vop->len; i += 4)
27095 - writel_relaxed(vop->regsbak[i / 4], vop->regs + i);
27096 + r = (vop->lut[regno] / lut_len / lut_len) & (lut_len - 1);
27097 + g = (vop->lut[regno] / lut_len) & (lut_len - 1);
27098 + b = vop->lut[regno] & (lut_len - 1);
27099 + *red = r * 0xffff / (lut_len - 1);
27100 + *green = g * 0xffff / (lut_len - 1);
27101 + *blue = b * 0xffff / (lut_len - 1);
27104 - /*
27105 - * We need to make sure that all windows are disabled before we
27106 - * enable the crtc. Otherwise we might try to scan from a destroyed
27107 - * buffer later.
27108 - *
27109 - * In the case of enable-after-PSR, we don't need to worry about this
27110 - * case since the buffer is guaranteed to be valid and disabling the
27111 - * window will result in screen glitches on PSR exit.
27112 - */
27113 - if (!old_state || !old_state->self_refresh_active) {
27114 - for (i = 0; i < vop->data->win_size; i++) {
27115 - struct vop_win *vop_win = &vop->win[i];
27121 + int len = min(size, vop->lut_len);
27124 - vop_win_disable(vop, vop_win);
27125 - }
27126 - }
27127 + if (!vop->lut)
27128 + return -EINVAL;
27130 - if (vop->data->afbc) {
27131 - struct rockchip_crtc_state *s;
27132 - /*
27133 - * Disable AFBC and forget there was a vop window with AFBC
27134 - */
27135 - VOP_AFBC_SET(vop, enable, 0);
27136 - s = to_rockchip_crtc_state(crtc->state);
27137 - s->enable_afbc = false;
27150 + struct drm_color_lut *lut = vop->gamma_lut;
27153 + for (i = 0; i < vop->lut_len; i++)
27166 + ret = clk_prepare_enable(vop->hclk);
27168 + dev_err(vop->dev, "failed to enable hclk - %d\n", ret);
27172 - vop_cfg_done(vop);
27173 + ret = clk_prepare_enable(vop->dclk);
27175 + dev_err(vop->dev, "failed to enable dclk - %d\n", ret);
27179 - spin_unlock(&vop->reg_lock);
27180 + ret = clk_prepare_enable(vop->aclk);
27182 + dev_err(vop->dev, "failed to enable aclk - %d\n", ret);
27186 - /*
27187 - * At here, vop clock & iommu is enable, R/W vop regs would be safe.
27188 - */
27189 - vop->is_enabled = true;
27190 + ret = pm_runtime_get_sync(vop->dev);
27192 + dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
27196 - spin_lock(&vop->reg_lock);
27197 + memcpy(vop->regsbak, vop->regs, vop->len);
27199 - VOP_REG_SET(vop, common, standby, 1);
27203 - spin_unlock(&vop->reg_lock);
27208 + vop->version = VOP_VERSION(3, 1);
27211 - drm_crtc_vblank_on(crtc);
27212 + vop->is_enabled = true;
27214 - return 0;
27218 - clk_disable(vop->dclk);
27219 -err_disable_core:
27220 - vop_core_clks_disable(vop);
27221 -err_put_pm_runtime:
27222 - pm_runtime_put_sync(vop->dev);
27223 - return ret;
27224 + clk_disable_unprepare(vop->dclk);
27226 + clk_disable_unprepare(vop->hclk);
27229 -static void rockchip_drm_set_win_enabled(struct drm_crtc *crtc, bool enabled)
27232 - struct vop *vop = to_vop(crtc);
27233 - int i;
27245 - spin_lock(&vop->reg_lock);
27251 + for (i = 0; i < vop->num_wins; i++) {
27252 + struct vop_win *win = &vop->win[i];
27255 - for (i = 0; i < vop->data->win_size; i++) {
27256 - struct vop_win *vop_win = &vop->win[i];
27257 - const struct vop_win_data *win = vop_win->data;
27264 - VOP_WIN_SET(vop, win, enable,
27265 - enabled && (vop->win_enabled & BIT(i)));
27266 - }
27267 - vop_cfg_done(vop);
27273 - spin_unlock(&vop->reg_lock);
27276 + vop->aclk_rate = clk_get_rate(vop->aclk);
27277 + clk_set_rate(vop->aclk, vop->aclk_rate / 3);
27278 + vop->aclk_rate_reset = true;
27288 WARN_ON(vop->event);
27290 - if (crtc->state->self_refresh_active)
27291 - rockchip_drm_set_win_enabled(crtc, false);
27292 -
27293 - mutex_lock(&vop->vop_lock);
27294 + if (crtc->state->self_refresh_active) {
27303 -
27304 - if (crtc->state->self_refresh_active)
27305 - goto out;
27312 @@ -721,28 +1647,34 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
27314 spin_lock(&vop->reg_lock);
27316 - VOP_REG_SET(vop, common, standby, 1);
27319 spin_unlock(&vop->reg_lock);
27321 - wait_for_completion(&vop->dsp_hold_completion);
27322 + WARN_ON(!wait_for_completion_timeout(&vop->dsp_hold_completion,
27327 vop->is_enabled = false;
27328 + if (vop->is_iommu_enabled) {
27333 + rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
27334 + vop->is_iommu_enabled = false;
27337 - /*
27338 - * vop standby complete, so iommu detach is safe.
27339 - */
27340 - rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
27341 + pm_runtime_put_sync(vop->dev);
27342 + clk_disable_unprepare(vop->dclk);
27343 + clk_disable_unprepare(vop->aclk);
27344 + clk_disable_unprepare(vop->hclk);
27347 - clk_disable(vop->dclk);
27348 - vop_core_clks_disable(vop);
27349 - pm_runtime_put(vop->dev);
27353 - mutex_unlock(&vop->vop_lock);
27354 -
27355 if (crtc->state->event && !crtc->state->active) {
27356 spin_lock_irq(&crtc->dev->event_lock);
27357 drm_crtc_send_vblank_event(crtc, crtc->state->event);
27358 @@ -752,23 +1684,29 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
27362 -static void vop_plane_destroy(struct drm_plane *plane)
27366 - drm_plane_cleanup(plane);
27367 + if (plane->state->fb)
27368 + drm_framebuffer_get(plane->state->fb);
27373 -static inline bool rockchip_afbc(u64 modifier)
27377 - return modifier == ROCKCHIP_AFBC_MOD;
27378 + if (old_state->fb)
27379 + drm_framebuffer_put(old_state->fb);
27382 -static bool rockchip_mod_supported(struct drm_plane *plane,
27383 - u32 format, u64 modifier)
27390 - if (!rockchip_afbc(modifier)) {
27395 @@ -783,21 +1721,43 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27396 struct drm_crtc *crtc = state->crtc;
27398 struct drm_framebuffer *fb = state->fb;
27399 - struct vop_win *vop_win = to_vop_win(plane);
27400 - const struct vop_win_data *win = vop_win->data;
27406 + struct drm_rect *dest = &vop_plane_state->dest;
27407 + struct drm_rect *src = &vop_plane_state->src;
27410 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
27412 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
27417 - if (!crtc || WARN_ON(!fb))
27418 + crtc = crtc ? crtc : plane->state->crtc;
27420 + plane->state->visible = false;
27424 crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
27426 return -EINVAL;
27428 + src->x1 = state->src_x;
27429 + src->y1 = state->src_y;
27430 + src->x2 = state->src_x + state->src_w;
27431 + src->y2 = state->src_y + state->src_h;
27432 + dest->x1 = state->crtc_x;
27433 + dest->y1 = state->crtc_y;
27434 + dest->x2 = state->crtc_x + state->crtc_w;
27435 + dest->y2 = state->crtc_y + state->crtc_h;
27436 + vop_plane_state->zpos = state->zpos;
27437 + vop_plane_state->blend_mode = state->pixel_blend_mode;
27442 @@ -807,16 +1767,37 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27443 if (!state->visible)
27446 - ret = vop_convert_format(fb->format->format);
27447 - if (ret < 0)
27448 - return ret;
27449 + vop_plane_state->format = vop_convert_format(fb->format->format);
27450 + if (vop_plane_state->format < 0)
27451 + return vop_plane_state->format;
27453 - /*
27454 - * Src.x1 can be odd when do clip, but yuv plane start point
27455 - * need align with 2 pixel.
27456 - */
27457 - if (fb->format->is_yuv && ((state->src.x1 >> 16) % 2)) {
27458 - DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n");
27460 + vop_data = vop->data;
27462 + if (state->src_w >> 16 < 4 || state->src_h >> 16 < 4 ||
27463 + state->crtc_w < 4 || state->crtc_h < 4) {
27464 + DRM_ERROR("Invalid size: %dx%d->%dx%d, min size is 4x4\n",
27465 + state->src_w >> 16, state->src_h >> 16,
27466 + state->crtc_w, state->crtc_h);
27467 + return -EINVAL;
27470 + if (drm_rect_width(src) >> 16 > vop_data->max_input.width ||
27471 + drm_rect_height(src) >> 16 > vop_data->max_input.height) {
27475 + vop_data->max_input.width,
27476 + vop_data->max_input.height);
27477 + return -EINVAL;
27484 + if (fb->format->is_yuv && ((state->src.x1 >> 16) % 2)) {
27486 return -EINVAL;
27489 @@ -825,28 +1806,28 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27490 return -EINVAL;
27493 - if (rockchip_afbc(fb->modifier)) {
27494 - struct vop *vop = to_vop(crtc);
27495 + offset = (src->x1 >> 16) * fb->format->cpp[0];
27496 + vop_plane_state->offset = offset + fb->offsets[0];
27497 + if (state->rotation & DRM_MODE_REFLECT_Y)
27498 + offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
27500 + offset += (src->y1 >> 16) * fb->pitches[0];
27502 - if (!vop->data->afbc) {
27503 - DRM_ERROR("vop does not support AFBC\n");
27504 - return -EINVAL;
27505 - }
27506 + obj = fb->obj[0];
27508 + vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
27509 + if (fb->format->is_yuv) {
27510 + int hsub = fb->format->hsub;
27511 + int vsub = fb->format->vsub;
27513 - ret = vop_convert_afbc_format(fb->format->format);
27514 - if (ret < 0)
27515 - return ret;
27516 + offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub;
27517 + offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
27519 - if (state->src.x1 || state->src.y1) {
27520 - DRM_ERROR("AFBC does not support offset display, xpos=%d, ypos=%d, offset=%d\n", state->src.x1,…
27521 - return -EINVAL;
27522 - }
27523 + uv_obj = fb->obj[1];
27526 - if (state->rotation && state->rotation != DRM_MODE_ROTATE_0) {
27527 - DRM_ERROR("No rotation support in AFBC, rotation=%d\n",
27528 - state->rotation);
27529 - return -EINVAL;
27530 - }
27531 + dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
27532 + vop_plane_state->uv_mst = dma_addr;
27536 @@ -855,15 +1836,33 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27540 - struct vop_win *vop_win = to_vop_win(plane);
27542 struct vop *vop = to_vop(old_state->crtc);
27545 + to_vop_plane_state(plane->state);
27548 if (!old_state->crtc)
27551 spin_lock(&vop->reg_lock);
27553 - vop_win_disable(vop, vop_win);
27561 + if (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 5 &&
27562 + win->win_id == 2)
27566 + kfree(vop_plane_state->planlist);
27567 + vop_plane_state->planlist = NULL;
27570 spin_unlock(&vop->reg_lock);
27572 @@ -873,26 +1872,46 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
27574 struct drm_plane_state *state = plane->state;
27575 struct drm_crtc *crtc = state->crtc;
27576 - struct vop_win *vop_win = to_vop_win(plane);
27577 - const struct vop_win_data *win = vop_win->data;
27578 - const struct vop_win_yuv2yuv_data *win_yuv2yuv = vop_win->yuv2yuv_data;
27582 + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
27584 struct vop *vop = to_vop(state->crtc);
27585 struct drm_framebuffer *fb = state->fb;
27586 - unsigned int actual_w, actual_h;
27590 - struct drm_rect *src = &state->src;
27591 - struct drm_rect *dest = &state->dst;
27592 - struct drm_gem_object *obj, *uv_obj;
27593 - struct rockchip_gem_object *rk_obj, *rk_uv_obj;
27594 - unsigned long offset;
27595 - dma_addr_t dma_addr;
27596 + struct drm_rect *src = &vop_plane_state->src;
27597 + struct drm_rect *dest = &vop_plane_state->dest;
27598 + const uint32_t *y2r_table = vop_plane_state->y2r_table;
27599 + const uint32_t *r2r_table = vop_plane_state->r2r_table;
27600 + const uint32_t *r2y_table = vop_plane_state->r2y_table;
27602 - bool rb_swap;
27603 - int win_index = VOP_WIN_TO_INDEX(vop_win);
27604 - int format;
27606 int is_yuv = fb->format->is_yuv;
27607 - int i;
27619 + obj = fb->obj[0];
27622 + num_pages = rk_obj->num_pages;
27623 + pages = rk_obj->pages;
27625 + if (fb->modifier == DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16))
27633 @@ -908,206 +1927,427 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
27637 - obj = fb->obj[0];
27638 - rk_obj = to_rockchip_obj(obj);
27639 -
27640 + mode = &crtc->state->adjusted_mode;
27643 - act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
27645 - dsp_info = (drm_rect_height(dest) - 1) << 16;
27646 - dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
27647 -
27648 - dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
27649 - dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
27650 - dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
27652 + if (dest->x1 + dsp_w > adjusted_mode->hdisplay) {
27653 + DRM_ERROR("%s win%d dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
27654 + crtc->name, win->win_id, dest->x1, dsp_w, adjusted_mode->hdisplay);
27655 + dsp_w = adjusted_mode->hdisplay - dest->x1;
27661 + if (dest->y1 + dsp_h > adjusted_mode->vdisplay) {
27662 + DRM_ERROR("%s win%d dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
27663 + crtc->name, win->win_id, dest->y1, dsp_h, adjusted_mode->vdisplay);
27664 + dsp_h = adjusted_mode->vdisplay - dest->y1;
27670 - offset = (src->x1 >> 16) * fb->format->cpp[0];
27671 - offset += (src->y1 >> 16) * fb->pitches[0];
27672 - dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
27673 + act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
27675 - /*
27676 - * For y-mirroring we need to move address
27677 - * to the beginning of the last line.
27678 - */
27679 - if (state->rotation & DRM_MODE_REFLECT_Y)
27680 - dma_addr += (actual_h - 1) * fb->pitches[0];
27681 + dsp_info = (dsp_h - 1) << 16;
27682 + dsp_info |= (dsp_w - 1) & 0xffff;
27684 - format = vop_convert_format(fb->format->format);
27685 + dsp_stx = dest->x1 + mode->crtc_htotal - mode->crtc_hsync_start;
27686 + dsp_sty = dest->y1 + mode->crtc_vtotal - mode->crtc_vsync_start;
27689 + s = to_rockchip_crtc_state(crtc->state);
27690 spin_lock(&vop->reg_lock);
27692 - if (rockchip_afbc(fb->modifier)) {
27693 - int afbc_format = vop_convert_afbc_format(fb->format->format);
27694 -
27695 - VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16);
27696 - VOP_AFBC_SET(vop, hreg_block_split, 0);
27697 - VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win));
27698 - VOP_AFBC_SET(vop, hdr_ptr, dma_addr);
27699 - VOP_AFBC_SET(vop, pic_size, act_info);
27700 - }
27701 -
27702 - VOP_WIN_SET(vop, win, format, format);
27703 + VOP_WIN_SET(vop, win, format, vop_plane_state->format);
27704 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
27705 - VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
27706 - VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
27707 - VOP_WIN_SET(vop, win, y_mir_en,
27708 + VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
27711 (state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0);
27712 - VOP_WIN_SET(vop, win, x_mir_en,
27714 (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
27717 - int hsub = fb->format->hsub;
27718 - int vsub = fb->format->vsub;
27719 - int bpp = fb->format->cpp[1];
27720 -
27721 - uv_obj = fb->obj[1];
27722 - rk_uv_obj = to_rockchip_obj(uv_obj);
27723 -
27724 - offset = (src->x1 >> 16) * bpp / hsub;
27725 - offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
27726 -
27727 - dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
27728 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
27729 - VOP_WIN_SET(vop, win, uv_mst, dma_addr);
27730 -
27731 - for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) {
27732 - VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop,
27733 - win_yuv2yuv,
27734 - y2r_coefficients[i],
27735 - bt601_yuv2rgb[i]);
27736 - }
27737 + VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst);
27739 + VOP_WIN_SET(vop, win, fmt_10, is_yuv_10bit(fb->format->format));
27740 + VOP_WIN_SET(vop, win, fmt_yuyv, is_yuyv_format(fb->format->format));
27742 if (win->phy->scl)
27745 - fb->format);
27746 + fb->format->format);
27752 rb_swap = has_rb_swapped(fb->format->format);
27753 - VOP_WIN_SET(vop, win, rb_swap, rb_swap);
27754 -
27756 - * Blending win0 with the background color doesn't seem to work
27757 - * correctly. We only get the background color, no matter the contents
27758 - * of the win0 framebuffer. However, blending pre-multiplied color
27759 - * with the default opaque black default background color is a no-op,
27760 - * so we can just disable blending to get the correct result.
27763 - if (fb->format->has_alpha && win_index > 0) {
27764 + if ((fb->format->format == DRM_FORMAT_RGB888 || fb->format->format == DRM_FORMAT_BGR888) &&
27765 + VOP_MAJOR(vop->version) == 3)
27769 + global_alpha_en = (vop_plane_state->global_alpha == 0xff) ? 0 : 1;
27770 + if ((is_alpha_support(fb->format->format) || global_alpha_en) &&
27771 + (s->dsp_layer_sel & 0x3) != win->win_id) {
27774 + if (is_alpha_support(fb->format->format) && global_alpha_en)
27776 + else if (is_alpha_support(fb->format->format))
27785 - SRC_BLEND_M0(ALPHA_PER_PIX) |
27786 - SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
27787 - SRC_FACTOR_M0(ALPHA_ONE);
27793 -
27794 - VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL);
27795 - VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX);
27797 + vop_plane_state->blend_mode == DRM_MODE_BLEND_PREMULTI ? 1 : 0);
27804 -
27805 + VOP_WIN_SET(vop, win, global_alpha_val, vop_plane_state->global_alpha);
27807 + VOP_WIN_SET(vop, win, csc_mode, vop_plane_state->csc_mode);
27808 + if (win->csc) {
27809 + vop_load_csc_table(vop, win->csc->y2r_offset, y2r_table);
27810 + vop_load_csc_table(vop, win->csc->r2r_offset, r2r_table);
27811 + vop_load_csc_table(vop, win->csc->r2y_offset, r2y_table);
27812 + VOP_WIN_SET_EXT(vop, win, csc, y2r_en, vop_plane_state->y2r_en);
27813 + VOP_WIN_SET_EXT(vop, win, csc, r2r_en, vop_plane_state->r2r_en);
27814 + VOP_WIN_SET_EXT(vop, win, csc, r2y_en, vop_plane_state->r2y_en);
27815 + VOP_WIN_SET_EXT(vop, win, csc, csc_mode, vop_plane_state->csc_mode);
27818 - vop->win_enabled |= BIT(win_index);
27820 spin_unlock(&vop->reg_lock);
27822 + * spi interface(vop_plane_state->yrgb_kvaddr, fb->pixel_format,
27825 + vop->is_iommu_needed = true;
27827 + kfree(vop_plane_state->planlist);
27828 + vop_plane_state->planlist = NULL;
27832 + planlist->dump_info.AFBC_flag = AFBC_flag;
27833 + planlist->dump_info.area_id = win->area_id;
27834 + planlist->dump_info.win_id = win->win_id;
27835 + planlist->dump_info.yuv_format =
27836 + is_yuv_support(fb->format->format);
27837 + planlist->dump_info.num_pages = num_pages;
27838 + planlist->dump_info.pages = pages;
27839 + planlist->dump_info.offset = vop_plane_state->offset;
27840 + planlist->dump_info.pitches = fb->pitches[0];
27841 + planlist->dump_info.height = actual_h;
27842 + planlist->dump_info.format = fb->format;
27843 + list_add_tail(&planlist->entry, &vop->rockchip_crtc.vop_dump_list_head);
27844 + vop_plane_state->planlist = planlist;
27849 + if (vop->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
27850 + vop->rockchip_crtc.vop_dump_times > 0) {
27851 + rockchip_drm_dump_plane_buffer(&planlist->dump_info, vop->rockchip_crtc.frame_count);
27852 + vop->rockchip_crtc.vop_dump_times--;
27857 -static int vop_plane_atomic_async_check(struct drm_plane *plane,
27858 - struct drm_plane_state *state)
27898 - struct vop_win *vop_win = to_vop_win(plane);
27899 - const struct vop_win_data *win = vop_win->data;
27900 - int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
27901 - DRM_PLANE_HELPER_NO_SCALING;
27902 - int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
27903 - DRM_PLANE_HELPER_NO_SCALING;
27904 - struct drm_crtc_state *crtc_state;
27910 - if (plane != state->crtc->cursor)
27911 - return -EINVAL;
27912 + state = drm_atomic_state_alloc(plane->dev);
27914 + return -ENOMEM;
27916 - if (!plane->state)
27917 - return -EINVAL;
27918 + state->acquire_ctx = ctx;
27925 - if (!plane->state->fb)
27926 - return -EINVAL;
27933 + plane_state->crtc_x = crtc_x;
27934 + plane_state->crtc_y = crtc_y;
27935 + plane_state->crtc_w = crtc_w;
27936 + plane_state->crtc_h = crtc_h;
27937 + plane_state->src_x = src_x;
27938 + plane_state->src_y = src_y;
27939 + plane_state->src_w = src_w;
27940 + plane_state->src_h = src_h;
27942 + if (plane == crtc->cursor || vop_plane_state->async_commit)
27943 + state->legacy_cursor_update = true;
27972 + state = drm_atomic_state_alloc(plane->dev);
27974 + return -ENOMEM;
27976 + state->acquire_ctx = ctx;
27984 - if (state->state)
27985 - crtc_state = drm_atomic_get_existing_crtc_state(state->state,
27986 - state->crtc);
27987 - else /* Special case for asynchronous cursor updates. */
27988 - crtc_state = plane->crtc->state;
27989 + if ((plane_state->crtc && plane_state->crtc->cursor == plane) ||
27990 + vop_plane_state->async_commit)
27991 + plane_state->state->legacy_cursor_update = true;
27993 - return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
27994 - min_scale, max_scale,
27995 - true, true);
28006 -static void vop_plane_atomic_async_update(struct drm_plane *plane,
28007 - struct drm_plane_state *new_state)
28010 - struct vop *vop = to_vop(plane->state->crtc);
28011 - struct drm_framebuffer *old_fb = plane->state->fb;
28015 - plane->state->crtc_x = new_state->crtc_x;
28016 - plane->state->crtc_y = new_state->crtc_y;
28017 - plane->state->crtc_h = new_state->crtc_h;
28018 - plane->state->crtc_w = new_state->crtc_w;
28019 - plane->state->src_x = new_state->src_x;
28020 - plane->state->src_y = new_state->src_y;
28021 - plane->state->src_h = new_state->src_h;
28022 - plane->state->src_w = new_state->src_w;
28023 - swap(plane->state->fb, new_state->fb);
28027 + to_vop_plane_state(plane->state);
28030 + if (plane->state && plane->state->fb)
28031 + __drm_atomic_helper_plane_destroy_state(plane->state);
28037 - if (vop->is_enabled) {
28038 - vop_plane_atomic_update(plane, plane->state);
28039 - spin_lock(&vop->reg_lock);
28040 - vop_cfg_done(vop);
28041 - spin_unlock(&vop->reg_lock);
28042 + __drm_atomic_helper_plane_reset(plane, &vop_plane_state->base);
28043 + win->state.zpos = win->zpos;
28044 + vop_plane_state->global_alpha = 0xff;
28047 - /*
28048 - * A scanout can still be occurring, so we can't drop the
28049 - * reference to the old framebuffer. To solve this we get a
28050 - * reference to old_fb and set a worker to release it later.
28051 - * FIXME: if we perform 500 async_update calls before the
28052 - * vblank, then we can have 500 different framebuffers waiting
28053 - * to be released.
28054 - */
28055 - if (old_fb && plane->state->fb != old_fb) {
28056 - drm_framebuffer_get(old_fb);
28057 - WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
28058 - drm_flip_work_queue(&vop->fb_unref_work, old_fb);
28059 - set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
28060 - }
28067 + if (WARN_ON(!plane->state))
28070 + old_vop_plane_state = to_vop_plane_state(plane->state);
28077 + &vop_plane_state->base);
28079 + return &vop_plane_state->base;
28097 + struct rockchip_drm_private *private = plane->dev->dev_private;
28101 + if (property == private->eotf_prop) {
28102 + plane_state->eotf = val;
28106 + if (property == private->color_space_prop) {
28107 + plane_state->color_space = val;
28111 + if (property == private->async_commit_prop) {
28112 + plane_state->async_commit = val;
28116 + if (property == win->color_key_prop) {
28117 + plane_state->color_key = val;
28122 + property->base.id, property->name);
28124 + return -EINVAL;
28127 -static const struct drm_plane_helper_funcs plane_helper_funcs = {
28128 - .atomic_check = vop_plane_atomic_check,
28129 - .atomic_update = vop_plane_atomic_update,
28130 - .atomic_disable = vop_plane_atomic_disable,
28131 - .atomic_async_check = vop_plane_atomic_async_check,
28132 - .atomic_async_update = vop_plane_atomic_async_update,
28133 - .prepare_fb = drm_gem_fb_prepare_fb,
28134 -};
28142 + struct rockchip_drm_private *private = plane->dev->dev_private;
28144 + if (property == private->eotf_prop) {
28145 + *val = plane_state->eotf;
28149 + if (property == private->color_space_prop) {
28150 + *val = plane_state->color_space;
28154 + if (property == private->async_commit_prop) {
28155 + *val = plane_state->async_commit;
28159 + if (property == private->share_id_prop) {
28161 + struct drm_mode_object *obj = &plane->base;
28163 + for (i = 0; i < obj->properties->count; i++) {
28164 + if (obj->properties->properties[i] == property) {
28165 + *val = obj->properties->values[i];
28171 + if (property == win->color_key_prop) {
28172 + *val = plane_state->color_key;
28177 + property->base.id, property->name);
28179 + return -EINVAL;
28183 - .update_plane = drm_atomic_helper_update_plane,
28184 - .disable_plane = drm_atomic_helper_disable_plane,
28188 - .reset = drm_atomic_helper_plane_reset,
28189 - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
28190 - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
28191 - .format_mod_supported = rockchip_mod_supported,
28201 @@ -1120,8 +2360,13 @@ static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
28203 spin_lock_irqsave(&vop->irq_lock, flags);
28205 - VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1);
28206 - VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1);
28207 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7) {
28215 spin_unlock_irqrestore(&vop->irq_lock, flags);
28217 @@ -1138,258 +2383,1457 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
28219 spin_lock_irqsave(&vop->irq_lock, flags);
28221 - VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0);
28222 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7)
28227 spin_unlock_irqrestore(&vop->irq_lock, flags);
28230 -static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
28231 - const struct drm_display_mode *mode,
28232 - struct drm_display_mode *adjusted_mode)
28236 + struct drm_device *drm = crtc->dev;
28238 - unsigned long rate;
28242 - /*
28243 - * Clock craziness.
28244 - *
28245 - * Key points:
28246 - *
28247 - * - DRM works in in kHz.
28248 - * - Clock framework works in Hz.
28249 - * - Rockchip's clock driver picks the clock rate that is the
28250 - * same _OR LOWER_ than the one requested.
28251 - *
28252 - * Action plan:
28253 - *
28254 - * 1. When DRM gives us a mode, we should add 999 Hz to it. That way
28255 - * if the clock we need is 60000001 Hz (~60 MHz) and DRM tells us to
28256 - * make 60000 kHz then the clock framework will actually give us
28257 - * the right clock.
28258 - *
28259 - * NOTE: if the PLL (maybe through a divider) could actually make
28260 - * a clock rate 999 Hz higher instead of the one we want then this
28261 - * could be a problem. Unfortunately there's not much we can do
28262 - * since it's baked into DRM to use kHz. It shouldn't matter in
28263 - * practice since Rockchip PLLs are controlled by tables and
28264 - * even if there is a divider in the middle I wouldn't expect PLL
28265 - * rates in the table that are just a few kHz different.
28266 - *
28267 - * 2. Get the clock framework to round the rate for us to tell us
28268 - * what it will actually make.
28269 - *
28270 - * 3. Store the rounded up rate so that we don't need to worry about
28271 - * this in the actual clk_set_rate().
28272 - */
28273 - rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
28274 - adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
28275 + spin_lock_irqsave(&drm->event_lock, flags);
28276 + e = vop->event;
28277 + if (e && e->base.file_priv == file_priv) {
28278 + vop->event = NULL;
28280 - return true;
28281 + /* e->base.destroy(&e->base);//todo */
28282 + file_priv->event_space += sizeof(e->event);
28284 + spin_unlock_irqrestore(&drm->event_lock, flags);
28287 -static bool vop_dsp_lut_is_enabled(struct vop *vop)
28290 - return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en);
28291 -}
28292 + struct rockchip_drm_private *private = crtc->dev->dev_private;
28297 -static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc)
28298 -{
28299 - struct drm_color_lut *lut = crtc->state->gamma_lut->data;
28300 - unsigned int i;
28301 + if (on == vop->loader_protect)
28305 + if (vop->dclk_source) {
28308 + parent = clk_get_parent(vop->dclk_source);
28310 + if (clk_is_match(private->default_pll.pll, parent))
28311 + vop->pll = &private->default_pll;
28312 + else if (clk_is_match(private->hdmi_pll.pll, parent))
28313 + vop->pll = &private->hdmi_pll;
28314 + if (vop->pll)
28315 + vop->pll->use_count++;
28319 - for (i = 0; i < crtc->gamma_size; i++) {
28320 - u32 word;
28324 + vop->loader_protect = true;
28328 - word = (drm_color_lut_extract(lut[i].red, 10) << 20) |
28329 - (drm_color_lut_extract(lut[i].green, 10) << 10) |
28330 - drm_color_lut_extract(lut[i].blue, 10);
28331 - writel(word, vop->lut_regs + i * 4);
28332 + if (vop->dclk_source && vop->pll) {
28333 + vop->pll->use_count--;
28334 + vop->pll = NULL;
28336 + vop->loader_protect = false;
28342 -static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
28343 - struct drm_crtc_state *old_state)
28344 -{
28345 - struct drm_crtc_state *state = crtc->state;
28346 - unsigned int idle;
28347 - int ret;
28356 - if (!vop->lut_regs)
28357 - return;
28358 - /*
28359 - * To disable gamma (gamma_lut is null) or to write
28360 - * an update to the LUT, clear dsp_lut_en.
28361 - */
28362 - spin_lock(&vop->reg_lock);
28363 - VOP_REG_SET(vop, common, dsp_lut_en, 0);
28364 - vop_cfg_done(vop);
28365 - spin_unlock(&vop->reg_lock);
28369 + struct drm_plane_state *state = plane->state;
28372 + struct drm_framebuffer *fb = state->fb;
28381 + DEBUG_PRINT(" win%d-%d: %s\n", win->win_id, win->area_id,
28382 + state->crtc ? "ACTIVE" : "DISABLED");
28386 - /*
28387 - * In order to write the LUT to the internal memory,
28388 - * we need to first make sure the dsp_lut_en bit is cleared.
28389 - */
28390 - ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
28391 - idle, !idle, 5, 30 * 1000);
28392 - if (ret) {
28393 - DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
28394 - return;
28395 + src = &pstate->src;
28396 + dest = &pstate->dest;
28398 + drm_get_format_name(fb->format->format, &format_name);
28401 + fb->modifier == afbdc_format ? "[AFBC]" : "",
28402 + pstate->eotf ? " HDR" : " SDR", pstate->eotf,
28403 + pstate->color_space);
28405 + pstate->y2r_en, pstate->r2r_en, pstate->r2y_en,
28406 + pstate->csc_mode);
28407 + DEBUG_PRINT("\tzpos: %d\n", pstate->zpos);
28408 + DEBUG_PRINT("\tsrc: pos[%dx%d] rect[%dx%d]\n", src->x1 >> 16,
28409 + src->y1 >> 16, drm_rect_width(src) >> 16,
28411 + DEBUG_PRINT("\tdst: pos[%dx%d] rect[%dx%d]\n", dest->x1, dest->y1,
28414 + for (i = 0; i < fb->format->num_planes; i++) {
28415 + obj = fb->obj[0];
28417 + fb_addr = rk_obj->dma_addr + fb->offsets[0];
28420 + i, &fb_addr, fb->pitches[i], fb->offsets[i]);
28423 - if (!state->gamma_lut)
28424 - return;
28425 -
28426 - spin_lock(&vop->reg_lock);
28427 - vop_crtc_write_gamma_lut(vop, crtc);
28428 - VOP_REG_SET(vop, common, dsp_lut_en, 1);
28437 + drm_connector_list_iter_begin(crtc->dev, &conn_iter);
28439 + if (crtc->state->connector_mask & drm_connector_mask(connector))
28440 + DEBUG_PRINT(" Connector: %s\n", connector->name);
28449 + struct drm_crtc_state *crtc_state = crtc->state;
28450 + struct drm_display_mode *mode = &crtc->state->adjusted_mode;
28451 + struct rockchip_crtc_state *state = to_rockchip_crtc_state(crtc->state);
28452 + bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
28456 + DEBUG_PRINT("VOP [%s]: %s\n", dev_name(vop->dev),
28457 + crtc_state->active ? "ACTIVE" : "DISABLED");
28459 + if (!crtc_state->active)
28463 + DEBUG_PRINT("\tbus_format[%x]: %s\n", state->bus_format,
28464 + drm_get_bus_format_name(state->bus_format));
28466 + state->yuv_overlay, state->output_mode);
28468 + state->color_space);
28470 + mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
28473 + mode->clock, mode->crtc_clock, mode->type, mode->flags);
28474 + DEBUG_PRINT("\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
28475 + mode->hsync_end, mode->htotal);
28476 + DEBUG_PRINT("\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
28477 + mode->vsync_end, mode->vtotal);
28479 + for (i = 0; i < vop->num_wins; i++) {
28480 + plane = &vop->win[i].base;
28484 + state->hdr.sdr2hdr_state.bt1886eotf_post_conv_en,
28485 + state->hdr.hdr2sdr_en);
28487 + state->hdr.sdr2hdr_state.bt1886eotf_pre_conv_en);
28489 + state->post_r2y_en, state->post_y2r_en,
28490 + state->post_csc_mode);
28498 + struct drm_crtc_state *crtc_state = crtc->state;
28499 + int dump_len = vop->len > 0x400 ? 0x400 : vop->len;
28502 + if (!crtc_state->active)
28514 + struct drm_info_node *node = s->private;
28515 + struct vop *vop = node->info_ent->data;
28518 + if (!vop->lut || !vop->lut_active || !vop->lut_regs)
28521 + for (i = 0; i < vop->lut_len; i++) {
28524 + DEBUG_PRINT("0x%08x ", vop->lut[i]);
28542 + vop->debugfs = debugfs_create_dir(dev_name(vop->dev),
28543 + minor->debugfs_root);
28545 + if (!vop->debugfs)
28546 + return -ENOMEM;
28548 + vop->debugfs_files = kmemdup(vop_debugfs_files,
28551 + if (!vop->debugfs_files) {
28552 + ret = -ENOMEM;
28556 + rockchip_drm_add_dump_buffer(crtc, vop->debugfs);
28559 + vop->debugfs_files[i].data = vop;
28561 + drm_debugfs_create_files(vop->debugfs_files, ARRAY_SIZE(vop_debugfs_files),
28562 + vop->debugfs, minor);
28566 + debugfs_remove(vop->debugfs);
28567 + vop->debugfs = NULL;
28575 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
28576 + const struct vop_data *vop_data = vop->data;
28577 + int request_clock = mode->clock;
28580 + if (mode->hdisplay > vop_data->max_output.width)
28583 + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
28584 + VOP_MAJOR(vop->version) == 3 &&
28585 + VOP_MINOR(vop->version) <= 2)
28588 + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
28590 + clock = clk_round_rate(vop->dclk, request_clock * 1000) / 1000;
28595 + if (s->output_type == DRM_MODE_CONNECTOR_HDMIA ||
28596 + s->output_type == DRM_MODE_CONNECTOR_DisplayPort)
28614 + return pa->y1 - pb->y2;
28620 + struct vop_win *win = to_vop_win(pstate->plane);
28621 + struct drm_crtc *crtc = pstate->crtc;
28623 + struct drm_framebuffer *fb = pstate->fb;
28624 + struct drm_rect *dest = &vop_plane_state->dest;
28625 + struct drm_rect *src = &vop_plane_state->src;
28626 + int bpp = fb->format->cpp[0] << 3;
28677 + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
28678 + u16 htotal = adjusted_mode->crtc_htotal;
28679 + u16 vdisplay = adjusted_mode->crtc_vdisplay;
28680 + int clock = adjusted_mode->crtc_clock;
28687 + struct drm_atomic_state *state = crtc_state->state;
28697 + if (!vop->rockchip_crtc.vop_dump_list_init_flag) {
28698 + INIT_LIST_HEAD(&vop->rockchip_crtc.vop_dump_list_head);
28699 + vop->rockchip_crtc.vop_dump_list_init_flag = true;
28701 + list_for_each_entry_safe(pos, n, &vop->rockchip_crtc.vop_dump_list_head, entry) {
28702 + list_del(&pos->entry);
28704 + if (vop->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
28705 + vop->rockchip_crtc.vop_dump_times > 0) {
28706 + vop->rockchip_crtc.frame_count++;
28713 + vop_bw_info->plane_num += plane_num;
28717 + return -ENOMEM;
28723 + if (pstate->crtc != crtc || !pstate->fb)
28727 + afbc_fac = rockchip_afbc(plane, pstate->fb->modifier) ? 2 : 1;
28730 + pbandwidth[cnt].y1 = vop_plane_state->dest.y1;
28731 + pbandwidth[cnt].y2 = vop_plane_state->dest.y2;
28734 + act_w = drm_rect_width(&pstate->src) >> 16;
28735 + act_h = drm_rect_height(&pstate->src) >> 16;
28736 + cpp = pstate->fb->format->cpp[0];
28738 + vop_bw_info->frame_bw_mbyte += act_w * act_h / 1000 * cpp * drm_mode_vrefresh(adjusted_mode) / 1…
28744 + vop_bw_info->line_bw_mbyte = vop_calc_max_bandwidth(pbandwidth, 0, cnt, vdisplay);
28753 + vop_bw_info->line_bw_mbyte = line_bw_mbyte;
28755 + return vop_bw_info->line_bw_mbyte;
28765 + mutex_lock(&vop->vop_lock);
28766 + if (!vop->is_enabled) {
28767 + mutex_unlock(&vop->vop_lock);
28772 + mutex_unlock(&vop->vop_lock);
28787 - spin_unlock(&vop->reg_lock);
28791 + dev_err(vop->dev, "wait mode 0x%x timeout\n", mode);
28795 -static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
28796 - struct drm_crtc_state *old_crtc_state)
28806 + state = to_rockchip_crtc_state(crtc->state);
28813 + mutex_lock(&vop->vop_lock);
28814 + if (vop && vop->is_enabled) {
28832 + mutex_unlock(&vop->vop_lock);
28838 + vop_set_out_mode(vop, state->output_mode);
28847 + if (!vop->is_enabled)
28848 + return -ENODEV;
28850 + mutex_lock(&vop->vop_lock);
28853 + ret = -EBUSY;
28857 + reinit_completion(&vop->line_flag_completion);
28860 + jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
28865 + DRM_DEV_ERROR(vop->dev, "timeout waiting for lineflag IRQ\n");
28866 + ret = -ETIMEDOUT;
28871 + mutex_unlock(&vop->vop_lock);
28892 + const struct vop_data *vop_data = vop->data;
28894 + if (mode->hdisplay > vop_data->max_output.width)
28900 + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
28901 + adj_mode->crtc_clock *= 2;
28903 + adj_mode->crtc_clock =
28904 + DIV_ROUND_UP(clk_round_rate(vop->dclk, adj_mode->crtc_clock * 1000),
28913 + to_rockchip_crtc_state(crtc->state);
28921 + if (vop->mcu_timing.mcu_pix_total)
28924 + switch (s->bus_format) {
28957 + s->output_mode == ROCKCHIP_OUT_MODE_AAAA ? 0 : 1);
28964 + to_rockchip_crtc_state(crtc->state);
28968 + if ((s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
28969 + !(vop->data->feature & VOP_FEATURE_OUTPUT_10BIT)) ||
28970 + (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) >= 12 &&
28971 + s->output_if & VOP_OUTPUT_IF_BT656))
28972 + s->output_mode = ROCKCHIP_OUT_MODE_P888;
28974 + if (is_uv_swap(s->bus_format, s->output_mode))
28979 + VOP_CTRL_SET(vop, out_mode, s->output_mode);
28983 + s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0);
28985 + s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0);
28987 + VOP_CTRL_SET(vop, overlay_mode, s->yuv_overlay);
28988 + VOP_CTRL_SET(vop, dsp_out_yuv, is_yuv_output(s->bus_format));
28991 - * Only update GAMMA if the 'active' flag is not changed,
28992 - * otherwise it's updated by .atomic_enable.
28995 - if (crtc->state->color_mgmt_changed &&
28996 - !crtc->state->active_changed)
28997 - vop_crtc_gamma_set(vop, crtc, old_crtc_state);
28998 + if (!is_yuv_output(s->bus_format))
29000 + else if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) == 8 &&
29001 + s->hdr.pre_overlay)
29003 + else if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 5)
29016 + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
29017 + u16 hsync_len = adjusted_mode->crtc_hsync_end -
29018 + adjusted_mode->crtc_hsync_start;
29019 + u16 hdisplay = adjusted_mode->crtc_hdisplay;
29020 + u16 htotal = adjusted_mode->crtc_htotal;
29021 + u16 hact_st = adjusted_mode->crtc_htotal -
29022 + adjusted_mode->crtc_hsync_start;
29024 + u16 vdisplay = adjusted_mode->crtc_vdisplay;
29025 + u16 vtotal = adjusted_mode->crtc_vtotal;
29026 + u16 vsync_len = adjusted_mode->crtc_vsync_end -
29027 + adjusted_mode->crtc_vsync_start;
29028 + u16 vact_st = adjusted_mode->crtc_vtotal -
29029 + adjusted_mode->crtc_vsync_start;
29035 + u32 crtc_clock = adjusted_mode->crtc_clock * 100;
29041 + crtc_clock != clk_get_rate(vop->dclk))
29055 + VOP_CTRL_SET(vop, mcu_pix_total, vop->mcu_timing.mcu_pix_total);
29056 + VOP_CTRL_SET(vop, mcu_cs_pst, vop->mcu_timing.mcu_cs_pst);
29057 + VOP_CTRL_SET(vop, mcu_cs_pend, vop->mcu_timing.mcu_cs_pend);
29058 + VOP_CTRL_SET(vop, mcu_rw_pst, vop->mcu_timing.mcu_rw_pst);
29059 + VOP_CTRL_SET(vop, mcu_rw_pend, vop->mcu_timing.mcu_rw_pend);
29066 - const struct vop_data *vop_data = vop->data;
29067 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
29068 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
29069 - u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
29070 - u16 hdisplay = adjusted_mode->hdisplay;
29071 - u16 htotal = adjusted_mode->htotal;
29072 - u16 hact_st = adjusted_mode->htotal - adjusted_mode->hsync_start;
29073 + u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
29074 + u16 hdisplay = adjusted_mode->crtc_hdisplay;
29075 + u16 htotal = adjusted_mode->crtc_htotal;
29076 + u16 hact_st = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_start;
29078 - u16 vdisplay = adjusted_mode->vdisplay;
29079 - u16 vtotal = adjusted_mode->vtotal;
29080 - u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
29081 - u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
29082 + u16 vdisplay = adjusted_mode->crtc_vdisplay;
29083 + u16 vtotal = adjusted_mode->crtc_vtotal;
29084 + u16 vsync_len = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
29085 + u16 vact_st = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
29087 - uint32_t pin_pol, val;
29088 - int dither_bpc = s->output_bpc ? s->output_bpc : 10;
29089 - int ret;
29094 + bool interlaced = !!(adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE);
29098 if (old_state && old_state->self_refresh_active) {
29100 - rockchip_drm_set_win_enabled(crtc, true);
29101 + if (vop->aclk_rate_reset)
29102 + clk_set_rate(vop->aclk, vop->aclk_rate);
29103 + vop->aclk_rate_reset = false;
29110 + DRM_DEV_INFO(vop->dev, "Update mode to %dx%d%s%d, type: %d\n",
29112 + drm_mode_vrefresh(adjusted_mode), s->output_type);
29116 + s->mode_update = vop_crtc_mode_update(crtc);
29117 + if (s->mode_update)
29120 - * If we have a GAMMA LUT in the state, then let's make sure
29121 - * it's updated. We might be coming out of suspend,
29122 - * which means the LUT internal memory needs to be re-written.
29125 - if (crtc->state->gamma_lut)
29126 - vop_crtc_gamma_set(vop, crtc, old_state);
29127 + if (vop->lut_active)
29130 - mutex_lock(&vop->vop_lock);
29131 + if (vop->mcu_timing.mcu_pix_total)
29134 - WARN_ON(vop->event);
29135 + dclk_inv = (s->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
29137 - ret = vop_enable(crtc, old_state);
29138 - if (ret) {
29139 - mutex_unlock(&vop->vop_lock);
29140 - DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
29141 - return;
29143 + val = (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ?
29145 + val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ?
29149 + if (vop->dclk_source && vop->pll && vop->pll->pll) {
29150 + if (clk_set_parent(vop->dclk_source, vop->pll->pll))
29151 + DRM_DEV_ERROR(vop->dev,
29154 - pin_pol = (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ?
29155 - BIT(HSYNC_POSITIVE) : 0;
29156 - pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
29157 - BIT(VSYNC_POSITIVE) : 0;
29158 - VOP_REG_SET(vop, output, pin_pol, pin_pol);
29159 - VOP_REG_SET(vop, output, mipi_dual_channel_en, 0);
29161 switch (s->output_type) {
29164 - VOP_REG_SET(vop, output, rgb_dclk_pol, 1);
29165 - VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
29166 - VOP_REG_SET(vop, output, rgb_en, 1);
29174 + if (s->output_if & VOP_OUTPUT_IF_BT1120) {
29176 + yc_swap = is_yc_swap(s->bus_format);
29179 + } else if (s->output_if & VOP_OUTPUT_IF_BT656) {
29184 - VOP_REG_SET(vop, output, edp_dclk_pol, 1);
29185 - VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
29186 - VOP_REG_SET(vop, output, edp_en, 1);
29192 - VOP_REG_SET(vop, output, hdmi_dclk_pol, 1);
29193 - VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
29194 - VOP_REG_SET(vop, output, hdmi_en, 1);
29200 - VOP_REG_SET(vop, output, mipi_dclk_pol, 1);
29201 - VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
29202 - VOP_REG_SET(vop, output, mipi_en, 1);
29203 - VOP_REG_SET(vop, output, mipi_dual_channel_en,
29204 - !!(s->output_flags & ROCKCHIP_OUTPUT_DSI_DUAL));
29209 + !!(s->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE));
29211 + !!(s->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) ||
29212 + vop->dual_channel_swap);
29215 - VOP_REG_SET(vop, output, dp_dclk_pol, 0);
29216 - VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
29217 - VOP_REG_SET(vop, output, dp_en, 1);
29237 - DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
29238 - s->output_type);
29239 + DRM_ERROR("unsupported connector_type[%d]\n", s->output_type);
29253 + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
29273 + if (VOP_MAJOR(vop->version) == 3 &&
29274 + (VOP_MINOR(vop->version) == 2 || VOP_MINOR(vop->version) == 8))
29278 + act_end - us_to_vertical_line(adjusted_mode, for_ddr_freq));
29283 + !!(adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) ||
29284 + s->output_if & VOP_OUTPUT_IF_BT656);
29288 + clk_set_rate(vop->dclk, adjusted_mode->crtc_clock * 1000);
29302 + return pa->zpos - pb->zpos;
29310 + struct drm_atomic_state *state = crtc_state->state;
29319 + s->afbdc_en = 0;
29328 + pstate = plane->state;
29330 + fb = pstate->fb;
29332 + if (pstate->crtc != crtc || !fb)
29334 + if (fb->modifier !=
29340 + return -EINVAL;
29345 + switch (plane_state->format) {
29356 + return -EINVAL;
29359 + if (s->afbdc_en) {
29361 + return -EINVAL;
29365 + src = &plane_state->src;
29366 + if (!(win->feature & WIN_FEATURE_AFBDC)) {
29368 + win->win_id, win->feature);
29369 + return -EINVAL;
29371 + if (!IS_ALIGNED(fb->width, 16)) {
29373 + win->win_id, fb->width);
29374 + return -EINVAL;
29383 + obj = fb->obj[0];
29385 + fb_addr = rk_obj->dma_addr + fb->offsets[0];
29387 + s->afbdc_win_format = afbdc_format;
29388 + s->afbdc_win_id = win->win_id;
29389 + s->afbdc_win_ptr = fb_addr;
29390 + s->afbdc_win_vir_width = fb->width;
29391 + s->afbdc_win_xoffset = (src->x1 >> 16);
29392 + s->afbdc_win_yoffset = (src->y1 >> 16);
29394 + align_x1 = (src->x1 >> 16) - ((src->x1 >> 16) % 16);
29395 + align_y1 = (src->y1 >> 16) - ((src->y1 >> 16) % 16);
29397 + align_val = (src->x2 >> 16) % 16;
29399 + align_x2 = (src->x2 >> 16) + (16 - align_val);
29401 + align_x2 = src->x2 >> 16;
29403 + align_val = (src->y2 >> 16) % 16;
29405 + align_y2 = (src->y2 >> 16) + (16 - align_val);
29407 + align_y2 = src->y2 >> 16;
29409 + s->afbdc_win_width = align_x2 - align_x1 - 1;
29410 + s->afbdc_win_height = align_y2 - align_y1 - 1;
29412 + s->afbdc_en = 1;
29416 + if (src->x1 || src->y1 || fb->offsets[0]) {
29418 + win->win_id);
29420 + src->x1, src->y1, fb->offsets[0]);
29421 + return -EINVAL;
29423 + s->afbdc_win_format = afbdc_format;
29424 + s->afbdc_win_width = fb->width - 1;
29425 + s->afbdc_win_height = (drm_rect_height(src) >> 16) - 1;
29426 + s->afbdc_win_id = win->win_id;
29427 + s->afbdc_win_ptr = plane_state->yrgb_mst;
29428 + s->afbdc_en = 1;
29437 + struct rockchip_drm_private *private = crtc->dev->dev_private;
29439 + struct rockchip_crtc_state *old_s = to_rockchip_crtc_state(crtc->state);
29441 + struct rockchip_dclk_pll *old_pll = vop->pll;
29443 + if (!vop->dclk_source)
29446 + if (crtc_state->active) {
29447 + WARN_ON(vop->pll && !vop->pll->use_count);
29448 + if (!vop->pll || vop->pll->use_count > 1 ||
29449 + s->output_type != old_s->output_type) {
29450 + if (vop->pll)
29451 + vop->pll->use_count--;
29453 + if (s->output_type != DRM_MODE_CONNECTOR_HDMIA &&
29454 + !private->default_pll.use_count)
29455 + vop->pll = &private->default_pll;
29457 + vop->pll = &private->hdmi_pll;
29459 + vop->pll->use_count++;
29461 + } else if (vop->pll) {
29462 + vop->pll->use_count--;
29463 + vop->pll = NULL;
29465 + if (vop->pll != old_pll)
29466 + crtc_state->mode_changed = true;
29472 + struct drm_atomic_state *state = crtc_state->state;
29475 + const struct vop_data *vop_data = vop->data;
29487 + s->yuv_overlay = 0;
29489 + s->yuv_overlay = is_yuv_output(s->bus_format);
29498 + pzpos = kmalloc_array(vop_data->win_size, sizeof(*pzpos), GFP_KERNEL);
29500 + return -ENOMEM;
29502 + for (i = 0; i < vop_data->win_size; i++) {
29503 + const struct vop_win_data *win_data = &vop_data->win[i];
29506 + if (!win_data->phy)
29509 + for (j = 0; j < vop->num_wins; j++) {
29510 + win = &vop->win[j];
29512 + if (win->win_id == i && !win->area_id)
29515 + if (WARN_ON(j >= vop->num_wins)) {
29516 + ret = -EINVAL;
29520 + plane = &win->base;
29521 + pstate = state->planes[drm_plane_index(plane)].state;
29527 + pstate = plane->state;
29530 + if (!pstate->visible)
29533 + pzpos[cnt].zpos = plane_state->zpos;
29534 + pzpos[cnt++].win_id = win->win_id;
29539 + for (i = 0, cnt = 0; i < vop_data->win_size; i++) {
29540 + const struct vop_win_data *win_data = &vop_data->win[i];
29543 + if (win_data->phy) {
29546 + dsp_layer_sel |= zpos->win_id << shift;
29552 + s->dsp_layer_sel = dsp_layer_sel;
29564 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
29565 + struct drm_display_mode *mode = &crtc->state->adjusted_mode;
29566 + u16 vtotal = mode->crtc_vtotal;
29567 + u16 hdisplay = mode->crtc_hdisplay;
29568 + u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
29569 + u16 vdisplay = mode->crtc_vdisplay;
29570 + u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
29571 + u16 hsize = hdisplay * (s->left_margin + s->right_margin) / 200;
29572 + u16 vsize = vdisplay * (s->top_margin + s->bottom_margin) / 200;
29576 + if (mode->flags & DRM_MODE_FLAG_INTERLACE)
29579 + hact_st += hdisplay * (100 - s->left_margin) / 200;
29584 + vact_st += vdisplay * (100 - s->top_margin) / 200;
29598 + if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
29611 + to_rockchip_crtc_state(crtc->state);
29613 + struct rockchip_sdr2hdr_state *sdr2hdr_state = &s->hdr.sdr2hdr_state;
29615 + if (!vop->data->hdr_table)
29618 + if (s->hdr.hdr2sdr_en) {
29626 + VOP_CTRL_SET(vop, hdr2sdr_en, s->hdr.hdr2sdr_en);
29629 + sdr2hdr_state->bt1886eotf_pre_conv_en);
29631 + sdr2hdr_state->bt1886eotf_post_conv_en);
29634 + sdr2hdr_state->rgb2rgb_pre_conv_en);
29636 + sdr2hdr_state->rgb2rgb_pre_conv_mode);
29638 + sdr2hdr_state->st2084oetf_pre_conv_en);
29641 + sdr2hdr_state->rgb2rgb_post_conv_en);
29643 + sdr2hdr_state->rgb2rgb_post_conv_mode);
29645 + sdr2hdr_state->st2084oetf_post_conv_en);
29647 + if (sdr2hdr_state->bt1886eotf_pre_conv_en ||
29648 + sdr2hdr_state->bt1886eotf_post_conv_en)
29649 + vop_load_sdr2hdr_table(vop, sdr2hdr_state->sdr2hdr_func);
29657 + to_rockchip_crtc_state(crtc->state);
29662 + const struct vop_data *vop_data = vop->data;
29664 + if (!s->tv_state)
29668 - * if vop is not support RGB10 output, need force RGB10 to RGB888.
29677 - if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
29678 - !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
29679 - s->output_mode = ROCKCHIP_OUT_MODE_P888;
29680 + if (!memcmp(s->tv_state,
29681 + &vop->active_tv_state, sizeof(*s->tv_state)) &&
29682 + s->yuv_overlay == old_s->yuv_overlay && s->mode_update &&
29683 + s->bcsh_en == old_s->bcsh_en && s->bus_format == old_s->bus_format)
29686 + memcpy(&vop->active_tv_state, s->tv_state, sizeof(*s->tv_state));
29688 + s->post_r2y_en = 0;
29689 + s->post_y2r_en = 0;
29690 + s->bcsh_en = 0;
29691 + if (s->tv_state) {
29692 + if (s->tv_state->brightness != 50 ||
29693 + s->tv_state->contrast != 50 ||
29694 + s->tv_state->saturation != 50 || s->tv_state->hue != 50)
29695 + s->bcsh_en = 1;
29698 + if (s->bcsh_en) {
29699 + if (!s->yuv_overlay)
29700 + s->post_r2y_en = 1;
29701 + if (!is_yuv_output(s->bus_format))
29702 + s->post_y2r_en = 1;
29704 + if (!s->yuv_overlay && is_yuv_output(s->bus_format))
29705 + s->post_r2y_en = 1;
29706 + if (s->yuv_overlay && !is_yuv_output(s->bus_format))
29707 + s->post_y2r_en = 1;
29710 - if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8)
29711 - VOP_REG_SET(vop, common, pre_dither_down, 1);
29712 + s->post_csc_mode = to_vop_csc_mode(s->color_space);
29713 + VOP_CTRL_SET(vop, bcsh_r2y_en, s->post_r2y_en);
29714 + VOP_CTRL_SET(vop, bcsh_y2r_en, s->post_y2r_en);
29715 + VOP_CTRL_SET(vop, bcsh_r2y_csc_mode, s->post_csc_mode);
29716 + VOP_CTRL_SET(vop, bcsh_y2r_csc_mode, s->post_csc_mode);
29717 + if (!s->bcsh_en) {
29718 + VOP_CTRL_SET(vop, bcsh_en, s->bcsh_en);
29722 + if (vop_data->feature & VOP_FEATURE_OUTPUT_10BIT)
29723 + brightness = interpolate(0, -128, 100, 127, s->tv_state->brightness);
29724 + else if (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 6) /* px30 vopb */
29725 + brightness = interpolate(0, -64, 100, 63, s->tv_state->brightness);
29727 - VOP_REG_SET(vop, common, pre_dither_down, 0);
29728 + brightness = interpolate(0, -32, 100, 31, s->tv_state->brightness);
29730 + if ((VOP_MAJOR(vop->version) == 3) ||
29731 + (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 6)) { /* px30 vopb */
29732 + contrast = interpolate(0, 0, 100, 511, s->tv_state->contrast);
29733 + saturation = interpolate(0, 0, 100, 511, s->tv_state->saturation);
29735 + * a:[-30~0]:
29736 + * sin_hue = 0x100 - sin(a)*256;
29742 + hue = interpolate(0, -30, 100, 30, s->tv_state->hue);
29747 - if (dither_bpc == 6) {
29748 - VOP_REG_SET(vop, common, dither_down_sel, DITHER_DOWN_ALLEGRO);
29749 - VOP_REG_SET(vop, common, dither_down_mode, RGB888_TO_RGB666);
29750 - VOP_REG_SET(vop, common, dither_down_en, 1);
29752 - VOP_REG_SET(vop, common, dither_down_en, 0);
29753 + contrast = interpolate(0, 0, 100, 255, s->tv_state->contrast);
29754 + saturation = interpolate(0, 0, 100, 255, s->tv_state->saturation);
29756 + * a:[-30~0]:
29757 + * sin_hue = 0x100 - sin(a)*128;
29763 + hue = interpolate(0, -30, 100, 30, s->tv_state->hue);
29769 - VOP_REG_SET(vop, common, out_mode, s->output_mode);
29775 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) == 0)
29777 + VOP_CTRL_SET(vop, bcsh_en, s->bcsh_en);
29780 - VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
29781 - val = hact_st << 16;
29782 - val |= hact_end;
29783 - VOP_REG_SET(vop, modeset, hact_st_end, val);
29784 - VOP_REG_SET(vop, modeset, hpost_st_end, val);
29789 + to_rockchip_crtc_state(crtc->state);
29791 + const struct vop_data *vop_data = vop->data;
29793 - VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
29794 - val = vact_st << 16;
29795 - val |= vact_end;
29796 - VOP_REG_SET(vop, modeset, vact_st_end, val);
29797 - VOP_REG_SET(vop, modeset, vpost_st_end, val);
29798 + spin_lock(&vop->reg_lock);
29800 - VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
29803 - clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
29806 - VOP_REG_SET(vop, common, standby, 0);
29807 - mutex_unlock(&vop->vop_lock);
29808 + if (s->afbdc_en) {
29811 + VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4);
29813 + VOP_CTRL_SET(vop, afbdc_sel, s->afbdc_win_id);
29814 + VOP_CTRL_SET(vop, afbdc_hdr_ptr, s->afbdc_win_ptr);
29815 + pic_size = (s->afbdc_win_width & 0xffff);
29816 + pic_size |= s->afbdc_win_height << 16;
29819 + VOP_CTRL_SET(vop, afbdc_pic_vir_width, s->afbdc_win_vir_width);
29820 + pic_offset = (s->afbdc_win_xoffset & 0xffff);
29821 + pic_offset |= s->afbdc_win_yoffset << 16;
29825 + VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
29827 + VOP_CTRL_SET(vop, dsp_layer_sel, s->dsp_layer_sel);
29828 + if (vop_data->feature & VOP_FEATURE_OVERSCAN)
29831 + spin_unlock(&vop->reg_lock);
29836 - return VOP_INTR_GET_TYPE(vop, status, FS_INTR);
29837 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7)
29844 @@ -1413,72 +3857,66 @@ static void vop_wait_for_irq_handler(struct vop *vop)
29845 synchronize_irq(vop->irq);
29848 -static int vop_crtc_atomic_check(struct drm_crtc *crtc,
29849 - struct drm_crtc_state *crtc_state)
29853 + struct drm_atomic_state *old_state = old_crtc_state->state;
29857 - struct drm_plane_state *plane_state;
29858 - struct rockchip_crtc_state *s;
29859 - int afbc_planes = 0;
29863 + to_rockchip_crtc_state(crtc->state);
29865 - if (vop->lut_regs && crtc_state->color_mgmt_changed &&
29866 - crtc_state->gamma_lut) {
29867 - unsigned int len;
29870 - len = drm_color_lut_size(crtc_state->gamma_lut);
29871 - if (len != crtc->gamma_size) {
29872 - DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
29873 - len, crtc->gamma_size);
29874 - return -EINVAL;
29875 - }
29876 - }
29877 + if (!vop->is_iommu_enabled && vop->is_iommu_needed) {
29880 - drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
29881 - plane_state =
29882 - drm_atomic_get_plane_state(crtc_state->state, plane);
29883 - if (IS_ERR(plane_state)) {
29884 - DRM_DEBUG_KMS("Cannot get plane state for plane %s\n",
29885 - plane->name);
29886 - return PTR_ERR(plane_state);
29887 - }
29888 + if (s->mode_update)
29891 - if (drm_is_afbc(plane_state->fb->modifier))
29892 - ++afbc_planes;
29893 + ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
29895 + vop->is_iommu_enabled = false;
29897 + dev_err(vop->dev, "failed to attach dma mapping, %d\n",
29900 + vop->is_iommu_enabled = true;
29905 - if (afbc_planes > 1) {
29906 - DRM_DEBUG_KMS("Invalid number of AFBC planes; got %d, expected at most 1\n", afbc_planes);
29907 - return -EINVAL;
29909 + if (old_crtc_state->color_mgmt_changed || old_crtc_state->active_changed) {
29910 + if (crtc->state->gamma_lut || vop->gamma_lut) {
29911 + if (old_crtc_state->gamma_lut)
29912 + vop->gamma_lut = old_crtc_state->gamma_lut->data;
29917 - s = to_rockchip_crtc_state(crtc_state);
29918 - s->enable_afbc = afbc_planes > 0;
29919 -
29920 - return 0;
29921 -}
29922 -
29923 -static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
29924 - struct drm_crtc_state *old_crtc_state)
29925 -{
29926 - struct drm_atomic_state *old_state = old_crtc_state->state;
29927 - struct drm_plane_state *old_plane_state, *new_plane_state;
29928 - struct vop *vop = to_vop(crtc);
29929 - struct drm_plane *plane;
29930 - struct rockchip_crtc_state *s;
29931 - int i;
29932 -
29933 - if (WARN_ON(!vop->is_enabled))
29934 - return;
29935 -
29936 - spin_lock(&vop->reg_lock);
29937 -
29938 - /* Enable AFBC if there is some AFBC window, disable otherwise. */
29939 - s = to_rockchip_crtc_state(crtc->state);
29940 - VOP_AFBC_SET(vop, enable, s->enable_afbc);
29941 + spin_lock_irqsave(&vop->irq_lock, flags);
29942 + vop->pre_overlay = s->hdr.pre_overlay;
29945 + * rk322x and rk332x odd-even field will mistake when in interlace mode.
29949 + if (VOP_MAJOR(vop->version) == 3 &&
29950 + (VOP_MINOR(vop->version) == 7 || VOP_MINOR(vop->version) == 8)) {
29951 + if (!s->mode_update && VOP_CTRL_GET(vop, reg_done_frm))
29956 + if (vop->mcu_timing.mcu_pix_total)
29959 - spin_unlock(&vop->reg_lock);
29960 + spin_unlock_irqrestore(&vop->irq_lock, flags);
29964 @@ -1496,13 +3934,11 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
29965 crtc->state->event = NULL;
29967 spin_unlock_irq(&crtc->dev->event_lock);
29968 -
29969 - for_each_oldnew_plane_in_state(old_state, plane, old_plane_state,
29970 - new_plane_state, i) {
29972 if (!old_plane_state->fb)
29975 - if (old_plane_state->fb == new_plane_state->fb)
29976 + if (old_plane_state->fb == plane->state->fb)
29979 drm_framebuffer_get(old_plane_state->fb);
29980 @@ -1514,8 +3950,8 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
29986 - .atomic_begin = vop_crtc_atomic_begin,
29990 @@ -1526,11 +3962,33 @@ static void vop_crtc_destroy(struct drm_crtc *crtc)
29996 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
29998 + if (crtc->state) {
29999 + __drm_atomic_helper_crtc_destroy_state(crtc->state);
30006 + crtc->state = &s->base;
30007 + crtc->state->crtc = crtc;
30009 + s->left_margin = 100;
30010 + s->right_margin = 100;
30011 + s->top_margin = 100;
30012 + s->bottom_margin = 100;
30017 - struct rockchip_crtc_state *rockchip_state;
30020 - rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
30021 + old_state = to_rockchip_crtc_state(crtc->state);
30026 @@ -1547,17 +4005,6 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc,
30030 -static void vop_crtc_reset(struct drm_crtc *crtc)
30031 -{
30032 - struct rockchip_crtc_state *crtc_state =
30033 - kzalloc(sizeof(*crtc_state), GFP_KERNEL);
30034 -
30035 - if (crtc->state)
30036 - vop_crtc_destroy_state(crtc, crtc->state);
30037 -
30038 - __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
30039 -}
30040 -
30044 @@ -1623,18 +4070,116 @@ vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
30053 + struct drm_device *drm_dev = crtc->dev;
30054 + struct rockchip_drm_private *private = drm_dev->dev_private;
30055 + struct drm_mode_config *mode_config = &drm_dev->mode_config;
30059 + if (property == mode_config->tv_left_margin_property) {
30060 + *val = s->left_margin;
30064 + if (property == mode_config->tv_right_margin_property) {
30065 + *val = s->right_margin;
30069 + if (property == mode_config->tv_top_margin_property) {
30070 + *val = s->top_margin;
30074 + if (property == mode_config->tv_bottom_margin_property) {
30075 + *val = s->bottom_margin;
30079 + if (property == private->aclk_prop) {
30080 + /* KHZ, keep align with mode->clock */
30081 + *val = clk_get_rate(vop->aclk) / 1000;
30085 + if (property == private->bg_prop) {
30086 + *val = vop->background;
30090 + if (property == private->line_flag_prop) {
30091 + *val = vop->line_flag;
30096 + return -EINVAL;
30104 + struct drm_device *drm_dev = crtc->dev;
30105 + struct rockchip_drm_private *private = drm_dev->dev_private;
30106 + struct drm_mode_config *mode_config = &drm_dev->mode_config;
30110 + if (property == mode_config->tv_left_margin_property) {
30111 + s->left_margin = val;
30115 + if (property == mode_config->tv_right_margin_property) {
30116 + s->right_margin = val;
30120 + if (property == mode_config->tv_top_margin_property) {
30121 + s->top_margin = val;
30125 + if (property == mode_config->tv_bottom_margin_property) {
30126 + s->bottom_margin = val;
30130 + if (property == private->bg_prop) {
30131 + vop->background = val;
30135 + if (property == private->line_flag_prop) {
30136 + vop->line_flag = val;
30141 + return -EINVAL;
30158 - .gamma_set = drm_atomic_helper_legacy_gamma_set,
30162 @@ -1642,115 +4187,368 @@ static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
30166 - drm_crtc_vblank_put(&vop->crtc);
30167 + drm_crtc_vblank_put(&vop->rockchip_crtc.crtc);
30173 struct drm_device *drm = vop->drm_dev;
30174 - struct drm_crtc *crtc = &vop->crtc;
30175 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30178 - spin_lock(&drm->event_lock);
30179 + spin_lock_irqsave(&drm->event_lock, flags);
30180 if (vop->event) {
30181 drm_crtc_send_vblank_event(crtc, vop->event);
30183 vop->event = NULL;
30185 - spin_unlock(&drm->event_lock);
30186 + spin_unlock_irqrestore(&drm->event_lock, flags);
30188 + if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
30189 + drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
30195 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30201 + * The irq is shared with the iommu. If the runtime-pm state of the
30202 + * vop-device is disabled the irq has to be targeted at the iommu.
30204 + if (!pm_runtime_get_if_in_use(vop->dev))
30208 + DRM_DEV_ERROR_RATELIMITED(vop->dev, "couldn't enable clocks\n");
30216 + spin_lock_irqsave(&vop->irq_lock, flags);
30223 + spin_unlock_irqrestore(&vop->irq_lock, flags);
30230 + complete(&vop->dsp_hold_completion);
30236 + complete(&vop->line_flag_completion);
30246 + spin_lock_irqsave(&vop->irq_lock, flags);
30247 + VOP_CTRL_SET(vop, level2_overlay_en, vop->pre_overlay);
30248 + VOP_CTRL_SET(vop, alpha_hard_calc, vop->pre_overlay);
30249 + spin_unlock_irqrestore(&vop->irq_lock, flags);
30259 + DRM_DEV_ERROR_RATELIMITED(vop->dev, #x " irq err\n"); \
30280 + pm_runtime_put(vop->dev);
30300 + struct drm_prop_enum_list *props = vop->plane_name_list;
30302 + uint64_t bits = BIT_ULL(win->plane_id);
30304 + prop = drm_property_create_bitmask(vop->drm_dev,
30306 + props, vop->num_wins, bits);
30308 + DRM_DEV_ERROR(vop->dev, "create Name prop for %s failed\n", win->name);
30309 + return -ENOMEM;
30311 + win->name_prop = prop;
30312 + drm_object_attach_property(&win->base.base, win->name_prop, bits);
30320 + struct rockchip_drm_private *private = vop->drm_dev->dev_private;
30323 + const struct vop_data *vop_data = vop->data;
30327 + ret = drm_universal_plane_init(vop->drm_dev, &win->base, possible_crtcs, &vop_plane_funcs,
30328 + win->data_formats, win->nformats, win->format_modifiers,
30329 + win->type, win->name);
30334 + drm_plane_helper_add(&win->base, &plane_helper_funcs);
30336 + if (win->phy->scl)
30341 + if (win->feature & WIN_FEATURE_HDR2SDR)
30343 + if (win->feature & WIN_FEATURE_SDR2HDR)
30345 + if (win->feature & WIN_FEATURE_AFBDC)
30348 + drm_object_attach_property(&win->base.base, vop->plane_feature_prop,
30350 + drm_object_attach_property(&win->base.base, private->eotf_prop, 0);
30351 + drm_object_attach_property(&win->base.base,
30352 + private->color_space_prop, 0);
30354 + drm_plane_create_alpha_property(&win->base);
30355 + drm_object_attach_property(&win->base.base,
30356 + private->async_commit_prop, 0);
30358 + if (win->parent)
30359 + drm_object_attach_property(&win->base.base, private->share_id_prop,
30360 + win->parent->base.base.id);
30362 + drm_object_attach_property(&win->base.base, private->share_id_prop,
30363 + win->base.base.id);
30365 + drm_plane_create_blend_mode_property(&win->base, blend_caps);
30366 + drm_plane_create_zpos_property(&win->base, win->win_id, 0, vop->num_wins - 1);
30370 + win->input_width_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30371 + "INPUT_WIDTH", 0, vop_data->max_input.width);
30372 + win->input_height_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30373 + "INPUT_HEIGHT", 0, vop_data->max_input.height);
30375 + win->output_width_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30376 + "OUTPUT_WIDTH", 0, vop_data->max_input.width);
30377 + win->output_height_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30378 + "OUTPUT_HEIGHT", 0, vop_data->max_input.height);
30380 + win->scale_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30387 + win->color_key_prop = drm_property_create_range(vop->drm_dev, 0,
30389 + if (!win->input_width_prop || !win->input_height_prop ||
30390 + !win->scale_prop || !win->color_key_prop) {
30392 + return -ENOMEM;
30395 - if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
30396 - drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
30397 + drm_object_attach_property(&win->base.base, win->input_width_prop, 0);
30398 + drm_object_attach_property(&win->base.base, win->input_height_prop, 0);
30399 + drm_object_attach_property(&win->base.base, win->output_width_prop, 0);
30400 + drm_object_attach_property(&win->base.base, win->output_height_prop, 0);
30401 + drm_object_attach_property(&win->base.base, win->scale_prop, 0);
30402 + drm_object_attach_property(&win->base.base, win->color_key_prop, 0);
30407 -static irqreturn_t vop_isr(int irq, void *data)
30410 - struct vop *vop = data;
30411 - struct drm_crtc *crtc = &vop->crtc;
30412 - uint32_t active_irqs;
30413 - int ret = IRQ_NONE;
30414 + struct device_node *node = vop->dev->of_node;
30416 + u32 lut_len = vop->lut_len;
30421 - /*
30422 - * The irq is shared with the iommu. If the runtime-pm state of the
30423 - * vop-device is disabled the irq has to be targeted at the iommu.
30424 - */
30425 - if (!pm_runtime_get_if_in_use(vop->dev))
30426 - return IRQ_NONE;
30427 + if (!vop->lut)
30428 + return -ENOMEM;
30430 - if (vop_core_clks_enable(vop)) {
30431 - DRM_DEV_ERROR_RATELIMITED(vop->dev, "couldn't enable clocks\n");
30432 - goto out;
30433 + dsp_lut = of_parse_phandle(node, "dsp-lut", 0);
30435 + return -ENXIO;
30437 + prop = of_find_property(dsp_lut, "gamma-lut", &length);
30439 + dev_err(vop->dev, "failed to find gamma_lut\n");
30440 + return -ENXIO;
30443 - /*
30444 - * interrupt register has interrupt status, enable and clear bits, we
30445 - * must hold irq_lock to avoid a race with enable/disable_vblank().
30446 - */
30447 - spin_lock(&vop->irq_lock);
30450 - active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK);
30451 - /* Clear all active interrupt sources */
30452 - if (active_irqs)
30453 - VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1);
30458 - spin_unlock(&vop->irq_lock);
30460 + return -ENOMEM;
30461 + ret = of_property_read_u32_array(dsp_lut, "gamma-lut", lut,
30464 + dev_err(vop->dev, "load gamma-lut failed\n");
30466 + return -EINVAL;
30469 - /* This is expected for vop iommu irqs, since the irq is shared */
30470 - if (!active_irqs)
30471 - goto out_disable;
30478 - if (active_irqs & DSP_HOLD_VALID_INTR) {
30479 - complete(&vop->dsp_hold_completion);
30480 - active_irqs &= ~DSP_HOLD_VALID_INTR;
30481 - ret = IRQ_HANDLED;
30482 - }
30483 + vop->lut[i] = r * lut_len * lut_len + g * lut_len + b;
30486 - if (active_irqs & LINE_FLAG_INTR) {
30487 - complete(&vop->line_flag_completion);
30488 - active_irqs &= ~LINE_FLAG_INTR;
30489 - ret = IRQ_HANDLED;
30492 + of_property_read_u32_array(dsp_lut, "gamma-lut",
30493 + vop->lut, vop->lut_len);
30495 + vop->lut_active = true;
30497 - if (active_irqs & FS_INTR) {
30498 - drm_crtc_handle_vblank(crtc);
30499 - vop_handle_vblank(vop);
30500 - active_irqs &= ~FS_INTR;
30501 - ret = IRQ_HANDLED;
30516 + prop = drm_property_create_bitmask(vop->drm_dev,
30521 + DRM_DEV_ERROR(vop->dev, "create plane_mask prop for vp%d failed\n", vop->id);
30522 + return -ENOMEM;
30525 - /* Unhandled irqs are spurious. */
30526 - if (active_irqs)
30527 - DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n",
30528 - active_irqs);
30529 + vop->plane_mask_prop = prop;
30530 + drm_object_attach_property(&crtc->base, vop->plane_mask_prop, vop->plane_mask);
30532 -out_disable:
30533 - vop_core_clks_disable(vop);
30534 -out:
30535 - pm_runtime_put(vop->dev);
30536 - return ret;
30540 -static void vop_plane_add_properties(struct drm_plane *plane,
30541 - const struct vop_win_data *win_data)
30544 - unsigned int flags = 0;
30545 + const struct vop_data *vop_data = vop->data;
30547 - flags |= VOP_WIN_HAS_REG(win_data, x_mir_en) ? DRM_MODE_REFLECT_X : 0;
30548 - flags |= VOP_WIN_HAS_REG(win_data, y_mir_en) ? DRM_MODE_REFLECT_Y : 0;
30549 - if (flags)
30550 - drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
30551 - DRM_MODE_ROTATE_0 | flags);
30561 + if (vop_data->feature & VOP_FEATURE_ALPHA_SCALE)
30563 + if (vop_data->feature & VOP_FEATURE_HDR10)
30565 + if (vop_data->feature & VOP_FEATURE_NEXT_HDR)
30568 + prop = drm_property_create_bitmask(vop->drm_dev,
30573 + DRM_DEV_ERROR(vop->dev, "create FEATURE prop for vop%d failed\n", vop->id);
30574 + return -ENOMEM;
30577 + vop->feature_prop = prop;
30578 + drm_object_attach_property(&crtc->base, vop->feature_prop, feature);
30585 - const struct vop_data *vop_data = vop->data;
30586 struct device *dev = vop->dev;
30587 struct drm_device *drm_dev = vop->drm_dev;
30588 + struct rockchip_drm_private *private = drm_dev->dev_private;
30590 - struct drm_crtc *crtc = &vop->crtc;
30591 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30593 - int ret;
30598 @@ -1758,29 +4556,19 @@ static int vop_create_crtc(struct vop *vop)
30602 - for (i = 0; i < vop_data->win_size; i++) {
30603 - struct vop_win *vop_win = &vop->win[i];
30604 - const struct vop_win_data *win_data = vop_win->data;
30605 + for (i = 0; i < vop->num_wins; i++) {
30606 + struct vop_win *win = &vop->win[i];
30608 - if (win_data->type != DRM_PLANE_TYPE_PRIMARY &&
30609 - win_data->type != DRM_PLANE_TYPE_CURSOR)
30610 + if (win->type != DRM_PLANE_TYPE_PRIMARY &&
30611 + win->type != DRM_PLANE_TYPE_CURSOR)
30614 - ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
30615 - 0, &vop_plane_funcs,
30616 - win_data->phy->data_formats,
30617 - win_data->phy->nformats,
30618 - win_data->phy->format_modifiers,
30619 - win_data->type, NULL);
30620 - if (ret) {
30621 - DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
30622 - ret);
30624 + DRM_DEV_ERROR(vop->dev, "failed to init plane\n");
30628 - plane = &vop_win->base;
30629 - drm_plane_helper_add(plane, &plane_helper_funcs);
30630 - vop_plane_add_properties(plane, win_data);
30631 + plane = &win->base;
30632 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
30634 else if (plane->type == DRM_PLANE_TYPE_CURSOR)
30635 @@ -1793,37 +4581,23 @@ static int vop_create_crtc(struct vop *vop)
30639 - if (vop->lut_regs) {
30640 - drm_mode_crtc_set_gamma_size(crtc, vop_data->lut_size);
30641 - drm_crtc_enable_color_mgmt(crtc, 0, false, vop_data->lut_size);
30642 - }
30648 - for (i = 0; i < vop_data->win_size; i++) {
30649 - struct vop_win *vop_win = &vop->win[i];
30650 - const struct vop_win_data *win_data = vop_win->data;
30651 + for (i = 0; i < vop->num_wins; i++) {
30652 + struct vop_win *win = &vop->win[i];
30655 - if (win_data->type != DRM_PLANE_TYPE_OVERLAY)
30656 + if (win->type != DRM_PLANE_TYPE_OVERLAY)
30659 - ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
30660 - possible_crtcs,
30661 - &vop_plane_funcs,
30662 - win_data->phy->data_formats,
30663 - win_data->phy->nformats,
30664 - win_data->phy->format_modifiers,
30665 - win_data->type, NULL);
30666 - if (ret) {
30667 - DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
30668 - ret);
30670 + DRM_DEV_ERROR(vop->dev, "failed to init overlay\n");
30673 - drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
30674 - vop_plane_add_properties(&vop_win->base, win_data);
30675 + vop_plane_add_properties(vop, &win->base, win);
30678 port = of_get_child_by_name(dev->of_node, "port");
30679 @@ -1840,15 +4614,65 @@ static int vop_create_crtc(struct vop *vop)
30680 init_completion(&vop->dsp_hold_completion);
30681 init_completion(&vop->line_flag_completion);
30682 crtc->port = port;
30683 -
30686 + drm_object_attach_property(&crtc->base, private->soc_id_prop, vop->soc_id);
30687 + drm_object_attach_property(&crtc->base, private->port_id_prop, vop->id);
30688 + drm_object_attach_property(&crtc->base, private->aclk_prop, 0);
30689 + drm_object_attach_property(&crtc->base, private->bg_prop, 0);
30690 + drm_object_attach_property(&crtc->base, private->line_flag_prop, 0);
30693 + drm_object_attach_property(&crtc->base, drm_dev->mode_config.prop, v)
30704 DRM_DEV_DEBUG_KMS(vop->dev,
30705 - "Failed to init %s with SR helpers %d, ignoring\n",
30706 - crtc->name, ret);
30708 + crtc->name, ret);
30710 + if (vop->lut_regs) {
30712 + u32 lut_len = vop->lut_len;
30714 + vop->lut = devm_kmalloc_array(dev, lut_len, sizeof(*vop->lut),
30716 + if (!vop->lut)
30725 + vop->lut[i] = r | g | b;
30731 + r_base = crtc->gamma_store;
30732 + g_base = r_base + crtc->gamma_size;
30733 + b_base = g_base + crtc->gamma_size;
30748 @@ -1860,7 +4684,7 @@ static int vop_create_crtc(struct vop *vop)
30752 - struct drm_crtc *crtc = &vop->crtc;
30753 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30754 struct drm_device *drm_dev = vop->drm_dev;
30757 @@ -1888,187 +4712,130 @@ static void vop_destroy_crtc(struct vop *vop)
30758 drm_flip_work_cleanup(&vop->fb_unref_work);
30761 -static int vop_initial(struct vop *vop)
30771 - struct reset_control *ahb_rst;
30772 - int i, ret;
30773 -
30774 - vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
30775 - if (IS_ERR(vop->hclk)) {
30776 - DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n");
30777 - return PTR_ERR(vop->hclk);
30778 - }
30779 - vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
30780 - if (IS_ERR(vop->aclk)) {
30781 - DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n");
30782 - return PTR_ERR(vop->aclk);
30783 - }
30784 - vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
30785 - if (IS_ERR(vop->dclk)) {
30786 - DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n");
30787 - return PTR_ERR(vop->dclk);
30788 - }
30789 -
30790 - ret = pm_runtime_get_sync(vop->dev);
30791 - if (ret < 0) {
30792 - DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
30793 - return ret;
30794 - }
30795 -
30796 - ret = clk_prepare(vop->dclk);
30797 - if (ret < 0) {
30798 - DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n");
30799 - goto err_put_pm_runtime;
30800 - }
30801 -
30802 - /* Enable both the hclk and aclk to setup the vop */
30803 - ret = clk_prepare_enable(vop->hclk);
30804 - if (ret < 0) {
30805 - DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n");
30806 - goto err_unprepare_dclk;
30807 - }
30808 -
30809 - ret = clk_prepare_enable(vop->aclk);
30810 - if (ret < 0) {
30811 - DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n");
30812 - goto err_disable_hclk;
30813 - }
30814 -
30815 - /*
30816 - * do hclk_reset, reset all vop registers.
30817 - */
30818 - ahb_rst = devm_reset_control_get(vop->dev, "ahb");
30819 - if (IS_ERR(ahb_rst)) {
30820 - DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n");
30821 - ret = PTR_ERR(ahb_rst);
30822 - goto err_disable_aclk;
30823 - }
30824 - reset_control_assert(ahb_rst);
30825 - usleep_range(10, 20);
30826 - reset_control_deassert(ahb_rst);
30827 -
30828 - VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
30829 - VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);
30830 -
30831 - for (i = 0; i < vop->len; i += sizeof(u32))
30832 - vop->regsbak[i / 4] = readl_relaxed(vop->regs + i);
30833 -
30834 - VOP_REG_SET(vop, misc, global_regdone_en, 1);
30835 - VOP_REG_SET(vop, common, dsp_blank, 0);
30836 -
30837 - for (i = 0; i < vop->data->win_size; i++) {
30838 - struct vop_win *vop_win = &vop->win[i];
30839 - const struct vop_win_data *win = vop_win->data;
30840 - int channel = i * 2 + 1;
30841 -
30842 - VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
30843 - vop_win_disable(vop, vop_win);
30844 - VOP_WIN_SET(vop, win, gate, 1);
30845 - }
30846 -
30847 - vop_cfg_done(vop);
30848 -
30849 - /*
30850 - * do dclk_reset, let all config take affect.
30851 - */
30852 - vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk");
30853 - if (IS_ERR(vop->dclk_rst)) {
30854 - DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n");
30855 - ret = PTR_ERR(vop->dclk_rst);
30856 - goto err_disable_aclk;
30863 + return size - 1;
30865 - reset_control_assert(vop->dclk_rst);
30866 - usleep_range(10, 20);
30867 - reset_control_deassert(vop->dclk_rst);
30868 -
30869 - clk_disable(vop->hclk);
30870 - clk_disable(vop->aclk);
30871 -
30872 - vop->is_enabled = false;
30873 -
30874 - pm_runtime_put_sync(vop->dev);
30875 -
30877 -
30878 -err_disable_aclk:
30879 - clk_disable_unprepare(vop->aclk);
30880 -err_disable_hclk:
30881 - clk_disable_unprepare(vop->hclk);
30882 -err_unprepare_dclk:
30883 - clk_unprepare(vop->dclk);
30884 -err_put_pm_runtime:
30885 - pm_runtime_put_sync(vop->dev);
30886 - return ret;
30890 * Initialize the vop->win array elements.
30892 -static void vop_win_init(struct vop *vop)
30895 const struct vop_data *vop_data = vop->data;
30896 - unsigned int i;
30910 for (i = 0; i < vop_data->win_size; i++) {
30911 - struct vop_win *vop_win = &vop->win[i];
30912 + struct vop_win *vop_win = &vop->win[num_wins];
30913 const struct vop_win_data *win_data = &vop_data->win[i];
30915 - vop_win->data = win_data;
30916 - vop_win->vop = vop;
30917 + if (!win_data->phy)
30920 - if (vop_data->win_yuv2yuv)
30921 - vop_win->yuv2yuv_data = &vop_data->win_yuv2yuv[i];
30922 - }
30923 -}
30924 + vop_win->phy = win_data->phy;
30925 + vop_win->csc = win_data->csc;
30926 + vop_win->offset = win_data->base;
30927 + vop_win->type = win_data->type;
30928 + vop_win->data_formats = win_data->phy->data_formats;
30929 + vop_win->nformats = win_data->phy->nformats;
30930 + vop_win->format_modifiers = win_data->format_modifiers;
30931 + vop_win->feature = win_data->feature;
30932 + vop_win->vop = vop;
30933 + vop_win->win_id = i;
30934 + vop_win->area_id = 0;
30935 + vop_win->plane_id = plane_id++;
30936 + snprintf(name, sizeof(name), "VOP%d-win%d-%d", vop->id, vop_win->win_id, vop_win->area_id);
30937 + vop_win->name = devm_kstrdup(vop->dev, name, GFP_KERNEL);
30938 + vop_win->zpos = vop_plane_get_zpos(win_data->type,
30939 + vop_data->win_size);
30941 -/**
30942 - * rockchip_drm_wait_vact_end
30943 - * @crtc: CRTC to enable line flag
30944 - * @mstimeout: millisecond for timeout
30945 - *
30946 - * Wait for vact_end line flag irq or timeout.
30947 - *
30948 - * Returns:
30949 - * Zero on success, negative errno on failure.
30950 - */
30951 -int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
30952 -{
30953 - struct vop *vop = to_vop(crtc);
30954 - unsigned long jiffies_left;
30955 - int ret = 0;
30958 - if (!crtc || !vop->is_enabled)
30959 - return -ENODEV;
30960 + if (!vop->support_multi_area)
30963 - mutex_lock(&vop->vop_lock);
30964 - if (mstimeout <= 0) {
30965 - ret = -EINVAL;
30966 - goto out;
30967 + for (j = 0; j < win_data->area_size; j++) {
30968 + struct vop_win *vop_area = &vop->win[num_wins];
30969 + const struct vop_win_phy *area = win_data->area[j];
30971 + vop_area->parent = vop_win;
30972 + vop_area->offset = vop_win->offset;
30973 + vop_area->phy = area;
30974 + vop_area->type = DRM_PLANE_TYPE_OVERLAY;
30975 + vop_area->data_formats = vop_win->data_formats;
30976 + vop_area->nformats = vop_win->nformats;
30977 + vop_area->format_modifiers = win_data->format_modifiers;
30978 + vop_area->vop = vop;
30979 + vop_area->win_id = i;
30980 + vop_area->area_id = j + 1;
30981 + vop_area->plane_id = plane_id++;
30982 + snprintf(name, sizeof(name), "VOP%d-win%d-%d", vop->id, vop_area->win_id, vop_area->area_id);
30983 + vop_area->name = devm_kstrdup(vop->dev, name, GFP_KERNEL);
30986 + vop->plane_mask |= BIT(vop_win->win_id);
30989 - if (vop_line_flag_irq_is_enabled(vop)) {
30990 - ret = -EBUSY;
30991 - goto out;
30992 + vop->num_wins = num_wins;
30994 + vop->plane_feature_prop = drm_property_create_bitmask(vop->drm_dev,
31002 + if (!vop->plane_feature_prop) {
31004 + return -EINVAL;
31007 - reinit_completion(&vop->line_flag_completion);
31008 - vop_line_flag_irq_enable(vop);
31009 + plane_name_list = devm_kzalloc(vop->dev,
31010 + vop->num_wins * sizeof(*plane_name_list),
31013 + DRM_DEV_ERROR(vop->dev, "failed to alloc memory for plane_name_list\n");
31014 + return -ENOMEM;
31017 - jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
31018 - msecs_to_jiffies(mstimeout));
31019 - vop_line_flag_irq_disable(vop);
31020 + for (i = 0; i < vop->num_wins; i++) {
31021 + struct vop_win *vop_win = &vop->win[i];
31023 - if (jiffies_left == 0) {
31024 - DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
31025 - ret = -ETIMEDOUT;
31026 - goto out;
31027 + plane_name_list[i].type = vop_win->plane_id;
31028 + plane_name_list[i].name = vop_win->name;
31031 -out:
31032 - mutex_unlock(&vop->vop_lock);
31033 - return ret;
31034 + vop->plane_name_list = plane_name_list;
31038 -EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
31042 @@ -2077,46 +4844,97 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
31046 - int ret, irq;
31055 return -ENODEV;
31057 + for (i = 0; i < vop_data->win_size; i++) {
31058 + const struct vop_win_data *win_data = &vop_data->win[i];
31060 + num_wins += win_data->area_size + 1;
31064 - vop = devm_kzalloc(dev, struct_size(vop, win, vop_data->win_size),
31065 - GFP_KERNEL);
31066 + alloc_size = sizeof(*vop) + sizeof(*vop->win) * num_wins;
31069 return -ENOMEM;
31071 vop->dev = dev;
31072 vop->data = vop_data;
31073 vop->drm_dev = drm_dev;
31074 + vop->num_wins = num_wins;
31075 + vop->version = vop_data->version;
31076 + vop->soc_id = vop_data->soc_id;
31077 + vop->id = vop_data->vop_id;
31079 + vop->support_multi_area = of_property_read_bool(dev->of_node, "support-multi-area");
31081 - vop_win_init(vop);
31086 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
31087 - vop->len = resource_size(res);
31090 + dev_warn(vop->dev, "failed to get vop register byname\n");
31093 vop->regs = devm_ioremap_resource(dev, res);
31094 if (IS_ERR(vop->regs))
31095 return PTR_ERR(vop->regs);
31096 + vop->len = resource_size(res);
31098 + vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
31099 + if (!vop->regsbak)
31100 + return -ENOMEM;
31102 - res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
31105 - if (!vop_data->lut_size) {
31106 - DRM_DEV_ERROR(dev, "no gamma LUT size defined\n");
31107 + vop->lut_len = resource_size(res) / sizeof(*vop->lut);
31108 + if (vop->lut_len != 256 && vop->lut_len != 1024) {
31109 + dev_err(vop->dev, "unsupported lut sizes %d\n",
31110 + vop->lut_len);
31111 return -EINVAL;
31114 vop->lut_regs = devm_ioremap_resource(dev, res);
31115 if (IS_ERR(vop->lut_regs))
31116 return PTR_ERR(vop->lut_regs);
31118 -
31119 - vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
31120 - if (!vop->regsbak)
31121 - return -ENOMEM;
31122 -
31123 + vop->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
31125 + if (IS_ERR(vop->grf))
31127 + vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
31128 + if (IS_ERR(vop->hclk)) {
31129 + dev_err(vop->dev, "failed to get hclk source\n");
31130 + return PTR_ERR(vop->hclk);
31132 + vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
31133 + if (IS_ERR(vop->aclk)) {
31134 + dev_err(vop->dev, "failed to get aclk source\n");
31135 + return PTR_ERR(vop->aclk);
31137 + vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
31138 + if (IS_ERR(vop->dclk)) {
31139 + dev_err(vop->dev, "failed to get dclk source\n");
31140 + return PTR_ERR(vop->dclk);
31142 + vop->dclk_source = devm_clk_get(vop->dev, "dclk_source");
31143 + if (PTR_ERR(vop->dclk_source) == -ENOENT) {
31144 + vop->dclk_source = NULL;
31145 + } else if (PTR_ERR(vop->dclk_source) == -EPROBE_DEFER) {
31146 + return -EPROBE_DEFER;
31147 + } else if (IS_ERR(vop->dclk_source)) {
31148 + dev_err(vop->dev, "failed to get dclk source parent\n");
31149 + return PTR_ERR(vop->dclk_source);
31154 @@ -2128,53 +4946,51 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
31155 spin_lock_init(&vop->irq_lock);
31156 mutex_init(&vop->vop_lock);
31158 + ret = devm_request_irq(dev, vop->irq, vop_isr,
31166 pm_runtime_enable(&pdev->dev);
31168 - ret = vop_initial(vop);
31169 - if (ret < 0) {
31170 - DRM_DEV_ERROR(&pdev->dev,
31171 - "cannot initial vop dev - err %d\n", ret);
31172 - goto err_disable_pm_runtime;
31173 - }
31174 -
31175 - ret = devm_request_irq(dev, vop->irq, vop_isr,
31176 - IRQF_SHARED, dev_name(dev), vop);
31177 - if (ret)
31178 - goto err_disable_pm_runtime;
31180 - if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) {
31181 - vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev);
31182 - if (IS_ERR(vop->rgb)) {
31183 - ret = PTR_ERR(vop->rgb);
31184 - goto err_disable_pm_runtime;
31185 - }
31186 + mcu = of_get_child_by_name(dev->of_node, "mcu-timing");
31188 + dev_dbg(dev, "no mcu-timing node found in %s\n",
31189 + dev->of_node->full_name);
31193 + if (!of_property_read_u32(mcu, "mcu-pix-total", &val))
31194 + vop->mcu_timing.mcu_pix_total = val;
31195 + if (!of_property_read_u32(mcu, "mcu-cs-pst", &val))
31196 + vop->mcu_timing.mcu_cs_pst = val;
31197 + if (!of_property_read_u32(mcu, "mcu-cs-pend", &val))
31198 + vop->mcu_timing.mcu_cs_pend = val;
31199 + if (!of_property_read_u32(mcu, "mcu-rw-pst", &val))
31200 + vop->mcu_timing.mcu_rw_pst = val;
31201 + if (!of_property_read_u32(mcu, "mcu-rw-pend", &val))
31202 + vop->mcu_timing.mcu_rw_pend = val;
31203 + if (!of_property_read_u32(mcu, "mcu-hold-mode", &val))
31204 + vop->mcu_timing.mcu_hold_mode = val;
31207 - return 0;
31208 + dual_channel_swap = of_property_read_bool(dev->of_node,
31209 + "rockchip,dual-channel-swap");
31210 + vop->dual_channel_swap = dual_channel_swap;
31212 -err_disable_pm_runtime:
31213 - pm_runtime_disable(&pdev->dev);
31214 - vop_destroy_crtc(vop);
31215 - return ret;
31223 - if (vop->rgb)
31224 - rockchip_rgb_fini(vop->rgb);
31225 -
31228 -
31229 - clk_unprepare(vop->aclk);
31230 - clk_unprepare(vop->hclk);
31231 - clk_unprepare(vop->dclk);
31235 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vo…
31237 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
31239 @@ -7,6 +7,9 @@
31249 @@ -15,104 +18,343 @@
31253 -#define NUM_YUV2YUV_COEFFICIENTS 12
31257 -/* AFBC supports a number of configurable modes. Relevant to us is block size
31258 - * (16x16 or 32x8), storage modifiers (SPARSE, SPLIT), and the YUV-like
31259 - * colourspace transform (YTR). 16x16 SPARSE mode is always used. SPLIT mode
31260 - * could be enabled via the hreg_block_split register, but is not currently
31261 - * handled. The colourspace transform is implicitly always assumed by the
31262 - * decoder, so consumers must use this transform as well.
31263 - *
31264 - * Failure to match modifiers will cause errors displaying AFBC buffers
31265 - * produced by conformant AFBC producers, including Mesa.
31298 + * Cluster1---->Cluster0
31299 + * Esmart1 ---->Esmart0
31300 + * Smart1 ---->Smart0
31316 + ROCKCHIP_VOP_PHY_ID_INVALID = -1,
31358 -#define ROCKCHIP_AFBC_MOD \
31359 - DRM_FORMAT_MOD_ARM_AFBC( \
31360 - AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE \
31361 - | AFBC_FORMAT_MOD_YTR \
31362 - )
31405 - VOP_FMT_RGB565,
31427 - uint16_t offset;
31428 - uint8_t shift;
31429 - bool write_mask;
31430 - bool relaxed;
31440 -struct vop_afbc {
31441 - struct vop_reg enable;
31442 - struct vop_reg win_sel;
31443 - struct vop_reg format;
31444 - struct vop_reg hreg_block_split;
31445 - struct vop_reg pic_size;
31446 - struct vop_reg hdr_ptr;
31447 - struct vop_reg rstn;
31464 -struct vop_modeset {
31473 - struct vop_reg hpost_st_end;
31480 -};
31481 -
31482 -struct vop_output {
31483 - struct vop_reg pin_pol;
31484 - struct vop_reg dp_pin_pol;
31485 - struct vop_reg dp_dclk_pol;
31486 - struct vop_reg edp_pin_pol;
31487 - struct vop_reg edp_dclk_pol;
31488 - struct vop_reg hdmi_pin_pol;
31489 - struct vop_reg hdmi_dclk_pol;
31490 - struct vop_reg mipi_pin_pol;
31491 - struct vop_reg mipi_dclk_pol;
31492 - struct vop_reg rgb_pin_pol;
31493 - struct vop_reg rgb_dclk_pol;
31494 - struct vop_reg dp_en;
31515 - struct vop_reg rgb_en;
31516 -};
31517 -
31518 -struct vop_common {
31519 - struct vop_reg cfg_done;
31520 - struct vop_reg dsp_blank;
31521 - struct vop_reg data_blank;
31522 - struct vop_reg pre_dither_down;
31541 - struct vop_reg dither_up;
31561 - struct vop_reg gate_en;
31562 - struct vop_reg mmu_en;
31565 - struct vop_reg standby;
31566 -};
31568 -struct vop_misc {
31569 - struct vop_reg global_regdone_en;
31650 -
31654 @@ -152,19 +394,129 @@ struct vop_scl_regs {
31658 -struct vop_yuv2yuv_phy {
31659 - struct vop_reg y2r_coefficients[NUM_YUV2YUV_COEFFICIENTS];
31774 - const uint64_t *format_modifiers;
31776 - struct vop_reg enable;
31788 @@ -173,56 +525,615 @@ struct vop_win_phy {
31792 - struct vop_reg y_mir_en;
31793 - struct vop_reg x_mir_en;
31798 - struct vop_reg alpha_pre_mul;
31801 - struct vop_reg channel;
31808 -struct vop_win_yuv2yuv_data {
31811 - const struct vop_yuv2yuv_phy *phy;
31885 -struct vop_win_data {
32089 - const struct vop_win_phy *phy;
32166 + * struct vop2_layer_data - The logic graphic layer in vop2
32170 + * LAYERn-1
32186 + * win-->layer-->mixer-->vp--->connector(RGB/LVDS/HDMI/MIPI)
32209 - uint32_t version;
32214 - const struct vop_common *common;
32215 - const struct vop_misc *misc;
32216 - const struct vop_modeset *modeset;
32217 - const struct vop_output *output;
32218 - const struct vop_afbc *afbc;
32219 - const struct vop_win_yuv2yuv_data *win_yuv2yuv;
32225 - unsigned int lut_size;
32226 -
32227 -#define VOP_FEATURE_OUTPUT_RGB10 BIT(0)
32228 -#define VOP_FEATURE_INTERNAL_RGB BIT(1)
32390 -#define DSP_HOLD_VALID_INTR (1 << 0)
32391 -#define FS_INTR (1 << 1)
32392 -#define LINE_FLAG_INTR (1 << 2)
32393 -#define BUS_ERROR_INTR (1 << 3)
32416 - LINE_FLAG_INTR | BUS_ERROR_INTR)
32417 -
32429 @@ -256,14 +1167,19 @@ struct vop_data {
32433 -#define ROCKCHIP_OUT_MODE_P888 0
32434 -#define ROCKCHIP_OUT_MODE_P666 1
32435 -#define ROCKCHIP_OUT_MODE_P565 2
32445 -#define ROCKCHIP_OUT_MODE_AAAA 15
32448 -/* output flags */
32449 -#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0)
32455 @@ -292,6 +1208,25 @@ enum factor_mode {
32481 @@ -319,6 +1254,18 @@ enum scale_down_mode {
32500 @@ -332,9 +1279,11 @@ enum dither_down_mode_sel {
32504 - DEN_NEGATIVE = 2
32513 @@ -359,7 +1308,7 @@ static inline uint16_t scl_get_bili_dn_vskip(int src_h, int dst_h,
32517 - act_height = DIV_ROUND_UP(src_h, vskiplines);
32518 + act_height = (src_h + vskiplines - 1) / vskiplines;
32522 @@ -409,5 +1358,16 @@ static inline int scl_vop_cal_lb_mode(int width, bool is_yuv)
32528 + return us * mode->clock / mode->htotal / 1000;
32533 + return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
32539 diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
32541 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
32543 @@ -6,98 +6,141 @@
32544 * Sandy Huang <hjc@rock-chips.com>
32547 -#include <linux/clk.h>
32552 -#include <linux/pinctrl/devinfo.h>
32553 -#include <linux/platform_device.h>
32554 -#include <linux/pm_runtime.h>
32557 -#include <linux/reset.h>
32558 -
32561 -#include <drm/drm_dp_helper.h>
32571 -#include "rockchip_lvds.h"
32573 -#define DISPLAY_OUTPUT_RGB 0
32574 -#define DISPLAY_OUTPUT_LVDS 1
32575 -#define DISPLAY_OUTPUT_DUAL_LVDS 2
32640 -#define connector_to_lvds(c) \
32641 - container_of(c, struct rockchip_lvds, connector)
32642 -
32643 -#define encoder_to_lvds(c) \
32644 - container_of(c, struct rockchip_lvds, encoder)
32645 -
32646 -/**
32647 - * rockchip_lvds_soc_data - rockchip lvds Soc private data
32648 - * @probe: LVDS platform probe function
32649 - * @helper_funcs: LVDS connector helper functions
32650 - */
32651 -struct rockchip_lvds_soc_data {
32652 - int (*probe)(struct platform_device *pdev, struct rockchip_lvds *lvds);
32653 - const struct drm_encoder_helper_funcs *helper_funcs;
32663 - void __iomem *regs;
32666 - struct clk *pclk;
32667 - struct phy *dphy;
32668 - const struct rockchip_lvds_soc_data *soc_data;
32669 - int output; /* rgb lvds or dual lvds output */
32670 - int format; /* vesa or jeida format */
32671 - struct drm_device *drm_dev;
32685 - struct dev_pin_info *pins;
32690 -static inline void rk3288_writel(struct rockchip_lvds *lvds, u32 offset,
32691 - u32 val)
32694 - writel_relaxed(val, lvds->regs + offset);
32695 - if (lvds->output == DISPLAY_OUTPUT_LVDS)
32696 - return;
32697 - writel_relaxed(val, lvds->regs + offset + RK3288_LVDS_CH1_OFFSET);
32701 -static inline int rockchip_lvds_name_to_format(const char *s)
32704 - if (strncmp(s, "jeida-18", 8) == 0)
32705 - return LVDS_JEIDA_18;
32706 - else if (strncmp(s, "jeida-24", 8) == 0)
32707 - return LVDS_JEIDA_24;
32708 - else if (strncmp(s, "vesa-24", 7) == 0)
32709 - return LVDS_VESA_24;
32710 -
32711 - return -EINVAL;
32715 -static inline int rockchip_lvds_name_to_output(const char *s)
32722 - if (strncmp(s, "rgb", 3) == 0)
32723 - return DISPLAY_OUTPUT_RGB;
32724 - else if (strncmp(s, "lvds", 4) == 0)
32725 - return DISPLAY_OUTPUT_LVDS;
32726 - else if (strncmp(s, "duallvds", 8) == 0)
32727 - return DISPLAY_OUTPUT_DUAL_LVDS;
32729 + struct rockchip_drm_private *private = connector->dev->dev_private;
32731 + if (property == private->connector_id_prop) {
32732 + *val = lvds->id;
32737 return -EINVAL;
32740 @@ -107,6 +150,7 @@ static const struct drm_connector_funcs rockchip_lvds_connector_funcs = {
32748 @@ -122,500 +166,235 @@ struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = {
32752 -static int
32753 -rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder,
32754 - struct drm_crtc_state *crtc_state,
32755 - struct drm_connector_state *conn_state)
32756 -{
32757 - struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
32758 -
32759 - s->output_mode = ROCKCHIP_OUT_MODE_P888;
32760 - s->output_type = DRM_MODE_CONNECTOR_LVDS;
32761 -
32762 - return 0;
32763 -}
32764 -
32765 -static int rk3288_lvds_poweron(struct rockchip_lvds *lvds)
32771 - int ret;
32772 - u32 val;
32773 -
32774 - ret = clk_enable(lvds->pclk);
32775 - if (ret < 0) {
32776 - DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
32777 - return ret;
32778 - }
32779 - ret = pm_runtime_get_sync(lvds->dev);
32780 - if (ret < 0) {
32781 - DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
32782 - clk_disable(lvds->pclk);
32783 - return ret;
32784 - }
32785 - val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN |
32786 - RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN |
32787 - RK3288_LVDS_CH0_REG0_LANE0_EN;
32788 - if (lvds->output == DISPLAY_OUTPUT_RGB) {
32789 - val |= RK3288_LVDS_CH0_REG0_TTL_EN |
32790 - RK3288_LVDS_CH0_REG0_LANECK_EN;
32791 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val);
32792 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG2,
32793 - RK3288_LVDS_PLL_FBDIV_REG2(0x46));
32794 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG4,
32795 - RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE |
32796 - RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE |
32797 - RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE |
32798 - RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE |
32799 - RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE |
32800 - RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE);
32801 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG5,
32802 - RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA |
32803 - RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA |
32804 - RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA |
32805 - RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA |
32806 - RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA |
32807 - RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA);
32808 - } else {
32809 - val |= RK3288_LVDS_CH0_REG0_LVDS_EN |
32810 - RK3288_LVDS_CH0_REG0_LANECK_EN;
32811 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val);
32812 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG1,
32813 - RK3288_LVDS_CH0_REG1_LANECK_BIAS |
32814 - RK3288_LVDS_CH0_REG1_LANE4_BIAS |
32815 - RK3288_LVDS_CH0_REG1_LANE3_BIAS |
32816 - RK3288_LVDS_CH0_REG1_LANE2_BIAS |
32817 - RK3288_LVDS_CH0_REG1_LANE1_BIAS |
32818 - RK3288_LVDS_CH0_REG1_LANE0_BIAS);
32819 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG2,
32820 - RK3288_LVDS_CH0_REG2_RESERVE_ON |
32821 - RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE |
32822 - RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE |
32823 - RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE |
32824 - RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE |
32825 - RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE |
32826 - RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE |
32827 - RK3288_LVDS_PLL_FBDIV_REG2(0x46));
32828 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00);
32829 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00);
32831 + struct drm_connector *connector = &lvds->connector;
32832 + struct drm_display_info *info = &connector->display_info;
32835 + if (info->num_bus_formats)
32836 + bus_format = info->bus_formats[0];
32839 + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* jeida-24 */
32840 + lvds->format = LVDS_8BIT_MODE_FORMAT_2;
32842 + case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA: /* jeida-30 */
32843 + lvds->format = LVDS_10BIT_MODE_FORMAT_2;
32845 + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* vesa-18 */
32846 + lvds->format = LVDS_8BIT_MODE_FORMAT_3;
32848 + case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG: /* vesa-30 */
32849 + lvds->format = LVDS_10BIT_MODE_FORMAT_1;
32851 + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* vesa-24 */
32853 + lvds->format = LVDS_8BIT_MODE_FORMAT_1;
32856 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG3,
32857 - RK3288_LVDS_PLL_FBDIV_REG3(0x46));
32858 - rk3288_writel(lvds, RK3288_LVDS_CH0_REGD,
32859 - RK3288_LVDS_PLL_PREDIV_REGD(0x0a));
32860 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG20,
32861 - RK3288_LVDS_CH0_REG20_LSB);
32862 -
32863 - rk3288_writel(lvds, RK3288_LVDS_CFG_REGC,
32864 - RK3288_LVDS_CFG_REGC_PLL_ENABLE);
32865 - rk3288_writel(lvds, RK3288_LVDS_CFG_REG21,
32866 - RK3288_LVDS_CFG_REG21_TX_ENABLE);
32867 -
32868 - return 0;
32869 -}
32871 -static void rk3288_lvds_poweroff(struct rockchip_lvds *lvds)
32872 -{
32873 - int ret;
32874 - u32 val;
32875 + if (lvds->secondary)
32876 + lvds->secondary->format = lvds->format;
32878 - rk3288_writel(lvds, RK3288_LVDS_CFG_REG21,
32879 - RK3288_LVDS_CFG_REG21_TX_ENABLE);
32880 - rk3288_writel(lvds, RK3288_LVDS_CFG_REGC,
32881 - RK3288_LVDS_CFG_REGC_PLL_ENABLE);
32882 - val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN;
32883 - val |= val << 16;
32884 - ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val);
32885 - if (ret != 0)
32886 - DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret);
32887 -
32888 - pm_runtime_put(lvds->dev);
32889 - clk_disable(lvds->pclk);
32890 + drm_mode_copy(&lvds->mode, &crtc_state->adjusted_mode);
32893 -static int rk3288_lvds_grf_config(struct drm_encoder *encoder,
32894 - struct drm_display_mode *mode)
32902 - u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0;
32903 - u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0;
32904 - u32 val;
32905 - int ret;
32906 -
32907 - /* iomux to LCD data/sync mode */
32908 - if (lvds->output == DISPLAY_OUTPUT_RGB)
32909 - if (lvds->pins && !IS_ERR(lvds->pins->default_state))
32910 - pinctrl_select_state(lvds->pins->p,
32911 - lvds->pins->default_state);
32912 - val = lvds->format | LVDS_CH0_EN;
32913 - if (lvds->output == DISPLAY_OUTPUT_RGB)
32914 - val |= LVDS_TTL_EN | LVDS_CH1_EN;
32915 - else if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS)
32916 - val |= LVDS_DUAL | LVDS_CH1_EN;
32917 -
32918 - if ((mode->htotal - mode->hsync_start) & 0x01)
32919 - val |= LVDS_START_PHASE_RST_1;
32920 -
32921 - val |= (pin_dclk << 8) | (pin_hsync << 9);
32922 - val |= (0xffff << 16);
32923 - ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val);
32924 - if (ret)
32925 - DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret);
32926 -
32927 - return ret;
32928 -}
32929 + struct drm_connector *connector = conn_state->connector;
32930 + struct drm_display_info *info = &connector->display_info;
32932 -static int rk3288_lvds_set_vop_source(struct rockchip_lvds *lvds,
32933 - struct drm_encoder *encoder)
32934 -{
32935 - u32 val;
32936 - int ret;
32937 + if (info->num_bus_formats)
32938 + s->bus_format = info->bus_formats[0];
32940 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
32942 - ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder);
32943 - if (ret < 0)
32944 - return ret;
32945 + s->output_mode = ROCKCHIP_OUT_MODE_P888;
32947 - val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16;
32948 - if (ret)
32949 - val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT;
32950 + if (s->bus_format == MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG ||
32951 + s->bus_format == MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA)
32952 + s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
32954 - ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON6, val);
32955 - if (ret < 0)
32956 - return ret;
32957 + s->output_type = DRM_MODE_CONNECTOR_LVDS;
32958 + s->bus_flags = info->bus_flags;
32959 + s->tv_state = &conn_state->tv;
32960 + s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
32961 + s->color_space = V4L2_COLORSPACE_DEFAULT;
32963 + switch (lvds->pixel_order) {
32965 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
32966 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32969 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
32970 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
32971 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32978 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
32979 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32982 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
32983 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
32984 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32988 + if (lvds->id)
32989 + s->output_if |= VOP_OUTPUT_IF_LVDS1;
32991 + s->output_if |= VOP_OUTPUT_IF_LVDS0;
32998 -static void rk3288_lvds_encoder_enable(struct drm_encoder *encoder)
33001 - struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
33002 - struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
33005 - drm_panel_prepare(lvds->panel);
33006 -
33007 - ret = rk3288_lvds_poweron(lvds);
33008 - if (ret < 0) {
33009 - DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret);
33010 - drm_panel_unprepare(lvds->panel);
33011 - return;
33012 - }
33013 -
33014 - ret = rk3288_lvds_grf_config(encoder, mode);
33015 - if (ret) {
33016 - DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret);
33017 - drm_panel_unprepare(lvds->panel);
33018 - return;
33019 - }
33020 + if (lvds->funcs->enable)
33021 + lvds->funcs->enable(lvds);
33023 - ret = rk3288_lvds_set_vop_source(lvds, encoder);
33024 + ret = phy_set_mode(lvds->phy, PHY_MODE_LVDS);
33026 - DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret);
33027 - drm_panel_unprepare(lvds->panel);
33028 + DRM_DEV_ERROR(lvds->dev, "failed to set phy mode: %d\n", ret);
33032 - drm_panel_enable(lvds->panel);
33033 -}
33034 -
33035 -static void rk3288_lvds_encoder_disable(struct drm_encoder *encoder)
33036 -{
33037 - struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
33038 + phy_power_on(lvds->phy);
33040 - drm_panel_disable(lvds->panel);
33041 - rk3288_lvds_poweroff(lvds);
33042 - drm_panel_unprepare(lvds->panel);
33043 + if (lvds->secondary)
33044 + rockchip_lvds_enable(lvds->secondary);
33047 -static int px30_lvds_poweron(struct rockchip_lvds *lvds)
33050 - int ret;
33051 -
33052 - ret = pm_runtime_get_sync(lvds->dev);
33053 - if (ret < 0) {
33054 - DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
33055 - return ret;
33056 - }
33057 -
33058 - /* Enable LVDS mode */
33059 - return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
33060 - PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1),
33061 - PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1));
33062 -}
33063 + if (lvds->funcs->disable)
33064 + lvds->funcs->disable(lvds);
33066 -static void px30_lvds_poweroff(struct rockchip_lvds *lvds)
33067 -{
33068 - regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
33069 - PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1),
33070 - PX30_LVDS_MODE_EN(0) | PX30_LVDS_P2S_EN(0));
33071 + phy_power_off(lvds->phy);
33073 - pm_runtime_put(lvds->dev);
33074 + if (lvds->secondary)
33075 + rockchip_lvds_disable(lvds->secondary);
33078 -static int px30_lvds_grf_config(struct drm_encoder *encoder,
33079 - struct drm_display_mode *mode)
33084 - if (lvds->output != DISPLAY_OUTPUT_LVDS) {
33085 - DRM_DEV_ERROR(lvds->dev, "Unsupported display output %d\n",
33086 - lvds->output);
33087 - return -EINVAL;
33088 - }
33089 -
33090 - /* Set format */
33091 - return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
33092 - PX30_LVDS_FORMAT(lvds->format),
33093 - PX30_LVDS_FORMAT(lvds->format));
33094 -}
33095 -
33096 -static int px30_lvds_set_vop_source(struct rockchip_lvds *lvds,
33097 - struct drm_encoder *encoder)
33098 -{
33099 - int vop;
33100 -
33101 - vop = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder);
33102 - if (vop < 0)
33103 - return vop;
33104 -
33105 - return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
33106 - PX30_LVDS_VOP_SEL(1),
33107 - PX30_LVDS_VOP_SEL(vop));
33108 + if (lvds->panel)
33109 + drm_panel_prepare(lvds->panel);
33111 + if (lvds->panel)
33112 + drm_panel_enable(lvds->panel);
33115 -static void px30_lvds_encoder_enable(struct drm_encoder *encoder)
33119 - struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
33120 - int ret;
33121 -
33122 - drm_panel_prepare(lvds->panel);
33123 -
33124 - ret = px30_lvds_poweron(lvds);
33125 - if (ret) {
33126 - DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret);
33127 - drm_panel_unprepare(lvds->panel);
33128 - return;
33129 - }
33130 -
33131 - ret = px30_lvds_grf_config(encoder, mode);
33132 - if (ret) {
33133 - DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret);
33134 - drm_panel_unprepare(lvds->panel);
33135 - return;
33136 - }
33138 - ret = px30_lvds_set_vop_source(lvds, encoder);
33139 - if (ret) {
33140 - DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret);
33141 + if (lvds->panel)
33142 + drm_panel_disable(lvds->panel);
33144 + if (lvds->panel)
33145 drm_panel_unprepare(lvds->panel);
33146 - return;
33147 - }
33148 -
33149 - drm_panel_enable(lvds->panel);
33152 -static void px30_lvds_encoder_disable(struct drm_encoder *encoder)
33158 - drm_panel_disable(lvds->panel);
33159 - px30_lvds_poweroff(lvds);
33160 - drm_panel_unprepare(lvds->panel);
33161 + if (lvds->panel)
33162 + panel_simple_loader_protect(lvds->panel);
33166 -struct drm_encoder_helper_funcs rk3288_lvds_encoder_helper_funcs = {
33167 - .enable = rk3288_lvds_encoder_enable,
33168 - .disable = rk3288_lvds_encoder_disable,
33176 -static const
33177 -struct drm_encoder_helper_funcs px30_lvds_encoder_helper_funcs = {
33178 - .enable = px30_lvds_encoder_enable,
33179 - .disable = px30_lvds_encoder_disable,
33180 - .atomic_check = rockchip_lvds_encoder_atomic_check,
33185 -static int rk3288_lvds_probe(struct platform_device *pdev,
33186 - struct rockchip_lvds *lvds)
33189 - struct resource *res;
33190 - int ret;
33191 -
33192 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
33193 - lvds->regs = devm_ioremap_resource(lvds->dev, res);
33194 - if (IS_ERR(lvds->regs))
33195 - return PTR_ERR(lvds->regs);
33196 -
33197 - lvds->pclk = devm_clk_get(lvds->dev, "pclk_lvds");
33198 - if (IS_ERR(lvds->pclk)) {
33199 - DRM_DEV_ERROR(lvds->dev, "could not get pclk_lvds\n");
33200 - return PTR_ERR(lvds->pclk);
33201 - }
33202 -
33203 - lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins),
33204 - GFP_KERNEL);
33205 - if (!lvds->pins)
33206 - return -ENOMEM;
33207 -
33208 - lvds->pins->p = devm_pinctrl_get(lvds->dev);
33209 - if (IS_ERR(lvds->pins->p)) {
33210 - DRM_DEV_ERROR(lvds->dev, "no pinctrl handle\n");
33211 - devm_kfree(lvds->dev, lvds->pins);
33212 - lvds->pins = NULL;
33213 - } else {
33214 - lvds->pins->default_state =
33215 - pinctrl_lookup_state(lvds->pins->p, "lcdc");
33216 - if (IS_ERR(lvds->pins->default_state)) {
33217 - DRM_DEV_ERROR(lvds->dev, "no default pinctrl state\n");
33218 - devm_kfree(lvds->dev, lvds->pins);
33219 - lvds->pins = NULL;
33220 - }
33221 - }
33222 -
33223 - ret = clk_prepare(lvds->pclk);
33224 - if (ret < 0) {
33225 - DRM_DEV_ERROR(lvds->dev, "failed to prepare pclk_lvds\n");
33226 - return ret;
33227 - }
33231 - return 0;
33232 + return lvds->id == *id;
33235 -static int px30_lvds_probe(struct platform_device *pdev,
33236 - struct rockchip_lvds *lvds)
33240 - int ret;
33241 -
33242 - /* MSB */
33243 - ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
33244 - PX30_LVDS_MSBSEL(1),
33245 - PX30_LVDS_MSBSEL(1));
33246 - if (ret)
33247 - return ret;
33248 -
33249 - /* PHY */
33250 - lvds->dphy = devm_phy_get(&pdev->dev, "dphy");
33251 - if (IS_ERR(lvds->dphy))
33252 - return PTR_ERR(lvds->dphy);
33253 -
33254 - ret = phy_init(lvds->dphy);
33255 - if (ret)
33256 - return ret;
33259 - ret = phy_set_mode(lvds->dphy, PHY_MODE_LVDS);
33260 - if (ret)
33261 - return ret;
33266 - return phy_power_on(lvds->dphy);
33270 -static const struct rockchip_lvds_soc_data rk3288_lvds_data = {
33271 - .probe = rk3288_lvds_probe,
33272 - .helper_funcs = &rk3288_lvds_encoder_helper_funcs,
33273 -};
33274 -
33275 -static const struct rockchip_lvds_soc_data px30_lvds_data = {
33276 - .probe = px30_lvds_probe,
33277 - .helper_funcs = &px30_lvds_encoder_helper_funcs,
33278 -};
33279 -
33280 -static const struct of_device_id rockchip_lvds_dt_ids[] = {
33281 - {
33282 - .compatible = "rockchip,rk3288-lvds",
33283 - .data = &rk3288_lvds_data
33284 - },
33285 - {
33286 - .compatible = "rockchip,px30-lvds",
33287 - .data = &px30_lvds_data
33288 - },
33289 - {}
33290 -};
33291 -MODULE_DEVICE_TABLE(of, rockchip_lvds_dt_ids);
33292 -
33298 - struct drm_encoder *encoder;
33299 - struct drm_connector *connector;
33300 - struct device_node *remote = NULL;
33301 - struct device_node *port, *endpoint;
33302 - int ret = 0, child_count = 0;
33303 - const char *name;
33304 - u32 endpoint_id = 0;
33305 -
33306 - lvds->drm_dev = drm_dev;
33307 - port = of_graph_get_port_by_id(dev->of_node, 1);
33308 - if (!port) {
33309 - DRM_DEV_ERROR(dev,
33310 - "can't found port point, please init lvds panel port!\n");
33311 - return -EINVAL;
33312 - }
33313 - for_each_child_of_node(port, endpoint) {
33314 - child_count++;
33315 - of_property_read_u32(endpoint, "reg", &endpoint_id);
33316 - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id,
33317 - &lvds->panel, &lvds->bridge);
33318 - if (!ret) {
33319 - of_node_put(endpoint);
33320 - break;
33321 - }
33322 - }
33323 - if (!child_count) {
33324 - DRM_DEV_ERROR(dev, "lvds port does not have any children\n");
33325 - ret = -EINVAL;
33326 - goto err_put_port;
33327 - } else if (ret) {
33328 - DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n");
33329 - ret = -EPROBE_DEFER;
33330 - goto err_put_port;
33331 - }
33332 - if (lvds->panel)
33333 - remote = lvds->panel->dev->of_node;
33334 - else
33335 - remote = lvds->bridge->of_node;
33336 - if (of_property_read_string(dev->of_node, "rockchip,output", &name))
33337 - /* default set it as output rgb */
33338 - lvds->output = DISPLAY_OUTPUT_RGB;
33339 - else
33340 - lvds->output = rockchip_lvds_name_to_output(name);
33341 -
33342 - if (lvds->output < 0) {
33343 - DRM_DEV_ERROR(dev, "invalid output type [%s]\n", name);
33344 - ret = lvds->output;
33345 - goto err_put_remote;
33346 - }
33347 + struct drm_encoder *encoder = &lvds->encoder;
33348 + struct drm_connector *connector = &lvds->connector;
33351 - if (of_property_read_string(remote, "data-mapping", &name))
33352 - /* default set it as format vesa 18 */
33353 - lvds->format = LVDS_VESA_18;
33354 - else
33355 - lvds->format = rockchip_lvds_name_to_format(name);
33359 + if (lvds->primary)
33362 - if (lvds->format < 0) {
33363 - DRM_DEV_ERROR(dev, "invalid data-mapping format [%s]\n", name);
33364 - ret = lvds->format;
33365 - goto err_put_remote;
33366 - }
33367 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
33368 + &lvds->panel, &lvds->bridge);
33372 - encoder = &lvds->encoder;
33373 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
33374 - dev->of_node);
33375 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
33376 + dev->of_node);
33378 - ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_LVDS);
33382 - DRM_DEV_ERROR(drm_dev->dev,
33383 + DRM_DEV_ERROR(lvds->dev,
33385 - goto err_put_remote;
33389 - drm_encoder_helper_add(encoder, lvds->soc_data->helper_funcs);
33392 if (lvds->panel) {
33393 - connector = &lvds->connector;
33394 - connector->dpms = DRM_MODE_DPMS_OFF;
33395 + struct rockchip_drm_private *private = drm_dev->dev_private;
33400 @@ -630,34 +409,31 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
33404 - DRM_DEV_ERROR(drm_dev->dev,
33405 + DRM_DEV_ERROR(lvds->dev,
33410 + lvds->sub_dev.connector = &lvds->connector;
33411 + lvds->sub_dev.of_node = lvds->dev->of_node;
33412 + lvds->sub_dev.loader_protect = rockchip_lvds_encoder_loader_protect;
33413 + rockchip_drm_register_sub_dev(&lvds->sub_dev);
33414 + drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
33416 ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);
33418 - DRM_DEV_ERROR(drm_dev->dev,
33419 + DRM_DEV_ERROR(lvds->dev,
33425 - pm_runtime_enable(dev);
33426 - of_node_put(remote);
33427 - of_node_put(port);
33428 -
33435 -err_put_remote:
33436 - of_node_put(remote);
33437 -err_put_port:
33438 - of_node_put(port);
33439 -
33443 @@ -665,13 +441,14 @@ static void rockchip_lvds_unbind(struct device *dev, struct device *master,
33447 - const struct drm_encoder_helper_funcs *encoder_funcs;
33449 - encoder_funcs = lvds->soc_data->helper_funcs;
33450 - encoder_funcs->disable(&lvds->encoder);
33451 - pm_runtime_disable(dev);
33452 - drm_connector_cleanup(&lvds->connector);
33453 - drm_encoder_cleanup(&lvds->encoder);
33454 + if (lvds->sub_dev.connector)
33455 + rockchip_drm_unregister_sub_dev(&lvds->sub_dev);
33456 + if (lvds->panel)
33457 + drm_connector_cleanup(&lvds->connector);
33459 + if (lvds->encoder.dev)
33460 + drm_encoder_cleanup(&lvds->encoder);
33464 @@ -683,56 +460,219 @@ static int rockchip_lvds_probe(struct platform_device *pdev)
33466 struct device *dev = &pdev->dev;
33468 - const struct of_device_id *match;
33471 if (!dev->of_node)
33472 return -ENODEV;
33474 - lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
33477 return -ENOMEM;
33479 + lvds->id = of_alias_get_id(dev->of_node, "lvds");
33480 + if (lvds->id < 0)
33481 + lvds->id = 0;
33483 lvds->dev = dev;
33484 - match = of_match_node(rockchip_lvds_dt_ids, dev->of_node);
33485 - if (!match)
33486 - return -ENODEV;
33487 - lvds->soc_data = match->data;
33488 + lvds->funcs = of_device_get_match_data(dev);
33491 + lvds->dual_channel = of_property_read_bool(dev->of_node,
33492 + "dual-channel");
33493 + lvds->data_swap = of_property_read_bool(dev->of_node,
33494 + "rockchip,data-swap");
33496 + lvds->phy = devm_phy_get(dev, "phy");
33497 + if (IS_ERR(lvds->phy)) {
33498 + ret = PTR_ERR(lvds->phy);
33503 - lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
33504 - "rockchip,grf");
33505 + lvds->grf = syscon_node_to_regmap(dev->parent->of_node);
33506 if (IS_ERR(lvds->grf)) {
33507 - DRM_DEV_ERROR(dev, "missing rockchip,grf property\n");
33508 - return PTR_ERR(lvds->grf);
33509 + ret = PTR_ERR(lvds->grf);
33514 - ret = lvds->soc_data->probe(pdev, lvds);
33515 - if (ret) {
33516 - DRM_DEV_ERROR(dev, "Platform initialization failed\n");
33517 - return ret;
33518 + lvds->pixel_order = -1;
33519 + if (lvds->funcs->probe) {
33520 + ret = lvds->funcs->probe(lvds);
33525 - dev_set_drvdata(dev, lvds);
33531 + component_del(&pdev->dev, &rockchip_lvds_component_ops);
33536 - ret = component_add(&pdev->dev, &rockchip_lvds_component_ops);
33537 - if (ret < 0) {
33538 - DRM_DEV_ERROR(dev, "failed to add component\n");
33539 - clk_unprepare(lvds->pclk);
33542 + int pipe = drm_of_encoder_active_endpoint_id(lvds->dev->of_node,
33543 + &lvds->encoder);
33545 + regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1,
33546 + PX30_LVDS_SELECT(lvds->format) |
33553 + regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1,
33564 + regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0,
33566 + RK3126_LVDS_MSBSEL(1) | RK3126_LVDS_SELECT(lvds->format));
33571 + regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0,
33582 + struct drm_display_mode *mode = &lvds->mode;
33586 + pipe = drm_of_encoder_active_endpoint_id(lvds->dev->of_node,
33587 + &lvds->encoder);
33588 + regmap_write(lvds->grf, RK3288_GRF_SOC_CON6,
33592 + RK3288_LVDS_CON_CHASEL(lvds->dual_channel) |
33593 + RK3288_LVDS_CON_SELECT(lvds->format);
33595 + if (lvds->dual_channel) {
33596 + u32 h_bp = mode->htotal - mode->hsync_start;
33600 + RK3288_LVDS_CON_STARTSEL(lvds->data_swap);
33612 - return ret;
33613 + regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, val);
33615 + phy_set_bus_width(lvds->phy, lvds->dual_channel ? 2 : 1);
33618 -static int rockchip_lvds_remove(struct platform_device *pdev)
33621 - struct rockchip_lvds *lvds = dev_get_drvdata(&pdev->dev);
33622 + regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, RK3288_LVDS_PWRDWN(1));
33625 - component_del(&pdev->dev, &rockchip_lvds_component_ops);
33626 - clk_unprepare(lvds->pclk);
33634 + regmap_write(lvds->grf, RK3368_GRF_SOC_CON7,
33635 + RK3368_LVDS_SELECT(lvds->format) |
33642 + regmap_write(lvds->grf, RK3368_GRF_SOC_CON7,
33653 + if (lvds->dual_channel) {
33658 + secondary = rockchip_lvds_find_by_id(lvds->dev->driver, 1);
33660 + return -EPROBE_DEFER;
33662 + port0 = of_graph_get_port_by_id(lvds->dev->of_node, 1);
33663 + port1 = of_graph_get_port_by_id(secondary->dev->of_node, 1);
33668 + secondary->primary = lvds;
33669 + lvds->secondary = secondary;
33670 + lvds->pixel_order = pixel_order >= 0 ? pixel_order : 0;
33678 + regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
33681 + regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
33682 + RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1));
33687 + regmap_write(lvds->grf, RK3568_GRF_VO_CON2, RK3568_LVDS0_MODE_EN(0));
33696 + { .compatible = "rockchip,px30-lvds", .data = &px30_lvds_funcs },
33697 + { .compatible = "rockchip,rk3126-lvds", .data = &rk3126_lvds_funcs },
33698 + { .compatible = "rockchip,rk3288-lvds", .data = &rk3288_lvds_funcs },
33699 + { .compatible = "rockchip,rk3368-lvds", .data = &rk3368_lvds_funcs },
33700 + { .compatible = "rockchip,rk3568-lvds", .data = &rk3568_lvds_funcs },
33708 diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c
33710 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
33712 @@ -6,29 +6,183 @@
33724 -#include <drm/drm_bridge.h>
33730 -#include <drm/drm_simple_kms_helper.h>
33737 -#define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder)
33783 - struct drm_device *drm_dev;
33788 - int output_mode;
33819 + struct rockchip_drm_private *private = connector->dev->dev_private;
33821 + if (property == private->connector_id_prop) {
33822 + *val = rgb->id;
33827 + return -EINVAL;
33843 + struct drm_panel *panel = rgb->panel;
33853 + return &rgb->encoder;
33866 + pinctrl_pm_select_default_state(rgb->dev);
33868 + if (rgb->funcs && rgb->funcs->enable)
33869 + rgb->funcs->enable(rgb);
33871 + if (rgb->phy)
33872 + phy_power_on(rgb->phy);
33874 + if (rgb->panel) {
33875 + drm_panel_prepare(rgb->panel);
33876 + drm_panel_enable(rgb->panel);
33884 + if (rgb->panel) {
33885 + drm_panel_disable(rgb->panel);
33886 + drm_panel_unprepare(rgb->panel);
33889 + if (rgb->phy)
33890 + phy_power_off(rgb->phy);
33892 + if (rgb->funcs && rgb->funcs->disable)
33893 + rgb->funcs->disable(rgb);
33895 + pinctrl_pm_select_sleep_state(rgb->dev);
33901 @@ -37,128 +191,369 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder,
33903 struct drm_connector *connector = conn_state->connector;
33904 struct drm_display_info *info = &connector->display_info;
33905 - u32 bus_format;
33907 if (info->num_bus_formats)
33908 - bus_format = info->bus_formats[0];
33909 + s->bus_format = info->bus_formats[0];
33911 - bus_format = MEDIA_BUS_FMT_RGB888_1X24;
33912 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
33914 - switch (bus_format) {
33915 + switch (s->bus_format) {
33917 s->output_mode = ROCKCHIP_OUT_MODE_P666;
33918 + s->output_if = VOP_OUTPUT_IF_RGB;
33921 s->output_mode = ROCKCHIP_OUT_MODE_P565;
33922 + s->output_if = VOP_OUTPUT_IF_RGB;
33925 + s->output_mode = ROCKCHIP_OUT_MODE_S888;
33926 + s->output_if = VOP_OUTPUT_IF_RGB;
33929 + s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY;
33930 + s->output_if = VOP_OUTPUT_IF_RGB;
33936 + s->output_mode = ROCKCHIP_OUT_MODE_BT656;
33937 + s->output_if = VOP_OUTPUT_IF_BT656;
33943 + s->output_mode = ROCKCHIP_OUT_MODE_BT1120;
33944 + s->output_if = VOP_OUTPUT_IF_BT1120;
33949 s->output_mode = ROCKCHIP_OUT_MODE_P888;
33950 + s->output_if = VOP_OUTPUT_IF_RGB;
33954 - s->output_type = DRM_MODE_CONNECTOR_LVDS;
33955 + s->output_type = DRM_MODE_CONNECTOR_DPI;
33956 + s->bus_flags = info->bus_flags;
33957 + s->tv_state = &conn_state->tv;
33958 + s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
33959 + s->color_space = V4L2_COLORSPACE_DEFAULT;
33969 + if (rgb->panel)
33970 + panel_simple_loader_protect(rgb->panel);
33978 + u32 request_clock = mode->clock;
33979 + u32 max_clock = rgb->max_dclk_rate;
33981 + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
34007 + struct drm_encoder *encoder = &rgb->encoder;
34011 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
34012 + &rgb->panel, &rgb->bridge);
34018 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
34019 + dev->of_node);
34030 + if (rgb->panel) {
34031 + struct rockchip_drm_private *private = drm_dev->dev_private;
34033 + connector = &rgb->connector;
34034 + connector->interlace_allowed = true;
34054 + rgb->sub_dev.connector = &rgb->connector;
34055 + rgb->sub_dev.of_node = rgb->dev->of_node;
34056 + rgb->sub_dev.loader_protect = rockchip_rgb_encoder_loader_protect;
34057 + drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
34058 + rockchip_drm_register_sub_dev(&rgb->sub_dev);
34060 + rgb->bridge->encoder = encoder;
34061 + ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
34083 + if (rgb->sub_dev.connector)
34084 + rockchip_drm_register_sub_dev(&rgb->sub_dev);
34085 + if (rgb->panel)
34086 + drm_connector_cleanup(&rgb->connector);
34088 + drm_encoder_cleanup(&rgb->encoder);
34096 -struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
34097 - struct drm_crtc *crtc,
34098 - struct drm_device *drm_dev)
34101 + struct device *dev = &pdev->dev;
34103 - struct drm_encoder *encoder;
34104 - struct device_node *port, *endpoint;
34105 - u32 endpoint_id;
34106 - int ret = 0, child_count = 0;
34107 - struct drm_panel *panel;
34108 - struct drm_bridge *bridge;
34112 - rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL);
34113 + rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL);
34115 - return ERR_PTR(-ENOMEM);
34116 + return -ENOMEM;
34118 + id = of_alias_get_id(dev->of_node, "rgb");
34123 + rgb->id = id;
34124 rgb->dev = dev;
34125 - rgb->drm_dev = drm_dev;
34126 -
34127 - port = of_graph_get_port_by_id(dev->of_node, 0);
34128 - if (!port)
34129 - return ERR_PTR(-EINVAL);
34130 -
34131 - for_each_child_of_node(port, endpoint) {
34132 - if (of_property_read_u32(endpoint, "reg", &endpoint_id))
34133 - endpoint_id = 0;
34134 -
34135 - /* if subdriver (> 0) or error case (< 0), ignore entry */
34136 - if (rockchip_drm_endpoint_is_subdriver(endpoint) != 0)
34137 - continue;
34138 -
34139 - child_count++;
34140 - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id,
34141 - &panel, &bridge);
34142 - if (!ret) {
34143 - of_node_put(endpoint);
34144 - break;
34145 + rgb->max_dclk_rate = rgb_data->max_dclk_rate;
34146 + rgb->funcs = rgb_data->funcs;
34149 + rgb->data_sync_bypass =
34150 + of_property_read_bool(dev->of_node, "rockchip,data-sync-bypass");
34152 + if (dev->parent && dev->parent->of_node) {
34153 + rgb->grf = syscon_node_to_regmap(dev->parent->of_node);
34154 + if (IS_ERR(rgb->grf)) {
34155 + ret = PTR_ERR(rgb->grf);
34161 - of_node_put(port);
34162 + rgb->phy = devm_phy_optional_get(dev, "phy");
34163 + if (IS_ERR(rgb->phy)) {
34164 + ret = PTR_ERR(rgb->phy);
34169 - /* if the rgb output is not connected to anything, just return */
34170 - if (!child_count)
34171 - return NULL;
34175 - if (ret < 0) {
34176 - if (ret != -EPROBE_DEFER)
34177 - DRM_DEV_ERROR(dev, "failed to find panel or bridge %d\n", ret);
34178 - return ERR_PTR(ret);
34179 - }
34182 + component_del(&pdev->dev, &rockchip_rgb_component_ops);
34184 - encoder = &rgb->encoder;
34185 - encoder->possible_crtcs = drm_crtc_mask(crtc);
34189 - ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_NONE);
34190 - if (ret < 0) {
34191 - DRM_DEV_ERROR(drm_dev->dev,
34192 - "failed to initialize encoder: %d\n", ret);
34193 - return ERR_PTR(ret);
34194 - }
34197 + int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node,
34198 + &rgb->encoder);
34200 - drm_encoder_helper_add(encoder, &rockchip_rgb_encoder_helper_funcs);
34201 + regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, PX30_RGB_VOP_SEL(pipe) |
34202 + PX30_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
34205 - if (panel) {
34206 - bridge = drm_panel_bridge_add_typed(panel,
34207 - DRM_MODE_CONNECTOR_LVDS);
34208 - if (IS_ERR(bridge))
34209 - return ERR_CAST(bridge);
34210 - }
34215 - rgb->bridge = bridge;
34220 - ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
34221 - if (ret) {
34222 - DRM_DEV_ERROR(drm_dev->dev,
34223 - "failed to attach bridge: %d\n", ret);
34224 - goto err_free_encoder;
34225 - }
34228 + regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
34229 + RK1808_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
34232 - return rgb;
34237 -err_free_encoder:
34238 - drm_encoder_cleanup(encoder);
34239 - return ERR_PTR(ret);
34246 + int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node,
34247 + &rgb->encoder);
34249 + regmap_write(rgb->grf, RK3288_GRF_SOC_CON6, RK3288_LVDS_LCDC_SEL(pipe));
34250 + regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
34255 -EXPORT_SYMBOL_GPL(rockchip_rgb_init);
34257 -void rockchip_rgb_fini(struct rockchip_rgb *rgb)
34260 - drm_panel_bridge_remove(rgb->bridge);
34261 - drm_encoder_cleanup(&rgb->encoder);
34262 + regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
34278 + regmap_write(rgb->grf, RK3568_GRF_VO_CON1,
34279 + RK3568_RGB_DATA_BYPASS(rgb->data_sync_bypass));
34292 + regmap_write(rgb->grf, RV1126_GRF_IOFUNC_CON3,
34293 + RV1126_LCDC_IO_BYPASS(rgb->data_sync_bypass));
34295 -EXPORT_SYMBOL_GPL(rockchip_rgb_fini);
34307 + regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER,
34308 + RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass) ? 0x3 : 0x0);
34309 + regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS,
34310 + RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass) ? 0x3 : 0x0);
34323 + { .compatible = "rockchip,px30-rgb", .data = &px30_rgb },
34324 + { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb },
34325 + { .compatible = "rockchip,rk3066-rgb", },
34326 + { .compatible = "rockchip,rk3128-rgb", },
34327 + { .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb },
34328 + { .compatible = "rockchip,rk3308-rgb", },
34329 + { .compatible = "rockchip,rk3368-rgb", },
34330 + { .compatible = "rockchip,rk3568-rgb", .data = &rk3568_rgb },
34331 + { .compatible = "rockchip,rk3588-rgb", },
34332 + { .compatible = "rockchip,rv1106-rgb", .data = &rv1106_rgb},
34333 + { .compatible = "rockchip,rv1108-rgb", },
34334 + { .compatible = "rockchip,rv1126-rgb", .data = &rv1126_rgb},
34343 + .name = "rockchip-rgb",
34347 diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.h b/drivers/gpu/drm/rockchip/rockchip_rgb.h
34349 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.h
34351 @@ -8,12 +8,14 @@
34355 - struct drm_device *drm_dev);
34362 - struct drm_device *drm_dev)
34368 diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_re…
34370 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
34372 @@ -5,36 +5,36 @@
34376 -#include <linux/mod_devicetable.h>
34377 -#include <linux/module.h>
34383 -#include <drm/drm_plane.h>
34388 -#include "rockchip_drm_drv.h"
34390 -#define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
34391 - { \
34392 - .offset = off, \
34397 - .shift = _shift, \
34400 - .relaxed = _relaxed, \
34401 - }
34406 -#define VOP_REG(off, _mask, _shift) \
34407 - _VOP_REG(off, _mask, _shift, false, true)
34409 + VOP_REG_VER_MASK(off, _mask, s, false, 0, 0, -1)
34411 -#define VOP_REG_SYNC(off, _mask, _shift) \
34412 - _VOP_REG(off, _mask, _shift, false, false)
34414 + VOP_REG_VER_MASK(off, _mask, s, true, 0, 0, -1)
34420 -#define VOP_REG_MASK_SYNC(off, _mask, _shift) \
34421 - _VOP_REG(off, _mask, _shift, true, false)
34425 @@ -50,15 +50,46 @@ static const uint32_t formats_win_full[] = {
34429 -static const uint64_t format_modifiers_win_full[] = {
34430 - DRM_FORMAT_MOD_LINEAR,
34431 - DRM_FORMAT_MOD_INVALID,
34451 -static const uint64_t format_modifiers_win_full_afbc[] = {
34452 - ROCKCHIP_AFBC_MOD,
34453 - DRM_FORMAT_MOD_LINEAR,
34454 - DRM_FORMAT_MOD_INVALID,
34472 + DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode or non-Linear mode */
34473 + DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode or non-Linear mode */
34474 + DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode or non-Linear mode */
34475 + DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode or non-Linear mode */
34479 @@ -72,524 +103,571 @@ static const uint32_t formats_win_lite[] = {
34483 -static const uint64_t format_modifiers_win_lite[] = {
34489 -static const struct vop_scl_regs rk3036_win_scl = {
34490 - .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
34491 - .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
34492 - .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
34493 - .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
34533 -static const struct vop_win_phy rk3036_win0_data = {
34534 - .scl = &rk3036_win_scl,
34535 - .data_formats = formats_win_full,
34536 - .nformats = ARRAY_SIZE(formats_win_full),
34537 - .format_modifiers = format_modifiers_win_full,
34538 - .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
34539 - .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
34540 - .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
34541 - .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
34542 - .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
34543 - .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
34544 - .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
34545 - .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
34546 - .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
34547 - .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
34572 -static const struct vop_win_phy rk3036_win1_data = {
34588 + .csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
34590 + .xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1),
34591 + .ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1),
34608 - .format_modifiers = format_modifiers_win_lite,
34609 - .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
34610 - .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
34611 - .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
34612 - .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
34613 - .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
34614 - .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
34615 - .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
34616 - .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
34630 -static const struct vop_win_data rk3036_vop_win_data[] = {
34631 - { .base = 0x00, .phy = &rk3036_win0_data,
34632 - .type = DRM_PLANE_TYPE_PRIMARY },
34633 - { .base = 0x00, .phy = &rk3036_win1_data,
34634 - .type = DRM_PLANE_TYPE_CURSOR },
34643 -static const int rk3036_vop_intrs[] = {
34644 - DSP_HOLD_VALID_INTR,
34645 - FS_INTR,
34646 - LINE_FLAG_INTR,
34647 - BUS_ERROR_INTR,
34656 -static const struct vop_intr rk3036_intr = {
34657 - .intrs = rk3036_vop_intrs,
34658 - .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
34659 - .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
34660 - .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
34661 - .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
34662 - .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
34671 -static const struct vop_modeset rk3036_modeset = {
34672 - .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
34673 - .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
34674 - .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
34675 - .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
34682 -static const struct vop_output rk3036_output = {
34683 - .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
34690 + .reg_done_frm = VOP_REG_VER(RK3288_SYS_CTRL1, 0x1, 24, 3, 5, -1),
34706 + .post_lb_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 18, 3, 2, -1),
34707 + .global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
34708 + .overlay_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 16, 3, 2, -1),
34709 + .core_dclk_div = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 4, 3, 4, -1),
34710 + .p2i_en = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 5, 3, 4, -1),
34711 + .dclk_ddr = VOP_REG_VER(RK3288_DSP_CTRL0, 0x1, 8, 3, 1, -1),
34712 + .dp_en = VOP_REG_VER(RK3399_SYS_CTRL, 0x1, 11, 3, 5, -1),
34719 + .data01_swap = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 17, 3, 5, -1),
34722 + .dp_dclk_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0x1, 19, 3, 5, -1),
34723 + .dp_pin_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0x7, 16, 3, 5, -1),
34724 + .rgb_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 19, 3, 2, -1),
34725 + .rgb_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 16, 3, 2, -1),
34731 + .hdmi_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 23, 3, 2, -1),
34732 + .hdmi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 20, 3, 2, -1),
34733 + .edp_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 27, 3, 2, -1),
34734 + .edp_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 24, 3, 2, -1),
34735 + .mipi_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 31, 3, 2, -1),
34736 + .mipi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 28, 3, 2, -1),
34744 + .dsp_out_yuv = VOP_REG_VER(RK3399_POST_SCL_CTRL, 0x1, 2, 3, 5, -1),
34748 + .update_gamma_lut = VOP_REG_VER(RK3288_DSP_CTRL1, 0x1, 7, 3, 5, -1),
34749 + .lut_buffer_index = VOP_REG_VER(RK3399_DBG_POST_REG1, 0x1, 1, 3, 5, -1),
34753 + .afbdc_rstn = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1, 3, 3, 5, -1),
34754 + .afbdc_en = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1, 0, 3, 5, -1),
34755 + .afbdc_sel = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x3, 1, 3, 5, -1),
34756 + .afbdc_format = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1f, 16, 3, 5, -1),
34758 + 0x1, 21, 3, 5, -1),
34760 + 0, 3, 5, -1),
34762 + 0, 3, 5, -1),
34769 + .bcsh_r2y_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 6, 3, 1, -1),
34770 + .bcsh_r2y_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 4, 3, 1, -1),
34771 + .bcsh_y2r_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x3, 2, 3, 1, -1),
34772 + .bcsh_y2r_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 0, 3, 1, -1),
34784 -static const struct vop_common rk3036_common = {
34785 - .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
34786 - .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
34787 - .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
34788 - .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
34789 - .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
34790 - .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
34791 - .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
34813 -static const struct vop_data rk3036_vop = {
34814 - .intr = &rk3036_intr,
34815 - .common = &rk3036_common,
34816 - .modeset = &rk3036_modeset,
34817 - .output = &rk3036_output,
34818 - .win = rk3036_vop_win_data,
34819 - .win_size = ARRAY_SIZE(rk3036_vop_win_data),
34827 -static const struct vop_win_phy rk3126_win1_data = {
34828 - .data_formats = formats_win_lite,
34829 - .nformats = ARRAY_SIZE(formats_win_lite),
34830 - .format_modifiers = format_modifiers_win_lite,
34831 - .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
34832 - .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
34833 - .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
34834 - .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
34835 - .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
34836 - .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
34837 - .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
34847 -static const struct vop_win_data rk3126_vop_win_data[] = {
34848 - { .base = 0x00, .phy = &rk3036_win0_data,
34849 - .type = DRM_PLANE_TYPE_PRIMARY },
34850 - { .base = 0x00, .phy = &rk3126_win1_data,
34851 - .type = DRM_PLANE_TYPE_CURSOR },
34856 -static const struct vop_data rk3126_vop = {
34857 - .intr = &rk3036_intr,
34858 - .common = &rk3036_common,
34859 - .modeset = &rk3036_modeset,
34860 - .output = &rk3036_output,
34861 - .win = rk3126_vop_win_data,
34862 - .win_size = ARRAY_SIZE(rk3126_vop_win_data),
34895 -static const int px30_vop_intrs[] = {
34898 - 0, 0,
34902 - 0,
34905 - 0, 0,
34916 -static const struct vop_intr px30_intr = {
34917 - .intrs = px30_vop_intrs,
34918 - .nintrs = ARRAY_SIZE(px30_vop_intrs),
34919 - .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
34920 - .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
34921 - .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
34922 - .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
34933 -static const struct vop_common px30_common = {
34934 - .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
34935 - .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
34936 - .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
34937 - .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
34938 - .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
34939 - .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
34940 - .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
34958 -static const struct vop_modeset px30_modeset = {
34959 - .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
34960 - .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
34961 - .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
34962 - .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
34973 -static const struct vop_output px30_output = {
34974 - .rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1),
34975 - .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2),
34976 - .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
34977 - .mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25),
34978 - .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26),
34979 - .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
34990 -static const struct vop_scl_regs px30_win_scl = {
34991 - .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
34992 - .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
34993 - .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
34994 - .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
35005 -static const struct vop_win_phy px30_win0_data = {
35006 - .scl = &px30_win_scl,
35007 - .data_formats = formats_win_full,
35008 - .nformats = ARRAY_SIZE(formats_win_full),
35009 - .format_modifiers = format_modifiers_win_full,
35010 - .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
35011 - .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
35012 - .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
35013 - .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
35014 - .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
35015 - .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
35016 - .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
35017 - .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
35018 - .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
35019 - .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
35020 - .alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2),
35021 - .alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1),
35022 - .alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0),
35023 -};
35024 -
35025 -static const struct vop_win_phy px30_win1_data = {
35026 - .data_formats = formats_win_lite,
35027 - .nformats = ARRAY_SIZE(formats_win_lite),
35028 - .format_modifiers = format_modifiers_win_lite,
35029 - .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
35030 - .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
35031 - .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
35032 - .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
35033 - .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
35034 - .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
35035 - .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
35036 - .alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2),
35037 - .alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1),
35038 - .alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0),
35039 -};
35040 -
35041 -static const struct vop_win_phy px30_win2_data = {
35042 - .data_formats = formats_win_lite,
35043 - .nformats = ARRAY_SIZE(formats_win_lite),
35044 - .format_modifiers = format_modifiers_win_lite,
35045 - .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
35046 - .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
35047 - .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
35048 - .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
35049 - .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
35050 - .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
35051 - .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
35052 - .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
35053 - .alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2),
35054 - .alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1),
35055 - .alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0),
35062 -static const struct vop_win_data px30_vop_big_win_data[] = {
35063 - { .base = 0x00, .phy = &px30_win0_data,
35067 - { .base = 0x00, .phy = &px30_win1_data,
35070 - { .base = 0x00, .phy = &px30_win2_data,
35071 - .type = DRM_PLANE_TYPE_CURSOR },
35082 -static const struct vop_data px30_vop_big = {
35083 - .intr = &px30_intr,
35084 - .feature = VOP_FEATURE_INTERNAL_RGB,
35085 - .common = &px30_common,
35086 - .modeset = &px30_modeset,
35087 - .output = &px30_output,
35088 - .win = px30_vop_big_win_data,
35089 - .win_size = ARRAY_SIZE(px30_vop_big_win_data),
35103 -static const struct vop_win_data px30_vop_lit_win_data[] = {
35104 - { .base = 0x00, .phy = &px30_win1_data,
35105 - .type = DRM_PLANE_TYPE_PRIMARY },
35116 -static const struct vop_data px30_vop_lit = {
35117 - .intr = &px30_intr,
35118 - .feature = VOP_FEATURE_INTERNAL_RGB,
35119 - .common = &px30_common,
35120 - .modeset = &px30_modeset,
35121 - .output = &px30_output,
35122 - .win = px30_vop_lit_win_data,
35123 - .win_size = ARRAY_SIZE(px30_vop_lit_win_data),
35128 -static const struct vop_scl_regs rk3066_win_scl = {
35129 - .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
35130 - .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
35131 - .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
35132 - .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
35147 -static const struct vop_win_phy rk3066_win0_data = {
35148 - .scl = &rk3066_win_scl,
35149 - .data_formats = formats_win_full,
35150 - .nformats = ARRAY_SIZE(formats_win_full),
35151 - .format_modifiers = format_modifiers_win_full,
35152 - .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
35153 - .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4),
35154 - .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19),
35155 - .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
35156 - .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
35157 - .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
35158 - .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
35159 - .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
35160 - .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
35161 - .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
35167 -static const struct vop_win_phy rk3066_win1_data = {
35168 - .data_formats = formats_win_full,
35169 - .nformats = ARRAY_SIZE(formats_win_full),
35170 - .format_modifiers = format_modifiers_win_full,
35171 - .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
35172 - .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7),
35173 - .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23),
35174 - .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
35175 - .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
35176 - .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
35177 - .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
35178 - .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
35179 - .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
35180 - .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
35186 -static const struct vop_win_phy rk3066_win2_data = {
35187 - .data_formats = formats_win_lite,
35188 - .nformats = ARRAY_SIZE(formats_win_lite),
35189 - .format_modifiers = format_modifiers_win_lite,
35190 - .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
35191 - .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10),
35192 - .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27),
35193 - .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
35194 - .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
35195 - .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
35196 - .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
35202 -static const struct vop_modeset rk3066_modeset = {
35203 - .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
35204 - .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
35205 - .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
35206 - .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
35212 -static const struct vop_output rk3066_output = {
35213 - .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
35219 -static const struct vop_common rk3066_common = {
35220 - .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
35221 - .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
35222 - .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
35223 - .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
35224 - .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
35225 - .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
35226 - .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9),
35227 - .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31),
35228 - .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25),
35234 -static const struct vop_win_data rk3066_vop_win_data[] = {
35235 - { .base = 0x00, .phy = &rk3066_win0_data,
35236 - .type = DRM_PLANE_TYPE_PRIMARY },
35237 - { .base = 0x00, .phy = &rk3066_win1_data,
35238 - .type = DRM_PLANE_TYPE_OVERLAY },
35239 - { .base = 0x00, .phy = &rk3066_win2_data,
35240 - .type = DRM_PLANE_TYPE_CURSOR },
35246 -static const int rk3066_vop_intrs[] = {
35247 - /*
35248 - * hs_start interrupt fires at frame-start, so serves
35249 - * the same purpose as dsp_hold in the driver.
35250 - */
35251 - DSP_HOLD_VALID_INTR,
35252 - FS_INTR,
35253 - LINE_FLAG_INTR,
35254 - BUS_ERROR_INTR,
35260 -static const struct vop_intr rk3066_intr = {
35261 - .intrs = rk3066_vop_intrs,
35262 - .nintrs = ARRAY_SIZE(rk3066_vop_intrs),
35263 - .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
35264 - .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
35265 - .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
35266 - .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
35272 -static const struct vop_data rk3066_vop = {
35273 - .version = VOP_VERSION(2, 1),
35274 - .intr = &rk3066_intr,
35275 - .common = &rk3066_common,
35276 - .modeset = &rk3066_modeset,
35277 - .output = &rk3066_output,
35278 - .win = rk3066_vop_win_data,
35279 - .win_size = ARRAY_SIZE(rk3066_vop_win_data),
35285 -static const struct vop_scl_regs rk3188_win_scl = {
35286 - .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
35287 - .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
35288 - .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
35289 - .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
35290 -};
35297 -static const struct vop_win_phy rk3188_win0_data = {
35298 - .scl = &rk3188_win_scl,
35299 - .data_formats = formats_win_full,
35300 - .nformats = ARRAY_SIZE(formats_win_full),
35301 - .format_modifiers = format_modifiers_win_full,
35302 - .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
35303 - .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
35304 - .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
35305 - .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
35306 - .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
35307 - .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
35308 - .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
35309 - .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
35310 - .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
35311 -};
35312 -
35313 -static const struct vop_win_phy rk3188_win1_data = {
35314 - .data_formats = formats_win_lite,
35315 - .nformats = ARRAY_SIZE(formats_win_lite),
35316 - .format_modifiers = format_modifiers_win_lite,
35317 - .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
35318 - .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
35319 - .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
35320 - /* no act_info on window1 */
35321 - .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
35322 - .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
35323 - .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
35324 - .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
35325 -};
35326 -
35327 -static const struct vop_modeset rk3188_modeset = {
35328 - .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
35329 - .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
35330 - .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
35331 - .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
35332 -};
35333 -
35334 -static const struct vop_output rk3188_output = {
35335 - .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
35336 -};
35337 -
35338 -static const struct vop_common rk3188_common = {
35339 - .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
35340 - .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
35341 - .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
35342 - .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
35343 - .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
35344 - .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
35345 - .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
35346 - .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24),
35347 - .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9),
35348 - .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28),
35349 - .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25),
35350 -};
35351 -
35352 -static const struct vop_win_data rk3188_vop_win_data[] = {
35353 - { .base = 0x00, .phy = &rk3188_win0_data,
35354 - .type = DRM_PLANE_TYPE_PRIMARY },
35355 - { .base = 0x00, .phy = &rk3188_win1_data,
35356 - .type = DRM_PLANE_TYPE_CURSOR },
35357 -};
35361 -static const int rk3188_vop_intrs[] = {
35362 - /*
35363 - * hs_start interrupt fires at frame-start, so serves
35364 - * the same purpose as dsp_hold in the driver.
35365 - */
35366 - DSP_HOLD_VALID_INTR,
35367 - FS_INTR,
35368 - LINE_FLAG_INTR,
35369 - BUS_ERROR_INTR,
35377 -static const struct vop_intr rk3188_vop_intr = {
35378 - .intrs = rk3188_vop_intrs,
35379 - .nintrs = ARRAY_SIZE(rk3188_vop_intrs),
35380 - .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
35381 - .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
35382 - .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
35383 - .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
35393 -static const struct vop_data rk3188_vop = {
35394 - .intr = &rk3188_vop_intr,
35395 - .common = &rk3188_common,
35396 - .modeset = &rk3188_modeset,
35397 - .output = &rk3188_output,
35398 - .win = rk3188_vop_win_data,
35399 - .win_size = ARRAY_SIZE(rk3188_vop_win_data),
35400 - .feature = VOP_FEATURE_INTERNAL_RGB,
35410 -static const struct vop_scl_extension rk3288_win_full_scl_ext = {
35411 - .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
35412 - .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
35413 - .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
35414 - .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
35415 - .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
35416 - .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
35417 - .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
35418 - .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
35419 - .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
35420 - .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
35421 - .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
35422 - .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
35423 - .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
35424 - .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
35425 - .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
35426 - .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
35427 - .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
35428 - .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
35429 - .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
35430 - .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
35431 - .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
35439 -static const struct vop_scl_regs rk3288_win_full_scl = {
35440 - .ext = &rk3288_win_full_scl_ext,
35441 - .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
35442 - .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
35443 - .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
35444 - .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
35452 -static const struct vop_win_phy rk3288_win01_data = {
35455 - .data_formats = formats_win_full,
35456 - .nformats = ARRAY_SIZE(formats_win_full),
35457 - .format_modifiers = format_modifiers_win_full,
35464 + .csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
35466 + .xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1),
35467 + .ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1),
35471 @@ -597,476 +675,1318 @@ static const struct vop_win_phy rk3288_win01_data = {
35475 - .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
35476 - .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
35477 - .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
35484 -static const struct vop_win_phy rk3288_win23_data = {
35485 - .data_formats = formats_win_lite,
35486 - .nformats = ARRAY_SIZE(formats_win_lite),
35487 - .format_modifiers = format_modifiers_win_lite,
35488 - .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
35489 - .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
35490 - .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
35491 - .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
35492 - .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
35493 - .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
35494 - .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
35495 - .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
35496 - .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
35497 - .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
35521 -static const struct vop_modeset rk3288_modeset = {
35522 - .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
35523 - .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
35524 - .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
35525 - .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
35526 - .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
35527 - .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
35542 -static const struct vop_output rk3288_output = {
35543 - .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
35544 - .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
35545 - .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
35546 - .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
35547 - .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
35563 -static const struct vop_common rk3288_common = {
35564 - .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
35565 - .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
35566 - .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
35567 - .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
35568 - .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
35569 - .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
35570 - .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
35571 - .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
35572 - .dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0),
35573 - .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
35574 - .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
35575 - .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
35576 - .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
35592 -/*
35593 - * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
35594 - * special support to get alpha blending working. For now, just use overlay
35595 - * window 3 for the drm cursor.
35596 - *
35597 - */
35598 -static const struct vop_win_data rk3288_vop_win_data[] = {
35603 - .type = DRM_PLANE_TYPE_OVERLAY },
35604 - { .base = 0x00, .phy = &rk3288_win23_data,
35605 - .type = DRM_PLANE_TYPE_OVERLAY },
35606 - { .base = 0x50, .phy = &rk3288_win23_data,
35610 -static const int rk3288_vop_intrs[] = {
35611 - DSP_HOLD_VALID_INTR,
35612 - FS_INTR,
35613 - LINE_FLAG_INTR,
35614 - BUS_ERROR_INTR,
35615 -};
35616 -
35617 -static const struct vop_intr rk3288_vop_intr = {
35618 - .intrs = rk3288_vop_intrs,
35619 - .nintrs = ARRAY_SIZE(rk3288_vop_intrs),
35620 - .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
35621 - .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
35622 - .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
35623 - .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
35637 -static const struct vop_data rk3288_vop = {
35638 - .version = VOP_VERSION(3, 1),
35639 - .feature = VOP_FEATURE_OUTPUT_RGB10,
35640 - .intr = &rk3288_vop_intr,
35641 - .common = &rk3288_common,
35642 - .modeset = &rk3288_modeset,
35643 - .output = &rk3288_output,
35644 - .win = rk3288_vop_win_data,
35645 - .win_size = ARRAY_SIZE(rk3288_vop_win_data),
35646 - .lut_size = 1024,
35849 -static const int rk3368_vop_intrs[] = {
35850 - FS_INTR,
35851 - 0, 0,
35852 - LINE_FLAG_INTR,
35855 - BUS_ERROR_INTR,
35856 - 0, 0, 0, 0, 0, 0, 0,
35857 - DSP_HOLD_VALID_INTR,
35994 -static const struct vop_intr rk3368_vop_intr = {
35998 - .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
35999 - .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
36000 - .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
36001 - .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
36002 - .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
36010 -static const struct vop_win_phy rk3368_win01_data = {
36011 - .scl = &rk3288_win_full_scl,
36012 - .data_formats = formats_win_full,
36013 - .nformats = ARRAY_SIZE(formats_win_full),
36014 - .format_modifiers = format_modifiers_win_full,
36015 - .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
36016 - .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
36017 - .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
36018 - .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
36019 - .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
36020 - .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
36021 - .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
36022 - .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
36023 - .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
36024 - .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
36025 - .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
36026 - .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
36027 - .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
36028 - .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
36029 - .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
36036 -static const struct vop_win_phy rk3368_win23_data = {
36037 - .data_formats = formats_win_lite,
36038 - .nformats = ARRAY_SIZE(formats_win_lite),
36039 - .format_modifiers = format_modifiers_win_lite,
36040 - .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
36041 - .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
36042 - .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
36043 - .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
36044 - .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
36045 - .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
36046 - .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
36047 - .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
36048 - .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
36049 - .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
36050 - .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
36057 -static const struct vop_win_data rk3368_vop_win_data[] = {
36058 - { .base = 0x00, .phy = &rk3368_win01_data,
36059 - .type = DRM_PLANE_TYPE_PRIMARY },
36060 - { .base = 0x40, .phy = &rk3368_win01_data,
36061 - .type = DRM_PLANE_TYPE_OVERLAY },
36062 - { .base = 0x00, .phy = &rk3368_win23_data,
36063 - .type = DRM_PLANE_TYPE_OVERLAY },
36064 - { .base = 0x50, .phy = &rk3368_win23_data,
36065 - .type = DRM_PLANE_TYPE_CURSOR },
36072 -static const struct vop_output rk3368_output = {
36073 - .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
36074 - .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
36075 - .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
36076 - .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
36077 - .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
36078 - .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
36079 - .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
36080 - .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
36081 - .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
36082 - .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
36083 - .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
36084 - .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
36097 -static const struct vop_misc rk3368_misc = {
36098 - .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
36114 -static const struct vop_data rk3368_vop = {
36115 - .version = VOP_VERSION(3, 2),
36116 - .intr = &rk3368_vop_intr,
36117 - .common = &rk3288_common,
36118 - .modeset = &rk3288_modeset,
36119 - .output = &rk3368_output,
36120 - .misc = &rk3368_misc,
36121 - .win = rk3368_vop_win_data,
36122 - .win_size = ARRAY_SIZE(rk3368_vop_win_data),
36130 -static const struct vop_intr rk3366_vop_intr = {
36131 - .intrs = rk3368_vop_intrs,
36132 - .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
36133 - .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
36134 - .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
36135 - .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
36136 - .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
36137 - .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
36143 -static const struct vop_data rk3366_vop = {
36144 - .version = VOP_VERSION(3, 4),
36145 - .intr = &rk3366_vop_intr,
36146 - .common = &rk3288_common,
36147 - .modeset = &rk3288_modeset,
36148 - .output = &rk3368_output,
36149 - .misc = &rk3368_misc,
36150 - .win = rk3368_vop_win_data,
36151 - .win_size = ARRAY_SIZE(rk3368_vop_win_data),
36171 -static const struct vop_output rk3399_output = {
36172 - .dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19),
36173 - .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
36174 - .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
36175 - .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
36176 - .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
36177 - .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16),
36178 - .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
36179 - .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
36180 - .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
36181 - .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
36182 - .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
36183 - .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
36184 - .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
36185 - .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
36186 - .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
36187 - .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
36204 -static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
36205 - .y2r_coefficients = {
36206 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
36207 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
36208 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
36209 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
36210 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
36211 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
36212 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
36213 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
36214 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
36215 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
36216 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
36217 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
36218 - },
36242 -static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
36270 -static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
36271 - { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
36272 - .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
36273 - { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
36274 - .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
36275 - { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
36276 - { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
36296 -static const struct vop_win_phy rk3399_win01_data = {
36297 - .scl = &rk3288_win_full_scl,
36302 - .format_modifiers = format_modifiers_win_full_afbc,
36303 - .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
36304 - .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
36305 - .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
36306 - .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
36307 - .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
36308 - .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
36309 - .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
36310 - .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
36311 - .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
36312 - .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
36313 - .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
36314 - .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
36315 - .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
36330 -/*
36331 - * rk3399 vop big windows register layout is same as rk3288, but we
36332 - * have a separate rk3399 win data array here so that we can advertise
36333 - * AFBC on the primary plane.
36334 - */
36335 -static const struct vop_win_data rk3399_vop_win_data[] = {
36336 - { .base = 0x00, .phy = &rk3399_win01_data,
36372 - { .base = 0x40, .phy = &rk3288_win01_data,
36373 - .type = DRM_PLANE_TYPE_OVERLAY },
36374 - { .base = 0x00, .phy = &rk3288_win23_data,
36377 - { .base = 0x50, .phy = &rk3288_win23_data,
36382 -static const struct vop_afbc rk3399_vop_afbc = {
36383 - .rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
36384 - .enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
36385 - .win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
36386 - .format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
36387 - .hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
36388 - .hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
36389 - .pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
36397 -static const struct vop_data rk3399_vop_big = {
36398 - .version = VOP_VERSION(3, 5),
36399 - .feature = VOP_FEATURE_OUTPUT_RGB10,
36400 - .intr = &rk3366_vop_intr,
36401 - .common = &rk3288_common,
36402 - .modeset = &rk3288_modeset,
36403 - .output = &rk3399_output,
36404 - .afbc = &rk3399_vop_afbc,
36405 - .misc = &rk3368_misc,
36406 - .win = rk3399_vop_win_data,
36407 - .win_size = ARRAY_SIZE(rk3399_vop_win_data),
36408 - .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
36418 -static const struct vop_win_data rk3399_vop_lit_win_data[] = {
36419 - { .base = 0x00, .phy = &rk3368_win01_data,
36420 - .type = DRM_PLANE_TYPE_PRIMARY },
36421 - { .base = 0x00, .phy = &rk3368_win23_data,
36422 - .type = DRM_PLANE_TYPE_CURSOR},
36437 -static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
36438 - { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
36439 - .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
36440 - { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
36453 -static const struct vop_data rk3399_vop_lit = {
36454 - .version = VOP_VERSION(3, 6),
36455 - .intr = &rk3366_vop_intr,
36456 - .common = &rk3288_common,
36457 - .modeset = &rk3288_modeset,
36458 - .output = &rk3399_output,
36459 - .misc = &rk3368_misc,
36460 - .win = rk3399_vop_lit_win_data,
36461 - .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
36462 - .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
36478 -static const struct vop_win_data rk3228_vop_win_data[] = {
36479 - { .base = 0x00, .phy = &rk3288_win01_data,
36534 - { .base = 0x40, .phy = &rk3288_win01_data,
36539 -static const struct vop_data rk3228_vop = {
36540 - .version = VOP_VERSION(3, 7),
36541 - .feature = VOP_FEATURE_OUTPUT_RGB10,
36542 - .intr = &rk3366_vop_intr,
36543 - .common = &rk3288_common,
36544 - .modeset = &rk3288_modeset,
36545 - .output = &rk3399_output,
36546 - .misc = &rk3368_misc,
36547 - .win = rk3228_vop_win_data,
36548 - .win_size = ARRAY_SIZE(rk3228_vop_win_data),
36559 -static const struct vop_modeset rk3328_modeset = {
36560 - .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
36561 - .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
36562 - .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
36563 - .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
36564 - .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
36565 - .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
36581 -static const struct vop_output rk3328_output = {
36582 - .rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19),
36583 - .hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23),
36584 - .edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27),
36585 - .mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31),
36586 - .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
36587 - .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
36588 - .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
36589 - .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
36590 - .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16),
36591 - .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20),
36592 - .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24),
36593 - .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28),
36601 -static const struct vop_misc rk3328_misc = {
36602 - .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
36615 -static const struct vop_common rk3328_common = {
36616 - .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
36617 - .dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
36618 - .dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
36619 - .dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
36620 - .pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
36621 - .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
36622 - .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
36623 - .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
36624 - .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
36627 + * so we set the PX30 VOPB win2 base = 0x190 - 0xb0 = 0xe0
36727 -static const struct vop_intr rk3328_vop_intr = {
36728 - .intrs = rk3368_vop_intrs,
36729 - .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
36730 - .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
36731 - .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
36732 - .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
36733 - .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
36734 - .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
36747 -static const struct vop_win_data rk3328_vop_win_data[] = {
36748 - { .base = 0xd0, .phy = &rk3368_win01_data,
36753 - { .base = 0x1d0, .phy = &rk3368_win01_data,
36961 - { .base = 0x2d0, .phy = &rk3368_win01_data,
36962 - .type = DRM_PLANE_TYPE_CURSOR },
37054 -static const struct vop_data rk3328_vop = {
37055 - .version = VOP_VERSION(3, 8),
37056 - .feature = VOP_FEATURE_OUTPUT_RGB10,
37057 - .intr = &rk3328_vop_intr,
37058 - .common = &rk3328_common,
37059 - .modeset = &rk3328_modeset,
37060 - .output = &rk3328_output,
37061 - .misc = &rk3328_misc,
37062 - .win = rk3328_vop_win_data,
37063 - .win_size = ARRAY_SIZE(rk3328_vop_win_data),
37083 { .compatible = "rockchip,rk3036-vop",
37087 + { .compatible = "rockchip,rk3066-vop",
37091 { .compatible = "rockchip,rk3126-vop",
37093 - { .compatible = "rockchip,px30-vop-big",
37094 - .data = &px30_vop_big },
37097 { .compatible = "rockchip,px30-vop-lit",
37099 - { .compatible = "rockchip,rk3066-vop",
37100 - .data = &rk3066_vop },
37101 - { .compatible = "rockchip,rk3188-vop",
37102 - .data = &rk3188_vop },
37103 - { .compatible = "rockchip,rk3288-vop",
37104 - .data = &rk3288_vop },
37105 + { .compatible = "rockchip,px30-vop-big",
37109 + { .compatible = "rockchip,rk3308-vop",
37113 + { .compatible = "rockchip,rv1106-vop",
37117 + { .compatible = "rockchip,rv1126-vop",
37121 + { .compatible = "rockchip,rk3288-vop-big",
37123 + { .compatible = "rockchip,rk3288-vop-lit",
37127 { .compatible = "rockchip,rk3368-vop",
37129 { .compatible = "rockchip,rk3366-vop",
37133 { .compatible = "rockchip,rk3399-vop-big",
37135 { .compatible = "rockchip,rk3399-vop-lit",
37139 { .compatible = "rockchip,rk3228-vop",
37143 { .compatible = "rockchip,rk3328-vop",
37149 diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_re…
37151 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
37153 @@ -113,6 +113,11 @@
37165 @@ -300,6 +305,7 @@
37173 @@ -628,6 +634,7 @@
37181 @@ -798,6 +805,21 @@
37203 @@ -830,6 +852,7 @@
37211 @@ -870,112 +893,6 @@
37215 -/* rk3126 register definition */
37216 -#define RK3126_WIN1_MST 0x4c
37217 -#define RK3126_WIN1_DSP_INFO 0x50
37218 -#define RK3126_WIN1_DSP_ST 0x54
37219 -/* rk3126 register definition end */
37220 -
37221 -/* px30 register definition */
37222 -#define PX30_REG_CFG_DONE 0x00000
37223 -#define PX30_VERSION 0x00004
37224 -#define PX30_DSP_BG 0x00008
37225 -#define PX30_MCU_CTRL 0x0000c
37226 -#define PX30_SYS_CTRL0 0x00010
37227 -#define PX30_SYS_CTRL1 0x00014
37228 -#define PX30_SYS_CTRL2 0x00018
37229 -#define PX30_DSP_CTRL0 0x00020
37230 -#define PX30_DSP_CTRL2 0x00028
37231 -#define PX30_VOP_STATUS 0x0002c
37232 -#define PX30_LINE_FLAG 0x00030
37233 -#define PX30_INTR_EN 0x00034
37234 -#define PX30_INTR_CLEAR 0x00038
37235 -#define PX30_INTR_STATUS 0x0003c
37236 -#define PX30_WIN0_CTRL0 0x00050
37237 -#define PX30_WIN0_CTRL1 0x00054
37238 -#define PX30_WIN0_COLOR_KEY 0x00058
37239 -#define PX30_WIN0_VIR 0x0005c
37240 -#define PX30_WIN0_YRGB_MST0 0x00060
37241 -#define PX30_WIN0_CBR_MST0 0x00064
37242 -#define PX30_WIN0_ACT_INFO 0x00068
37243 -#define PX30_WIN0_DSP_INFO 0x0006c
37244 -#define PX30_WIN0_DSP_ST 0x00070
37245 -#define PX30_WIN0_SCL_FACTOR_YRGB 0x00074
37246 -#define PX30_WIN0_SCL_FACTOR_CBR 0x00078
37247 -#define PX30_WIN0_SCL_OFFSET 0x0007c
37248 -#define PX30_WIN0_ALPHA_CTRL 0x00080
37249 -#define PX30_WIN1_CTRL0 0x00090
37250 -#define PX30_WIN1_CTRL1 0x00094
37251 -#define PX30_WIN1_VIR 0x00098
37252 -#define PX30_WIN1_MST 0x000a0
37253 -#define PX30_WIN1_DSP_INFO 0x000a4
37254 -#define PX30_WIN1_DSP_ST 0x000a8
37255 -#define PX30_WIN1_COLOR_KEY 0x000ac
37256 -#define PX30_WIN1_ALPHA_CTRL 0x000bc
37257 -#define PX30_HWC_CTRL0 0x000e0
37258 -#define PX30_HWC_CTRL1 0x000e4
37259 -#define PX30_HWC_MST 0x000e8
37260 -#define PX30_HWC_DSP_ST 0x000ec
37261 -#define PX30_HWC_ALPHA_CTRL 0x000f0
37262 -#define PX30_DSP_HTOTAL_HS_END 0x00100
37263 -#define PX30_DSP_HACT_ST_END 0x00104
37264 -#define PX30_DSP_VTOTAL_VS_END 0x00108
37265 -#define PX30_DSP_VACT_ST_END 0x0010c
37266 -#define PX30_DSP_VS_ST_END_F1 0x00110
37267 -#define PX30_DSP_VACT_ST_END_F1 0x00114
37268 -#define PX30_BCSH_CTRL 0x00160
37269 -#define PX30_BCSH_COL_BAR 0x00164
37270 -#define PX30_BCSH_BCS 0x00168
37271 -#define PX30_BCSH_H 0x0016c
37272 -#define PX30_FRC_LOWER01_0 0x00170
37273 -#define PX30_FRC_LOWER01_1 0x00174
37274 -#define PX30_FRC_LOWER10_0 0x00178
37275 -#define PX30_FRC_LOWER10_1 0x0017c
37276 -#define PX30_FRC_LOWER11_0 0x00180
37277 -#define PX30_FRC_LOWER11_1 0x00184
37278 -#define PX30_MCU_RW_BYPASS_PORT 0x0018c
37279 -#define PX30_WIN2_CTRL0 0x00190
37280 -#define PX30_WIN2_CTRL1 0x00194
37281 -#define PX30_WIN2_VIR0_1 0x00198
37282 -#define PX30_WIN2_VIR2_3 0x0019c
37283 -#define PX30_WIN2_MST0 0x001a0
37284 -#define PX30_WIN2_DSP_INFO0 0x001a4
37285 -#define PX30_WIN2_DSP_ST0 0x001a8
37286 -#define PX30_WIN2_COLOR_KEY 0x001ac
37287 -#define PX30_WIN2_ALPHA_CTRL 0x001bc
37288 -#define PX30_BLANKING_VALUE 0x001f4
37289 -#define PX30_FLAG_REG_FRM_VALID 0x001f8
37290 -#define PX30_FLAG_REG 0x001fc
37291 -#define PX30_HWC_LUT_ADDR 0x00600
37292 -#define PX30_GAMMA_LUT_ADDR 0x00a00
37293 -/* px30 register definition end */
37294 -
37295 -/* rk3188 register definition */
37296 -#define RK3188_SYS_CTRL 0x00
37297 -#define RK3188_DSP_CTRL0 0x04
37298 -#define RK3188_DSP_CTRL1 0x08
37299 -#define RK3188_INT_STATUS 0x10
37300 -#define RK3188_WIN0_YRGB_MST0 0x20
37301 -#define RK3188_WIN0_CBR_MST0 0x24
37302 -#define RK3188_WIN0_YRGB_MST1 0x28
37303 -#define RK3188_WIN0_CBR_MST1 0x2c
37304 -#define RK3188_WIN_VIR 0x30
37305 -#define RK3188_WIN0_ACT_INFO 0x34
37306 -#define RK3188_WIN0_DSP_INFO 0x38
37307 -#define RK3188_WIN0_DSP_ST 0x3c
37308 -#define RK3188_WIN0_SCL_FACTOR_YRGB 0x40
37309 -#define RK3188_WIN0_SCL_FACTOR_CBR 0x44
37310 -#define RK3188_WIN1_MST 0x4c
37311 -#define RK3188_WIN1_DSP_INFO 0x50
37312 -#define RK3188_WIN1_DSP_ST 0x54
37313 -#define RK3188_DSP_HTOTAL_HS_END 0x6c
37314 -#define RK3188_DSP_HACT_ST_END 0x70
37315 -#define RK3188_DSP_VTOTAL_VS_END 0x74
37316 -#define RK3188_DSP_VACT_ST_END 0x78
37317 -#define RK3188_REG_CFG_DONE 0x90
37318 -/* rk3188 register definition end */
37319 -
37320 -/* rk3066 register definition */
37324 @@ -1026,6 +943,693 @@
37328 -/* rk3066 register definition end */
38019 diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
38021 --- a/drivers/i2c/busses/i2c-rk3x.c
38022 +++ b/drivers/i2c/busses/i2c-rk3x.c
38023 @@ -23,6 +23,8 @@
38032 @@ -35,6 +37,7 @@
38040 @@ -62,6 +65,15 @@ enum {
38056 @@ -73,7 +85,14 @@ enum {
38060 -#define REG_INT_ALL 0x7f
38072 @@ -152,7 +171,6 @@ struct rk3x_i2c_calced_timings {
38076 - STATE_START,
38080 @@ -189,6 +207,8 @@ struct rk3x_i2c_soc_data {
38089 @@ -200,6 +220,7 @@ struct rk3x_i2c {
38097 @@ -219,8 +240,21 @@ struct rk3x_i2c {
38112 + if (!i2c->system_restarting)
38113 + wake_up(&i2c->wait);
38119 @@ -238,14 +272,75 @@ static inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c)
38139 + if (!i2c->autostop_supported)
38142 + if (!(i2c->msg->flags & I2C_M_IGNORE_NAK))
38145 + if (!i2c->is_last_msg)
38148 + len = i2c->msg->len - i2c->processed;
38153 + i2c->state = STATE_STOP;
38178 - i2c_writel(i2c, REG_INT_START, REG_IEN);
38180 + if (i2c->mode == REG_CON_MOD_TX) {
38183 + i2c->state = STATE_WRITE;
38190 + i2c->state = STATE_READ;
38195 val |= REG_CON_EN | REG_CON_MOD(i2c->mode) | REG_CON_START;
38196 @@ -255,6 +350,12 @@ static void rk3x_i2c_start(struct rk3x_i2c *i2c)
38202 + if (i2c->mode == REG_CON_MOD_TX)
38209 @@ -278,6 +379,7 @@ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error)
38217 @@ -293,7 +395,7 @@ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error)
38221 - wake_up(&i2c->wait);
38226 @@ -322,6 +424,8 @@ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
38227 if (i2c->processed != 0) {
38235 @@ -331,7 +435,7 @@ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
38237 * Fill the transmit buffer with data from i2c->msg
38239 -static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c)
38244 @@ -359,40 +463,15 @@ static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c)
38248 - i2c_writel(i2c, cnt, REG_MTXCNT);
38258 -static void rk3x_i2c_handle_start(struct rk3x_i2c *i2c, unsigned int ipd)
38259 -{
38260 - if (!(ipd & REG_INT_START)) {
38261 - rk3x_i2c_stop(i2c, -EIO);
38262 - dev_warn(i2c->dev, "unexpected irq in START: 0x%x\n", ipd);
38263 - rk3x_i2c_clean_ipd(i2c);
38264 - return;
38265 - }
38266 -
38267 - /* ack interrupt */
38268 - i2c_writel(i2c, REG_INT_START, REG_IPD);
38269 -
38270 - /* disable start bit */
38271 - i2c_writel(i2c, i2c_readl(i2c, REG_CON) & ~REG_CON_START, REG_CON);
38272 -
38273 - /* enable appropriate interrupts and transition */
38274 - if (i2c->mode == REG_CON_MOD_TX) {
38275 - i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN);
38276 - i2c->state = STATE_WRITE;
38277 - rk3x_i2c_fill_transmit_buf(i2c);
38278 - } else {
38279 - /* in any other case, we are going to be reading. */
38280 - i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN);
38281 - i2c->state = STATE_READ;
38282 - rk3x_i2c_prepare_read(i2c);
38283 - }
38284 -}
38285 -
38289 @@ -405,27 +484,21 @@ static void rk3x_i2c_handle_write(struct rk3x_i2c *i2c, unsigned int ipd)
38295 if (i2c->processed == i2c->msg->len)
38296 rk3x_i2c_stop(i2c, i2c->error);
38298 - rk3x_i2c_fill_transmit_buf(i2c);
38302 -static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
38306 unsigned int len = i2c->msg->len - i2c->processed;
38310 - /* we only care for MBRF here. */
38311 - if (!(ipd & REG_INT_MBRF))
38312 - return;
38313 -
38314 - /* ack interrupt (read also produces a spurious START flag, clear it too) */
38315 - i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD);
38316 -
38320 @@ -438,7 +511,21 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
38322 i2c->msg->buf[i2c->processed++] = byte;
38340 if (i2c->processed == i2c->msg->len)
38341 rk3x_i2c_stop(i2c, i2c->error);
38342 @@ -457,19 +544,31 @@ static void rk3x_i2c_handle_stop(struct rk3x_i2c *i2c, unsigned int ipd)
38346 + if (i2c->autostop_supported && !i2c->error) {
38347 + if (i2c->mode != REG_CON_MOD_TX && i2c->msg) {
38348 + if ((i2c->msg->len - i2c->processed) > 0)
38352 + i2c->processed = 0;
38353 + i2c->msg = NULL;
38362 + if (i2c->autostop_supported)
38366 i2c->busy = false;
38367 i2c->state = STATE_IDLE;
38370 - wake_up(&i2c->wait);
38375 @@ -481,7 +580,9 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
38378 if (i2c->state == STATE_IDLE) {
38379 - dev_warn(i2c->dev, "irq in STATE_IDLE, ipd = 0x%x\n", ipd);
38380 + dev_warn_ratelimited(i2c->dev,
38386 @@ -501,8 +602,15 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
38390 - if (!(i2c->msg->flags & I2C_M_IGNORE_NAK))
38391 - rk3x_i2c_stop(i2c, -ENXIO);
38392 + if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
38393 + if (i2c->autostop_supported) {
38394 + i2c->error = -ENXIO;
38395 + i2c->state = STATE_STOP;
38397 + rk3x_i2c_stop(i2c, -ENXIO);
38404 @@ -510,9 +618,6 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
38407 switch (i2c->state) {
38408 - case STATE_START:
38409 - rk3x_i2c_handle_start(i2c, ipd);
38410 - break;
38414 @@ -1032,11 +1137,12 @@ static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int n…
38416 i2c->addr = msgs[0].addr;
38417 i2c->busy = true;
38418 - i2c->state = STATE_START;
38419 i2c->processed = 0;
38420 i2c->error = 0;
38423 + if (i2c->autostop_supported)
38428 @@ -1063,6 +1169,9 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38432 + if (i2c->suspended)
38433 + return -EACCES;
38435 spin_lock_irqsave(&i2c->lock, flags);
38437 clk_enable(i2c->clk);
38438 @@ -1085,10 +1194,10 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38440 i2c->is_last_msg = true;
38442 - spin_unlock_irqrestore(&i2c->lock, flags);
38443 -
38446 + spin_unlock_irqrestore(&i2c->lock, flags);
38449 timeout = wait_event_timeout(i2c->wait, !i2c->busy,
38451 @@ -1103,7 +1212,7 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38452 i2c_readl(i2c, REG_IPD), i2c->state);
38455 - i2c_writel(i2c, 0, REG_IEN);
38460 @@ -1120,6 +1229,9 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38467 clk_disable(i2c->pclk);
38468 clk_disable(i2c->clk);
38470 @@ -1140,12 +1252,81 @@ static int rk3x_i2c_xfer_polling(struct i2c_adapter *adap,
38474 -static __maybe_unused int rk3x_i2c_resume(struct device *dev)
38483 + if (i2c->state != STATE_IDLE) {
38484 + i2c->system_restarting = true;
38486 + while (tmo-- && i2c->busy) {
38493 + dev_err(i2c->dev, "restart timeout, ipd: 0x%02x, state: %d\n",
38494 + i2c_readl(i2c, REG_IPD), i2c->state);
38503 + i2c->state = STATE_IDLE;
38513 + clk_enable(i2c->pclk);
38515 + clk_disable(i2c->pclk);
38528 + * is trying to use I2C bus - this may cause i2c timeout.
38530 + * So forbid access to I2C device using i2c->suspended flag.
38532 + i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38533 + i2c->suspended = 1;
38534 + i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38543 rk3x_i2c_adapt_div(i2c, clk_get_rate(i2c->clk));
38546 + i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38547 + i2c->suspended = 0;
38548 + i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38553 @@ -1161,7 +1342,12 @@ static const struct i2c_algorithm rk3x_i2c_algorithm = {
38557 - .grf_offset = -1,
38567 @@ -1195,6 +1381,10 @@ static const struct of_device_id rk3x_i2c_match[] = {
38568 .compatible = "rockchip,rv1108-i2c",
38572 + .compatible = "rockchip,rv1126-i2c",
38576 .compatible = "rockchip,rk3066-i2c",
38578 @@ -1225,7 +1415,6 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38582 - int bus_nr;
38586 @@ -1253,13 +1442,18 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38587 spin_lock_init(&i2c->lock);
38588 init_waitqueue_head(&i2c->wait);
38590 + i2c->i2c_restart_nb.notifier_call = rk3x_i2c_restart_notify;
38591 + i2c->i2c_restart_nb.priority = 128;
38592 + ret = register_pre_restart_handler(&i2c->i2c_restart_nb);
38594 + dev_err(&pdev->dev, "failed to setup i2c restart handler.\n");
38598 i2c->regs = devm_platform_ioremap_resource(pdev, 0);
38599 if (IS_ERR(i2c->regs))
38600 return PTR_ERR(i2c->regs);
38602 - /* Try to set the I2C adapter number from dt */
38603 - bus_nr = of_alias_get_id(np, "i2c");
38604 -
38608 @@ -1268,24 +1462,34 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38612 - if (IS_ERR(grf)) {
38613 - dev_err(&pdev->dev,
38614 - "rk3x-i2c needs 'rockchip,grf' property\n");
38615 - return PTR_ERR(grf);
38616 - }
38617 -
38618 - if (bus_nr < 0) {
38619 - dev_err(&pdev->dev, "rk3x-i2c needs i2cX alias");
38620 - return -EINVAL;
38621 - }
38622 -
38623 - /* 27+i: write mask, 11+i: value */
38624 - value = BIT(27 + bus_nr) | BIT(11 + bus_nr);
38625 -
38626 - ret = regmap_write(grf, i2c->soc_data->grf_offset, value);
38627 - if (ret != 0) {
38628 - dev_err(i2c->dev, "Could not write to GRF: %d\n", ret);
38629 - return ret;
38636 + dev_err(&pdev->dev, "rk3x-i2c needs i2cX alias");
38637 + return -EINVAL;
38640 + if (i2c->soc_data == &rv1108_soc_data && bus_nr == 2)
38641 + /* rv1108 i2c2 set grf offset-0x408, bit-10 */
38643 + else if (i2c->soc_data == &rv1126_soc_data &&
38645 + /* rv1126 i2c2 set pmugrf offset-0x118, bit-4 */
38651 + ret = regmap_write(grf, i2c->soc_data->grf_offset,
38654 + dev_err(i2c->dev, "Could not write to GRF: %d\n",
38661 @@ -1341,6 +1545,9 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38662 clk_rate = clk_get_rate(i2c->clk);
38666 + i2c->autostop_supported = true;
38668 ret = i2c_add_adapter(&i2c->adap);
38671 @@ -1363,13 +1570,17 @@ static int rk3x_i2c_remove(struct platform_device *pdev)
38672 i2c_del_adapter(&i2c->adap);
38674 clk_notifier_unregister(i2c->clk, &i2c->clk_rate_nb);
38675 + unregister_pre_restart_handler(&i2c->i2c_restart_nb);
38676 clk_unprepare(i2c->pclk);
38677 clk_unprepare(i2c->clk);
38682 -static SIMPLE_DEV_PM_OPS(rk3x_i2c_pm_ops, NULL, rk3x_i2c_resume);
38690 @@ -1381,7 +1592,21 @@ static struct platform_driver rk3x_i2c_driver = {
38712 diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
38714 --- a/drivers/i2c/i2c-core-base.c
38715 +++ b/drivers/i2c/i2c-core-base.c
38716 @@ -61,6 +61,7 @@
38724 @@ -808,7 +809,8 @@ static void i2c_adapter_unlock_bus(struct i2c_adapter *adapter,
38728 - struct i2c_board_info const *info)
38732 struct acpi_device *adev = ACPI_COMPANION(&client->dev);
38734 @@ -822,8 +824,12 @@ static void i2c_dev_set_name(struct i2c_adapter *adap,
38738 - dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
38739 - i2c_encode_flags_to_addr(client));
38741 + dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
38744 + dev_set_name(&client->dev, "%d-%04x-%01x", i2c_adapter_id(adap),
38749 @@ -899,9 +905,11 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *i…
38753 - status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client));
38756 - goto out_err;
38757 + dev_err(&adap->dev,
38759 + status, client->addr);
38761 client->dev.parent = &client->adapter->dev;
38762 client->dev.bus = &i2c_bus_type;
38763 @@ -909,7 +917,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
38764 client->dev.of_node = of_node_get(info->of_node);
38765 client->dev.fwnode = info->fwnode;
38767 - i2c_dev_set_name(adap, client, info);
38770 if (info->properties) {
38771 status = device_add_properties(&client->dev, info->properties);
38772 @@ -935,10 +943,6 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *i…
38773 device_remove_properties(&client->dev);
38775 of_node_put(info->of_node);
38776 -out_err:
38777 - dev_err(&adap->dev,
38778 - "Failed to register i2c client %s at 0x%02x (%d)\n",
38779 - client->name, client->addr, status);
38783 @@ -1838,6 +1842,33 @@ EXPORT_SYMBOL(i2c_del_driver);
38785 /* ------------------------------------------------------------------------- */
38796 + int addr = addrinfo->addr;
38798 + if (client && client->addr == addr)
38799 + addrinfo->cnt++;
38810 + device_for_each_child(&adapter->dev, &addrinfo, __i2c_check_addr_ex);
38817 diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
38819 --- a/drivers/iio/adc/Kconfig
38821 @@ -876,6 +876,13 @@ config ROCKCHIP_SARADC
38835 diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
38837 --- a/drivers/iio/adc/rockchip_saradc.c
38839 @@ -35,7 +35,7 @@
38843 -#define SARADC_MAX_CHANNELS 6
38848 @@ -49,10 +49,17 @@ struct rockchip_saradc {
38866 @@ -90,6 +97,10 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
38871 + if (info->test)
38876 mutex_lock(&indio_dev->mlock);
38877 @@ -105,13 +116,11 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
38878 mutex_unlock(&indio_dev->mlock);
38881 - ret = regulator_get_voltage(info->vref);
38882 - if (ret < 0) {
38883 - dev_err(&indio_dev->dev, "failed to get voltage\n");
38884 - return ret;
38885 - }
38887 + if (info->uv_vref < 0)
38888 + return info->uv_vref;
38890 - *val = ret / 1000;
38891 + *val = info->uv_vref / 1000;
38892 *val2 = chan->scan_type.realbits;
38895 @@ -122,6 +131,9 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
38904 info->last_val = readl_relaxed(info->regs + SARADC_DATA);
38905 @@ -130,7 +142,14 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id)
38908 complete(&info->completion);
38909 -
38911 + spin_lock_irqsave(&info->lock, flags);
38912 + if (info->test) {
38913 + pr_info("chn[%d] val = %d\n", info->chn, info->last_val);
38914 + mod_timer(&info->timer, jiffies + HZ/1000);
38916 + spin_unlock_irqrestore(&info->lock, flags);
38921 @@ -192,6 +211,23 @@ static const struct rockchip_saradc_data rk3399_saradc_data = {
38945 @@ -202,6 +238,9 @@ static const struct of_device_id rockchip_saradc_match[] = {
38947 .compatible = "rockchip,rk3399-saradc",
38950 + .compatible = "rockchip,rk3568-saradc",
38955 @@ -278,6 +317,72 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
38965 + writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
38968 + writel(SARADC_CTRL_POWER_CTRL | (info->chn & SARADC_CTRL_CHN_MASK) |
38969 + SARADC_CTRL_IRQ_ENABLE, info->regs + SARADC_CTRL);
38986 + spin_lock_irqsave(&info->lock, flags);
38988 + if (val > SARADC_CTRL_CHN_MASK && info->test) {
38989 + info->test = false;
38990 + del_timer_sync(&info->timer);
38991 + spin_unlock_irqrestore(&info->lock, flags);
38995 + if (!info->test && val < SARADC_CTRL_CHN_MASK) {
38996 + info->test = true;
38997 + info->chn = val;
38998 + mod_timer(&info->timer, jiffies + HZ/1000);
39001 + spin_unlock_irqrestore(&info->lock, flags);
39021 + sysfs_remove_group(&pdev->dev.kobj, &rockchip_saradc_attr_group);
39028 @@ -390,6 +495,13 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
39032 + info->uv_vref = regulator_get_voltage(info->vref);
39033 + if (info->uv_vref < 0) {
39034 + dev_err(&pdev->dev, "failed to get voltage\n");
39035 + ret = info->uv_vref;
39039 ret = clk_prepare_enable(info->pclk);
39041 dev_err(&pdev->dev, "failed to enable pclk\n");
39042 @@ -430,6 +542,21 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
39047 + spin_lock_init(&info->lock);
39048 + timer_setup(&info->timer, rockchip_saradc_timer, 0);
39049 + ret = sysfs_create_group(&pdev->dev.kobj, &rockchip_saradc_attr_group);
39053 + ret = devm_add_action_or_reset(&pdev->dev,
39056 + dev_err(&pdev->dev, "failed to register devm action, %d\n",
39061 return devm_iio_device_register(&pdev->dev, indio_dev);
39064 diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
39066 --- a/drivers/input/Kconfig
39068 @@ -197,6 +197,8 @@ source "drivers/input/tablet/Kconfig"
39077 diff --git a/drivers/input/Makefile b/drivers/input/Makefile
39079 --- a/drivers/input/Makefile
39081 @@ -24,6 +24,7 @@ obj-$(CONFIG_INPUT_MOUSE) += mouse/
39082 obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
39083 obj-$(CONFIG_INPUT_TABLET) += tablet/
39084 obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
39085 +obj-$(CONFIG_ROCKCHIP_REMOTECTL)+= remotectl/
39086 obj-$(CONFIG_INPUT_MISC) += misc/
39088 obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
39089 diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
39091 --- a/drivers/input/touchscreen/Kconfig
39093 @@ -404,6 +404,15 @@ config TOUCHSCREEN_GOODIX
39102 + on Rockchip platform, and your board-specific initialization
39109 diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
39111 --- a/drivers/input/touchscreen/Makefile
39113 @@ -45,6 +45,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
39114 obj-$(CONFIG_TOUCHSCREEN_EXC3000) += exc3000.o
39115 obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
39116 obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
39117 +obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/
39118 obj-$(CONFIG_TOUCHSCREEN_HIDEEP) += hideep.o
39119 obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
39120 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o
39121 diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
39123 --- a/drivers/iommu/Kconfig
39125 @@ -160,7 +160,8 @@ config OMAP_IOMMU_DEBUG
39129 - bool "Rockchip IOMMU Support"
39135 diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
39137 --- a/drivers/iommu/dma-iommu.c
39138 +++ b/drivers/iommu/dma-iommu.c
39139 @@ -372,6 +372,52 @@ static int iommu_dma_deferred_attach(struct device *dev,
39144 + * Should be called prior to using dma-apis
39155 + if (!domain || !domain->iova_cookie)
39156 + return -EINVAL;
39158 + cookie = domain->iova_cookie;
39159 + iovad = &cookie->iovad;
39163 + pfn_hi = iova_pfn(iovad, base + size - 1);
39165 + return -EINVAL;
39172 + * Should be called prior to using dma-apis.
39180 + if (!domain || !domain->iova_cookie)
39181 + return -EINVAL;
39183 + iovad = &((struct iommu_dma_cookie *)domain->iova_cookie)->iovad;
39184 + iovad->best_fit = true;
39190 * dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API
39192 @@ -388,6 +434,10 @@ static int dma_info_to_prot(enum dma_data_direction dir, bool coherent,
39203 diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
39205 --- a/drivers/iommu/iommu.c
39207 @@ -8,6 +8,7 @@
39215 @@ -2198,7 +2199,8 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
39218 mutex_lock(&group->mutex);
39219 - if (iommu_group_device_count(group) != 1) {
39225 @@ -2332,38 +2334,85 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
39229 -static size_t iommu_pgsize(struct iommu_domain *domain,
39230 - unsigned long addr_merge, size_t size)
39234 - unsigned int pgsize_idx;
39235 - size_t pgsize;
39241 - /* Max page size that still fits into 'size' */
39242 - pgsize_idx = __fls(size);
39244 + pgsizes = domain->pgsize_bitmap & GENMASK(__fls(size), 0);
39246 - /* need to consider alignment requirements ? */
39247 - if (likely(addr_merge)) {
39248 - /* Max page size allowed by address */
39249 - unsigned int align_pgsize_idx = __ffs(addr_merge);
39250 - pgsize_idx = min(pgsize_idx, align_pgsize_idx);
39251 - }
39267 + pgsizes = domain->pgsize_bitmap & ~GENMASK(pgsize_idx, 0);
39271 - /* build a mask of acceptable page sizes */
39272 - pgsize = (1UL << (pgsize_idx + 1)) - 1;
39276 - /* throw away page sizes not supported by the hardware */
39277 - pgsize &= domain->pgsize_bitmap;
39282 + if ((iova ^ paddr) & (pgsize_next - 1))
39285 - /* make sure we're still sane */
39286 - BUG_ON(!pgsize);
39288 + offset = pgsize_next - (addr_merge & (pgsize_next - 1));
39290 - /* pick the biggest page */
39291 - pgsize_idx = __fls(pgsize);
39292 - pgsize = 1UL << pgsize_idx;
39309 + const struct iommu_ops *ops = domain->ops;
39318 + if (ops->map_pages) {
39319 + ret = ops->map_pages(domain, iova, paddr, pgsize, count, prot,
39322 + ret = ops->map(domain, iova, paddr, pgsize, prot, gfp);
39332 @@ -2374,7 +2423,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova,
39336 - if (unlikely(ops->map == NULL ||
39337 + if (unlikely(!(ops->map || ops->map_pages) ||
39338 domain->pgsize_bitmap == 0UL))
39339 return -ENODEV;
39341 @@ -2398,18 +2447,21 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova,
39345 - size_t pgsize = iommu_pgsize(domain, iova | paddr, size);
39348 - pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n",
39349 - iova, &paddr, pgsize);
39350 - ret = ops->map(domain, iova, paddr, pgsize, prot, gfp);
39357 + size -= mapped;
39362 - iova += pgsize;
39363 - paddr += pgsize;
39364 - size -= pgsize;
39370 @@ -2429,7 +2481,7 @@ static int _iommu_map(struct iommu_domain *domain, unsigned long iova,
39373 if (ret == 0 && ops->iotlb_sync_map)
39374 - ops->iotlb_sync_map(domain);
39375 + ops->iotlb_sync_map(domain, iova, size);
39379 @@ -2449,6 +2501,19 @@ int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova,
39387 + const struct iommu_ops *ops = domain->ops;
39391 + return ops->unmap_pages ?
39392 + ops->unmap_pages(domain, iova, pgsize, count, iotlb_gather) :
39393 + ops->unmap(domain, iova, pgsize, iotlb_gather);
39399 @@ -2458,7 +2523,7 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
39403 - if (unlikely(ops->unmap == NULL ||
39404 + if (unlikely(!(ops->unmap || ops->unmap_pages) ||
39405 domain->pgsize_bitmap == 0UL))
39408 @@ -2486,9 +2551,9 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
39412 - size_t pgsize = iommu_pgsize(domain, iova, size - unmapped);
39413 -
39414 - unmapped_page = ops->unmap(domain, iova, pgsize, iotlb_gather);
39416 + size - unmapped,
39421 @@ -2535,6 +2600,18 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
39425 + if (ops->map_sg) {
39426 + ret = ops->map_sg(domain, iova, sg, nents, prot, gfp, &mapped);
39428 + if (ops->iotlb_sync_map)
39429 + ops->iotlb_sync_map(domain, iova, mapped);
39440 @@ -2561,7 +2638,13 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
39443 if (ops->iotlb_sync_map)
39444 - ops->iotlb_sync_map(domain);
39445 + ops->iotlb_sync_map(domain, iova, mapped);
39448 + if (domain->ops->flush_iotlb_all && (prot & IOMMU_TLB_SHOT_ENTIRE))
39449 + domain->ops->flush_iotlb_all(domain);
39455 diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
39457 --- a/drivers/iommu/rockchip-iommu.c
39458 +++ b/drivers/iommu/rockchip-iommu.c
39459 @@ -19,6 +19,7 @@
39467 @@ -27,6 +28,7 @@
39475 @@ -75,25 +77,53 @@
39510 +#define PAGE_DESC_HI_SHIFT1 (PAGE_DESC_HI1_LOWER - DTE_HI1_LOWER)
39511 +#define PAGE_DESC_HI_SHIFT2 (PAGE_DESC_HI2_LOWER - DTE_HI2_LOWER)
39524 -/* list of clocks required by IOMMU */
39525 -static const char * const rk_iommu_clocks[] = {
39526 - "aclk", "iface",
39532 @@ -104,15 +134,21 @@ struct rk_iommu {
39554 @@ -174,11 +210,32 @@ static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
39560 + * 31:12 - PT address bit 31:0
39561 + * 11: 8 - PT address bit 35:32
39562 + * 7: 4 - PT address bit 39:36
39563 + * 3: 1 - Reserved
39564 + * 0 - 1 if PT @ PT address is valid
39587 @@ -189,6 +246,15 @@ static inline u32 rk_mk_dte(dma_addr_t pt_dma)
39602 * +---------------------+---+-------+-+
39603 @@ -215,11 +281,37 @@ static inline u32 rk_mk_dte(dma_addr_t pt_dma)
39609 + * 31:12 - Page address bit 31:0
39610 + * 11:9 - Page address bit 34:32
39611 + * 8:4 - Page address bit 39:35
39612 + * 3 - Security
39613 + * 2 - Writable
39614 + * 1 - Readable
39615 + * 0 - 1 if Page @ Page address is valid
39641 @@ -235,6 +327,20 @@ static u32 rk_mk_pte(phys_addr_t page, int prot)
39662 @@ -350,6 +456,10 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
39668 + if (iommu->skip_read)
39673 @@ -358,15 +468,22 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
39679 + if (iommu->skip_read)
39685 - if (ret)
39687 for (i = 0; i < iommu->num_mmu; i++)
39688 - dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n",
39689 + dev_err(iommu->dev, "Enable stall request timed out, retry_count = %d, status: %#08x\n",
39691 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39692 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39698 @@ -375,19 +492,30 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu)
39704 + if (iommu->skip_read)
39712 + if (iommu->skip_read)
39718 - if (ret)
39720 for (i = 0; i < iommu->num_mmu; i++)
39721 - dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n",
39722 + dev_err(iommu->dev, "Disable stall request timed out, retry_count = %d, status: %#08x\n",
39724 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39725 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39731 @@ -396,19 +524,30 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu)
39737 + if (iommu->skip_read)
39745 + if (iommu->skip_read)
39751 - if (ret)
39753 for (i = 0; i < iommu->num_mmu; i++)
39754 - dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n",
39755 + dev_err(iommu->dev, "Enable paging request timed out, retry_count = %d, status: %#08x\n",
39757 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39758 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39764 @@ -417,19 +556,30 @@ static int rk_iommu_disable_paging(struct rk_iommu *iommu)
39770 + if (iommu->skip_read)
39778 + if (iommu->skip_read)
39784 - if (ret)
39786 for (i = 0; i < iommu->num_mmu; i++)
39787 - dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n",
39788 + dev_err(iommu->dev, "Disable paging request timed out, retry_count = %d, status: %#08x\n",
39790 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39791 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39797 @@ -439,25 +589,40 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
39803 if (iommu->reset_disabled)
39806 + if (iommu->skip_read)
39817 for (i = 0; i < iommu->num_mmu; i++) {
39818 rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, DTE_ADDR_DUMMY);
39820 + if (iommu->version >= 0x2)
39824 dte_addr = rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR);
39825 - if (dte_addr != (DTE_ADDR_DUMMY & RK_DTE_PT_ADDRESS_MASK)) {
39827 dev_err(iommu->dev, "Error during raw reset. MMU_DTE_ADDR is not functioning\n");
39828 return -EFAULT;
39834 + if (iommu->skip_read)
39839 @@ -490,6 +655,10 @@ static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova)
39843 + if (iommu->version >= 0x2) {
39850 @@ -498,14 +667,20 @@ static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova)
39854 - pte_addr_phys = rk_dte_pt_address(dte) + (pte_index * 4);
39855 + if (iommu->version >= 0x2)
39865 - page_addr_phys = rk_pte_page_address(pte) + page_offset;
39866 + if (iommu->version >= 0x2)
39873 @@ -522,6 +697,7 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
39881 @@ -561,12 +737,20 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
39883 if (iommu->domain)
39884 report_iommu_fault(iommu->domain, iommu->dev, iova,
39885 - flags);
39888 dev_err(iommu->dev, "Page fault while iommu not attached to domain?\n");
39890 rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
39891 - rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_PAGE_FAULT_DONE);
39895 + * re-enter interrupt when mapping. So we postpone
39898 + int_mask = rk_iommu_read(iommu->bases[i], RK_MMU_INT_MASK);
39900 + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_PAGE_FAULT_DONE);
39904 @@ -614,6 +798,34 @@ static phys_addr_t rk_iommu_iova_to_phys(struct iommu_domain *domain,
39917 + spin_lock_irqsave(&rk_domain->dt_lock, flags);
39919 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
39931 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
39939 @@ -690,6 +902,44 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
39951 + assert_spin_locked(&rk_domain->dt_lock);
39954 + dte_addr = &rk_domain->dt[dte_index];
39961 + return ERR_PTR(-ENOMEM);
39967 + return ERR_PTR(-ENOMEM);
39975 + rk_domain->dt_dma + dte_index * sizeof(u32), 1);
39984 @@ -741,7 +991,9 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
39988 - rk_iommu_zap_iova_first_last(rk_domain, iova, size);
39990 + if (!rk_domain->shootdown_entire)
39995 @@ -757,6 +1009,53 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
39996 return -EADDRINUSE;
40007 + assert_spin_locked(&rk_domain->dt_lock);
40029 + if (!rk_domain->shootdown_entire)
40043 + return -EADDRINUSE;
40049 @@ -764,7 +1063,7 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
40053 - u32 dte_index, pte_index;
40057 spin_lock_irqsave(&rk_domain->dt_lock, flags);
40058 @@ -782,10 +1081,10 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
40062 - dte_index = rk_domain->dt[rk_iova_dte_index(iova)];
40063 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
40066 - pte_dma = rk_dte_pt_address(dte_index) + pte_index * sizeof(u32);
40071 @@ -794,6 +1093,43 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
40085 + spin_lock_irqsave(&rk_domain->dt_lock, flags);
40089 + * (1024 4-KiB pages = 4 MiB).
40096 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
40100 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
40107 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
40115 @@ -834,6 +1170,77 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
40130 + spin_lock_irqsave(&rk_domain->dt_lock, flags);
40134 + * (1024 4-KiB pages = 4 MiB).
40139 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
40142 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
40151 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
40155 + if (!rk_domain->shootdown_entire)
40168 + spin_lock_irqsave(&rk_domain->iommus_lock, flags);
40169 + list_for_each(pos, &rk_domain->iommus) {
40175 + ret = pm_runtime_get_if_in_use(iommu->dev);
40179 + WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
40180 + for (i = 0; i < iommu->num_mmu; i++)
40181 + rk_iommu_write(iommu->bases[i], RK_MMU_COMMAND,
40183 + clk_bulk_disable(iommu->num_clocks, iommu->clocks);
40184 + pm_runtime_put(iommu->dev);
40187 + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
40193 @@ -858,12 +1265,28 @@ static void rk_iommu_disable(struct rk_iommu *iommu)
40194 clk_bulk_disable(iommu->num_clocks, iommu->clocks);
40203 + return -ENODEV;
40214 struct iommu_domain *domain = iommu->domain;
40220 ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
40222 @@ -878,10 +1301,21 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
40225 for (i = 0; i < iommu->num_mmu; i++) {
40226 - rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
40227 - rk_domain->dt_dma);
40228 + if (iommu->version >= 0x2) {
40229 + dt_v2 = (rk_domain->dt_dma & DT_LO_MASK) |
40230 + ((rk_domain->dt_dma & DT_HI_MASK) >> DT_SHIFT);
40231 + rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, dt_v2);
40233 + rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
40234 + rk_domain->dt_dma);
40236 rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
40237 rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
40240 + auto_gate = rk_iommu_read(iommu->bases[i], RK_MMU_AUTO_GATING);
40242 + rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, auto_gate);
40246 @@ -893,6 +1327,18 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
40256 + return -ENODEV;
40265 @@ -908,8 +1354,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
40269 - /* iommu already detached */
40270 - if (iommu->domain != domain)
40271 + if (!iommu->domain)
40274 iommu->domain = NULL;
40275 @@ -944,19 +1389,20 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
40279 - /* iommu already attached */
40280 - if (iommu->domain == domain)
40281 - return 0;
40282 -
40283 if (iommu->domain)
40284 rk_iommu_detach_device(iommu->domain, dev);
40286 iommu->domain = domain;
40292 spin_lock_irqsave(&rk_domain->iommus_lock, flags);
40293 list_add_tail(&iommu->node, &rk_domain->iommus);
40294 spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
40296 + rk_domain->shootdown_entire = iommu->shootdown_entire;
40297 ret = pm_runtime_get_if_in_use(iommu->dev);
40300 @@ -1054,6 +1500,35 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
40309 + WARN_ON(!list_empty(&rk_domain->iommus));
40312 + u32 dte = rk_domain->dt[i];
40324 + dma_unmap_single(dma_dev, rk_domain->dt_dma,
40326 + free_page((unsigned long)rk_domain->dt);
40328 + if (domain->type == IOMMU_DOMAIN_DMA)
40329 + iommu_put_dma_cookie(&rk_domain->domain);
40336 @@ -1068,6 +1543,16 @@ static struct iommu_device *rk_iommu_probe_device(struct device *dev)
40337 data->link = device_link_add(dev, iommu->dev,
40340 + data->defer_attach = false;
40343 + if (!dev->dma_parms)
40344 + dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL);
40345 + if (!dev->dma_parms)
40346 + return ERR_PTR(-ENOMEM);
40350 return &iommu->iommu;
40353 @@ -1087,6 +1572,14 @@ static struct iommu_group *rk_iommu_device_group(struct device *dev)
40354 return iommu_group_ref_get(iommu->group);
40362 + return data->defer_attach;
40368 @@ -1100,6 +1593,10 @@ static int rk_iommu_of_xlate(struct device *dev,
40369 iommu_dev = of_find_device_by_node(args->np);
40371 data->iommu = platform_get_drvdata(iommu_dev);
40374 + data->defer_attach = true;
40379 @@ -1107,21 +1604,90 @@ static int rk_iommu_of_xlate(struct device *dev,
40383 -static const struct iommu_ops rk_iommu_ops = {
40392 + for (i = 0; i < iommu->num_mmu; i++)
40393 + rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
40405 + for (i = 0; i < iommu->num_mmu; i++) {
40407 + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
40408 + rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
40410 + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_PAGE_FAULT_DONE);
40462 + .compatible = "rockchip,iommu-v2",
40470 struct device *dev = &pdev->dev;
40471 @@ -1129,11 +1695,21 @@ static int rk_iommu_probe(struct platform_device *pdev)
40473 int num_res = pdev->num_resources;
40480 return -ENOMEM;
40484 + return -EINVAL;
40486 + data = (struct rockchip_iommu_data *)match->data;
40487 + iommu->version = data->version;
40488 + dev_info(dev, "version = %x\n", iommu->version);
40491 iommu->dev = dev;
40492 iommu->num_mmu = 0;
40493 @@ -1161,26 +1737,30 @@ static int rk_iommu_probe(struct platform_device *pdev)
40495 iommu->reset_disabled = device_property_read_bool(dev,
40496 "rockchip,disable-mmu-reset");
40497 -
40498 - iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
40499 - iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
40500 - sizeof(*iommu->clocks), GFP_KERNEL);
40501 - if (!iommu->clocks)
40502 - return -ENOMEM;
40503 -
40504 - for (i = 0; i < iommu->num_clocks; ++i)
40505 - iommu->clocks[i].id = rk_iommu_clocks[i];
40506 + iommu->skip_read = device_property_read_bool(dev,
40507 + "rockchip,skip-mmu-read");
40508 + iommu->dlr_disable = device_property_read_bool(dev,
40509 + "rockchip,disable-device-link-resume");
40510 + iommu->shootdown_entire = device_property_read_bool(dev,
40511 + "rockchip,shootdown-entire");
40515 + iommu->cmd_retry = device_property_read_bool(dev,
40516 + "rockchip,enable-cmd-retry");
40523 - err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks);
40524 + err = devm_clk_bulk_get_all(dev, &iommu->clocks);
40525 if (err == -ENOENT)
40526 iommu->num_clocks = 0;
40527 - else if (err)
40531 + iommu->num_clocks = err;
40533 err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);
40535 @@ -1196,7 +1776,10 @@ static int rk_iommu_probe(struct platform_device *pdev)
40539 - iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
40540 + if (iommu->version >= 0x2)
40541 + iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops_v2);
40543 + iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
40544 iommu_device_set_fwnode(&iommu->iommu, &dev->of_node->fwnode);
40546 err = iommu_device_register(&iommu->iommu);
40547 @@ -1211,10 +1794,16 @@ static int rk_iommu_probe(struct platform_device *pdev)
40549 dma_dev = &pdev->dev;
40551 - bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
40552 + if (iommu->version >= 0x2)
40559 + if (iommu->skip_read)
40562 for (i = 0; i < iommu->num_irq; i++) {
40565 @@ -1229,6 +1818,7 @@ static int rk_iommu_probe(struct platform_device *pdev)
40572 iommu_device_sysfs_remove(&iommu->iommu);
40573 @@ -1260,6 +1850,9 @@ static int __maybe_unused rk_iommu_suspend(struct device *dev)
40574 if (!iommu->domain)
40577 + if (iommu->dlr_disable)
40583 @@ -1271,6 +1864,9 @@ static int __maybe_unused rk_iommu_resume(struct device *dev)
40584 if (!iommu->domain)
40587 + if (iommu->dlr_disable)
40593 @@ -1280,11 +1876,6 @@ static const struct dev_pm_ops rk_iommu_pm_ops = {
40597 -static const struct of_device_id rk_iommu_dt_ids[] = {
40598 - { .compatible = "rockchip,iommu" },
40599 - { /* sentinel */ }
40600 -};
40601 -
40605 @@ -1301,3 +1892,8 @@ static int __init rk_iommu_init(void)
40611 +MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
40612 +MODULE_ALIAS("platform:rockchip-iommu");
40614 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
40616 --- a/drivers/irqchip/Kconfig
40618 @@ -416,8 +416,9 @@ config IRQ_UNIPHIER_AIDET
40622 - bool "Meson GPIO Interrupt Multiplexer"
40623 - depends on ARCH_MESON
40630 diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
40632 --- a/drivers/irqchip/irq-gic-v3-its.c
40633 +++ b/drivers/irqchip/irq-gic-v3-its.c
40634 @@ -2167,6 +2167,8 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
40643 @@ -2290,6 +2292,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
40649 psz = baser->psz;
40651 @@ -2301,7 +2304,10 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
40655 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
40659 + page = alloc_pages_node(its->numa_node, gfp_flags, order);
40661 return -ENOMEM;
40663 @@ -2348,6 +2354,14 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
40665 tmp = baser->val;
40678 @@ -2930,6 +2944,8 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
40687 @@ -3077,6 +3093,10 @@ static void its_cpu_init_lpis(void)
40698 @@ -3101,6 +3121,10 @@ static void its_cpu_init_lpis(void)
40708 * The HW reports non-shareable, we must remove the
40709 @@ -3263,7 +3287,11 @@ static bool its_alloc_table_entry(struct its_node *its,
40713 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
40718 + page = alloc_pages_node(its->numa_node, gfp_flags,
40719 get_order(baser->psz));
40722 @@ -3352,6 +3380,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
40730 @@ -3367,7 +3396,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
40732 sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
40733 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
40734 - itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
40738 + itt = kzalloc_node(sz, gfp_flags, its->numa_node);
40742 @@ -3841,8 +3873,6 @@ static void its_vpe_schedule(struct its_vpe *vpe)
40743 val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
40746 -
40747 - its_wait_vpt_parse_complete();
40751 @@ -3890,6 +3920,10 @@ static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
40762 @@ -4051,8 +4085,6 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe,
40763 val |= FIELD_PREP(GICR_VPENDBASER_4_1_VPEID, vpe->vpe_id);
40766 -
40767 - its_wait_vpt_parse_complete();
40771 @@ -4127,6 +4159,10 @@ static int its_vpe_4_1_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
40782 @@ -4945,6 +4981,7 @@ static int __init its_probe_one(struct resource *res,
40788 its_base = ioremap(res->start, SZ_64K);
40790 @@ -5013,7 +5050,10 @@ static int __init its_probe_one(struct resource *res,
40792 its->numa_node = numa_node;
40794 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
40798 + page = alloc_pages_node(its->numa_node, gfp_flags,
40801 err = -ENOMEM;
40802 @@ -5044,6 +5084,10 @@ static int __init its_probe_one(struct resource *res,
40803 gits_write_cbaser(baser, its->base + GITS_CBASER);
40804 tmp = gits_read_cbaser(its->base + GITS_CBASER);
40813 diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
40815 --- a/drivers/irqchip/irq-gic-v3.c
40816 +++ b/drivers/irqchip/irq-gic-v3.c
40817 @@ -18,6 +18,9 @@
40826 #include <linux/irqchip/arm-gic-common.h>
40827 @@ -725,6 +728,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
40835 @@ -1309,6 +1313,27 @@ static void gic_cpu_pm_init(void)
40863 @@ -1765,6 +1790,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
40871 diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
40873 --- a/drivers/irqchip/irq-gic-v4.c
40874 +++ b/drivers/irqchip/irq-gic-v4.c
40875 @@ -232,6 +232,8 @@ int its_make_vpe_non_resident(struct its_vpe *vpe, bool db)
40877 vpe->resident = false;
40879 + vpe->ready = false;
40884 @@ -258,6 +260,23 @@ int its_make_vpe_resident(struct its_vpe *vpe, bool g0en, bool g1en)
40899 + vpe->ready = true;
40908 diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
40910 --- a/drivers/irqchip/irq-meson-gpio.c
40911 +++ b/drivers/irqchip/irq-meson-gpio.c
40912 @@ -15,6 +15,7 @@
40920 @@ -136,6 +137,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
40928 @@ -436,8 +438,8 @@ static const struct irq_domain_ops meson_gpio_irq_domain_ops = {
40932 -static int __init meson_gpio_irq_parse_dt(struct device_node *node,
40933 - struct meson_gpio_irq_controller *ctl)
40939 @@ -463,63 +465,84 @@ static int __init meson_gpio_irq_parse_dt(struct device_node *node,
40943 -static int __init meson_gpio_irq_of_init(struct device_node *node,
40944 - struct device_node *parent)
40947 - struct irq_domain *domain, *parent_domain;
40948 + struct device_node *node = pdev->dev.of_node, *parent;
40956 - pr_err("missing parent interrupt node\n");
40957 + dev_err(&pdev->dev, "missing parent interrupt node\n");
40958 return -ENODEV;
40963 - pr_err("unable to obtain parent domain\n");
40964 + dev_err(&pdev->dev, "unable to obtain parent domain\n");
40965 return -ENXIO;
40968 - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
40969 + ctl = devm_kzalloc(&pdev->dev, sizeof(*ctl), GFP_KERNEL);
40971 return -ENOMEM;
40973 spin_lock_init(&ctl->lock);
40975 - ctl->base = of_iomap(node, 0);
40976 - if (!ctl->base) {
40977 - ret = -ENOMEM;
40978 - goto free_ctl;
40979 - }
40981 + ctl->base = devm_ioremap_resource(&pdev->dev, res);
40982 + if (IS_ERR(ctl->base))
40983 + return PTR_ERR(ctl->base);
40987 - goto free_channel_irqs;
40988 -
40989 - domain = irq_domain_create_hierarchy(parent_domain, 0,
40990 - ctl->params->nr_hwirq,
40991 - of_node_to_fwnode(node),
40992 - &meson_gpio_irq_domain_ops,
40993 - ctl);
40994 - if (!domain) {
40995 - pr_err("failed to add domain\n");
40996 - ret = -ENODEV;
40997 - goto free_channel_irqs;
41000 + ctl->domain = irq_domain_create_hierarchy(parent_domain, 0,
41001 + ctl->params->nr_hwirq,
41005 + if (!ctl->domain) {
41006 + dev_err(&pdev->dev, "failed to add domain\n");
41007 + return -ENODEV;
41010 - pr_info("%d to %d gpio interrupt mux initialized\n",
41011 - ctl->params->nr_hwirq, NUM_CHANNEL);
41014 + dev_info(&pdev->dev, "%d to %d gpio interrupt mux initialized\n",
41015 + ctl->params->nr_hwirq, NUM_CHANNEL);
41020 -free_channel_irqs:
41021 - iounmap(ctl->base);
41022 -free_ctl:
41023 - kfree(ctl);
41028 - return ret;
41029 + irq_domain_remove(ctl->domain);
41034 -IRQCHIP_DECLARE(meson_gpio_intc, "amlogic,meson-gpio-intc",
41035 - meson_gpio_irq_of_init);
41037 + { .compatible = "amlogic,meson-gpio-intc", },
41046 + .name = "meson-gpio-intc",
41054 +MODULE_ALIAS("platform:meson-gpio-intc");
41055 diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c
41057 --- a/drivers/mailbox/rockchip-mailbox.c
41058 +++ b/drivers/mailbox/rockchip-mailbox.c
41059 @@ -11,6 +11,7 @@
41067 @@ -24,7 +25,7 @@
41071 - int rx_size;
41076 @@ -34,17 +35,13 @@ struct rockchip_mbox_data {
41080 - struct rockchip_mbox_msg *msg;
41081 - struct rockchip_mbox *mb;
41088 -
41089 - /* The maximum size of buf for each channel */
41090 - u32 buf_size;
41095 @@ -53,24 +50,23 @@ static int rockchip_mbox_send_data(struct mbox_chan *chan, void *data)
41097 struct rockchip_mbox *mb = dev_get_drvdata(chan->mbox->dev);
41099 - struct rockchip_mbox_chan *chans = mb->chans;
41100 + struct rockchip_mbox_chan *chans = chan->con_priv;
41104 return -EINVAL;
41106 - if (msg->rx_size > mb->buf_size) {
41107 - dev_err(mb->mbox.dev, "Transmit size over buf size(%d)\n",
41108 - mb->buf_size);
41109 - return -EINVAL;
41110 + status = readl_relaxed(mb->mbox_base + MAILBOX_A2B_STATUS);
41111 + if (status & (1U << chans->idx)) {
41112 + dev_err(mb->mbox.dev, "The mailbox channel is busy\n");
41113 + return -EBUSY;
41116 - dev_dbg(mb->mbox.dev, "Chan[%d]: A2B message, cmd 0x%08x\n",
41117 - chans->idx, msg->cmd);
41118 -
41119 - mb->chans[chans->idx].msg = msg;
41120 + dev_dbg(mb->mbox.dev, "Chan[%d]: A2B message, cmd 0x%08x, data 0x%08x\n",
41121 + chans->idx, msg->cmd, msg->data);
41123 writel_relaxed(msg->cmd, mb->mbox_base + MAILBOX_A2B_CMD(chans->idx));
41124 - writel_relaxed(msg->rx_size, mb->mbox_base +
41125 + writel_relaxed(msg->data, mb->mbox_base +
41126 MAILBOX_A2B_DAT(chans->idx));
41129 @@ -79,10 +75,15 @@ static int rockchip_mbox_send_data(struct mbox_chan *chan, void *data)
41132 struct rockchip_mbox *mb = dev_get_drvdata(chan->mbox->dev);
41133 + struct rockchip_mbox_chan *chans = chan->con_priv;
41136 - /* Enable all B2A interrupts */
41137 - writel_relaxed((1 << mb->mbox.num_chans) - 1,
41138 - mb->mbox_base + MAILBOX_B2A_INTEN);
41140 + spin_lock(&mb->cfg_lock);
41141 + val = readl_relaxed(mb->mbox_base + MAILBOX_B2A_INTEN) |
41142 + (1U << chans->idx);
41143 + writel_relaxed(val, mb->mbox_base + MAILBOX_B2A_INTEN);
41144 + spin_unlock(&mb->cfg_lock);
41148 @@ -90,12 +91,15 @@ static int rockchip_mbox_startup(struct mbox_chan *chan)
41151 struct rockchip_mbox *mb = dev_get_drvdata(chan->mbox->dev);
41152 - struct rockchip_mbox_chan *chans = mb->chans;
41153 -
41154 - /* Disable all B2A interrupts */
41155 - writel_relaxed(0, mb->mbox_base + MAILBOX_B2A_INTEN);
41156 -
41157 - mb->chans[chans->idx].msg = NULL;
41158 + struct rockchip_mbox_chan *chans = chan->con_priv;
41162 + spin_lock(&mb->cfg_lock);
41163 + val = readl_relaxed(mb->mbox_base + MAILBOX_B2A_INTEN) &
41164 + ~(1U << chans->idx);
41165 + writel_relaxed(val, mb->mbox_base + MAILBOX_B2A_INTEN);
41166 + spin_unlock(&mb->cfg_lock);
41170 @@ -107,45 +111,28 @@ static const struct mbox_chan_ops rockchip_mbox_chan_ops = {
41176 u32 status = readl_relaxed(mb->mbox_base + MAILBOX_B2A_STATUS);
41178 for (idx = 0; idx < mb->mbox.num_chans; idx++) {
41179 - if ((status & (1 << idx)) && (irq == mb->chans[idx].irq)) {
41180 + if ((status & (1U << idx)) && irq == mb->chans[idx].irq) {
41182 + msg.cmd = readl_relaxed(mb->mbox_base +
41184 + msg.data = readl_relaxed(mb->mbox_base +
41187 + dev_dbg(mb->mbox.dev, "Chan[%d]: B2A message, cmd 0x%08x, data 0x%08x\n",
41190 + if (mb->mbox.chans[idx].cl)
41191 + mbox_chan_received_data(&mb->mbox.chans[idx],
41194 - writel_relaxed(1 << idx,
41196 mb->mbox_base + MAILBOX_B2A_STATUS);
41197 - return IRQ_WAKE_THREAD;
41198 - }
41199 - }
41200 -
41201 - return IRQ_NONE;
41202 -}
41203 -
41204 -static irqreturn_t rockchip_mbox_isr(int irq, void *dev_id)
41205 -{
41206 - int idx;
41207 - struct rockchip_mbox_msg *msg = NULL;
41208 - struct rockchip_mbox *mb = (struct rockchip_mbox *)dev_id;
41209 -
41210 - for (idx = 0; idx < mb->mbox.num_chans; idx++) {
41211 - if (irq != mb->chans[idx].irq)
41212 - continue;
41213 -
41214 - msg = mb->chans[idx].msg;
41215 - if (!msg) {
41216 - dev_err(mb->mbox.dev,
41217 - "Chan[%d]: B2A message is NULL\n", idx);
41218 - break; /* spurious */
41220 -
41221 - mbox_chan_received_data(&mb->mbox.chans[idx], msg);
41222 - mb->chans[idx].msg = NULL;
41223 -
41224 - dev_dbg(mb->mbox.dev, "Chan[%d]: B2A message, cmd 0x%08x\n",
41225 - idx, msg->cmd);
41226 -
41227 - break;
41231 @@ -195,6 +182,7 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
41232 mb->mbox.num_chans = drv_data->num_chans;
41233 mb->mbox.ops = &rockchip_mbox_chan_ops;
41234 mb->mbox.txdone_irq = true;
41235 + spin_lock_init(&mb->cfg_lock);
41239 @@ -204,9 +192,6 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
41240 if (IS_ERR(mb->mbox_base))
41241 return PTR_ERR(mb->mbox_base);
41243 - /* Each channel has two buffers for A2B and B2A */
41244 - mb->buf_size = (size_t)resource_size(res) / (drv_data->num_chans * 2);
41245 -
41246 mb->pclk = devm_clk_get(&pdev->dev, "pclk_mailbox");
41247 if (IS_ERR(mb->pclk)) {
41248 ret = PTR_ERR(mb->pclk);
41249 @@ -223,20 +208,26 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
41251 for (i = 0; i < mb->mbox.num_chans; i++) {
41253 - if (irq < 0)
41254 - return irq;
41255 -
41256 - ret = devm_request_threaded_irq(&pdev->dev, irq,
41257 - rockchip_mbox_irq,
41258 - rockchip_mbox_isr, IRQF_ONESHOT,
41259 - dev_name(&pdev->dev), mb);
41260 - if (ret < 0)
41261 - return ret;
41264 + if (i > 0 && irq == -ENXIO)
41265 + mb->chans[i].irq = mb->chans[0].irq;
41269 + mb->chans[i].irq = irq;
41270 + ret = devm_request_threaded_irq(&pdev->dev, irq,
41274 + dev_name(&pdev->dev),
41280 mb->chans[i].idx = i;
41281 - mb->chans[i].irq = irq;
41282 - mb->chans[i].mb = mb;
41283 - mb->chans[i].msg = NULL;
41284 + mb->mbox.chans[i].con_priv = &mb->chans[i];
41287 ret = devm_mbox_controller_register(&pdev->dev, &mb->mbox);
41288 diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
41290 --- a/drivers/media/i2c/Kconfig
41292 @@ -384,6 +384,19 @@ config VIDEO_TC358743_CEC
41304 + Support for the Toshiba TC35874X HDMI to MIPI CSI-2 bridge.
41312 @@ -710,6 +723,16 @@ config VIDEO_ST_MIPID02
41315 module will be called st-mipid02.
41318 + tristate "Rockchip IR-CUT control device"
41321 + Support for the Rockchip IR-CUT control board.
41329 @@ -725,6 +748,17 @@ config VIDEO_APTINA_PLL
41345 tristate "Hynix Hi-556 sensor support"
41347 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
41349 --- a/drivers/media/i2c/Makefile
41351 @@ -108,9 +108,12 @@ obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
41352 obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
41353 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
41354 obj-$(CONFIG_VIDEO_I2C) += video-i2c.o
41355 +obj-$(CONFIG_VIDEO_RK_IRCUT) += rk_ircut.o
41356 obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
41357 obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
41358 obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
41359 +obj-$(CONFIG_VIDEO_TC35874X) += tc35874x.o
41360 +obj-$(CONFIG_VIDEO_GC8034) += gc8034.o
41361 obj-$(CONFIG_VIDEO_HI556) += hi556.o
41362 obj-$(CONFIG_VIDEO_IMX214) += imx214.o
41363 obj-$(CONFIG_VIDEO_IMX219) += imx219.o
41364 diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
41366 --- a/drivers/media/platform/Kconfig
41368 @@ -153,6 +153,9 @@ source "drivers/media/platform/xilinx/Kconfig"
41369 source "drivers/media/platform/rcar-vin/Kconfig"
41378 diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
41380 --- a/drivers/media/platform/Makefile
41382 @@ -53,6 +53,9 @@ obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
41383 obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
41385 obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/
41386 +obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip/cif/
41387 +obj-$(CONFIG_VIDEO_ROCKCHIP_ISP) += rockchip/isp/
41388 +obj-$(CONFIG_VIDEO_ROCKCHIP_ISPP) += rockchip/ispp/
41390 obj-y += omap/
41392 diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
41394 --- a/drivers/media/usb/uvc/uvc_driver.c
41396 @@ -12,6 +12,7 @@
41404 @@ -2341,7 +2342,11 @@ static int uvc_probe(struct usb_interface *intf,
41408 - usb_enable_autosuspend(udev);
41409 + if (udev->quirks & USB_QUIRK_AUTO_SUSPEND ||
41410 + udev->parent->quirks & USB_QUIRK_AUTO_SUSPEND)
41411 + uvc_printk(KERN_INFO, "auto-suspend is blacklisted for this device\n");
41417 diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
41419 --- a/drivers/media/v4l2-core/v4l2-async.c
41420 +++ b/drivers/media/v4l2-core/v4l2-async.c
41421 @@ -555,6 +555,60 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
41432 + list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
41441 + list_for_each_entry_safe(sd, tmp, ¬ifier->waiting, async_list) {
41442 + list_del_init(&sd->async_list);
41443 + sd->asd = NULL;
41444 + sd->dev = NULL;
41458 + while (notifier->parent)
41459 + notifier = notifier->parent;
41461 + if (!notifier->v4l2_dev)
41465 + dev_info(notifier->v4l2_dev->dev,
41482 diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
41484 --- a/drivers/mfd/rk808.c
41486 @@ -2,7 +2,7 @@
41490 - * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
41491 + * Copyright (c) 2014-2018, Fuzhou Rockchip Electronics Co., Ltd
41493 * Author: Chris Zhong <zyw@rock-chips.com>
41494 * Author: Zhang Qing <zhangqing@rock-chips.com>
41495 @@ -18,7 +18,11 @@
41507 @@ -65,22 +69,61 @@ static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
41519 - case RK817_SYS_STS:
41523 - return true;
41531 + * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
41533 + * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
41565 - .max_register = RK818_USB_CTRL_REG,
41568 - .volatile_reg = rk808_is_volatile_reg,
41573 @@ -99,11 +142,20 @@ static const struct regmap_config rk808_regmap_config = {
41589 - .cache_type = REGCACHE_NONE,
41595 @@ -111,18 +163,27 @@ static struct resource rtc_resources[] = {
41608 - DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
41619 - DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
41625 @@ -150,9 +211,28 @@ static const struct mfd_cell rk808s[] = {
41630 + { .name = "rk808-clkout", },
41631 + { .name = "rk808-regulator", },
41632 + { .name = "rk805-pinctrl", },
41633 + { .name = "rk816-battery", .of_compatible = "rk816-battery", },
41635 + .name = "rk805-pwrkey",
41640 + .name = "rk808-rtc",
41647 { .name = "rk808-clkout",},
41648 { .name = "rk808-regulator",},
41649 + { .name = "rk817-battery", .of_compatible = "rk817,battery", },
41650 + { .name = "rk817-charger", .of_compatible = "rk817,charger", },
41652 .name = "rk805-pwrkey",
41654 @@ -163,11 +243,17 @@ static const struct mfd_cell rk817s[] = {
41659 + .name = "rk817-codec",
41660 + .of_compatible = "rockchip,rk817-codec",
41665 { .name = "rk808-clkout", },
41666 { .name = "rk808-regulator", },
41667 + { .name = "rk818-battery", .of_compatible = "rk818-battery", },
41668 + { .name = "rk818-charger", },
41670 .name = "rk808-rtc",
41672 @@ -176,16 +262,18 @@ static const struct mfd_cell rk818s[] = {
41676 - {RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
41677 - RK805_BUCK1_2_ILMAX_4000MA},
41678 - {RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
41679 - RK805_BUCK1_2_ILMAX_4000MA},
41680 - {RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
41681 - RK805_BUCK3_ILMAX_3000MA},
41682 - {RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
41683 - RK805_BUCK4_ILMAX_3500MA},
41699 @@ -195,11 +283,40 @@ static const struct rk808_reg_data rk808_pre_init_reg[] = {
41740 @@ -220,8 +337,10 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
41751 @@ -301,6 +420,70 @@ static const struct regmap_irq rk808_irqs[] = {
41822 @@ -421,6 +604,61 @@ static const struct regmap_irq_chip rk808_irq_chip = {
41884 @@ -446,8 +684,70 @@ static const struct regmap_irq_chip rk818_irq_chip = {
41899 + ret = regmap_update_bits(rk808->regmap,
41903 + dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
41912 + regmap_update_bits(rk808->regmap,
41915 + regmap_update_bits(rk808->regmap,
41919 + if (rk808->pins && rk808->pins->p && rk808->pins->power_off) {
41920 + ret = regmap_update_bits(rk808->regmap,
41927 + ret = regmap_update_bits(rk808->regmap,
41934 + ret = pinctrl_select_state(rk808->pins->p,
41935 + rk808->pins->power_off);
41942 + ret = regmap_update_bits(rk808->regmap,
41946 + dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
41951 -static void rk808_pm_power_off(void)
41956 @@ -462,6 +762,10 @@ static void rk808_pm_power_off(void)
41967 @@ -469,42 +773,345 @@ static void rk808_pm_power_off(void)
41972 ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
41974 dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
41977 -static void rk8xx_shutdown(struct i2c_client *client)
41983 - struct rk808 *rk808 = i2c_get_clientdata(client);
41987 - switch (rk808->variant) {
41988 - case RK805_ID:
41989 - ret = regmap_update_bits(rk808->regmap,
41990 - RK805_GPIO_IO_POL_REG,
41991 - SLP_SD_MSK,
41992 - SHUTDOWN_FUN);
41994 + dev_warn(&rk808_i2c_client->dev,
42000 + regmap_update_bits(rk808->regmap,
42003 + regmap_update_bits(rk808->regmap,
42015 + if (rk808->variant == RK809_ID || rk808->variant == RK817_ID) {
42016 + ret = regmap_update_bits(rk808->regmap,
42021 + dev_warn(&rk808_i2c_client->dev,
42027 + dev_info(&rk808_i2c_client->dev, "System power off\n");
42030 + dev_info(&rk808_i2c_client->dev,
42082 + regmap_write(rk808->regmap, addr, data);
42083 + regmap_read(rk808->regmap, addr, &data);
42086 - case RK809_ID:
42087 - case RK817_ID:
42088 - ret = regmap_update_bits(rk808->regmap,
42089 - RK817_SYS_CFG(3),
42090 - RK817_SLPPIN_FUNC_MSK,
42091 - SLPPIN_DN_FUN);
42100 + regmap_read(rk808->regmap, addr, &data);
42104 - return;
42119 + pinctrl_dev = platform_device_alloc("rk805-pinctrl", -1);
42122 + return -ENOMEM;
42125 + pinctrl_dev->dev.parent = dev;
42131 + dev_err(dev, "Add rk805-pinctrl dev failed!\n");
42134 + if (dev->pins && !IS_ERR(dev->pins->p)) {
42139 + rk808->pins = devm_kzalloc(dev, sizeof(struct rk808_pin_info),
42141 + if (!rk808->pins)
42142 + return -ENOMEM;
42144 + rk808->pins->p = devm_pinctrl_get(dev);
42145 + if (IS_ERR(rk808->pins->p)) {
42146 + rk808->pins->p = NULL;
42151 + default_st = pinctrl_lookup_state(rk808->pins->p,
42156 + return -EINVAL;
42159 + ret = pinctrl_select_state(rk808->pins->p, default_st);
42162 + return -EINVAL;
42165 + rk808->pins->power_off = pinctrl_lookup_state(rk808->pins->p,
42166 + "pmic-power-off");
42167 + if (IS_ERR(rk808->pins->power_off)) {
42168 + rk808->pins->power_off = NULL;
42169 + dev_dbg(dev, "no power-off pinctrl state\n");
42172 + rk808->pins->sleep = pinctrl_lookup_state(rk808->pins->p,
42173 + "pmic-sleep");
42174 + if (IS_ERR(rk808->pins->sleep)) {
42175 + rk808->pins->sleep = NULL;
42176 + dev_dbg(dev, "no sleep-setting state\n");
42179 + rk808->pins->reset = pinctrl_lookup_state(rk808->pins->p,
42180 + "pmic-reset");
42181 + if (IS_ERR(rk808->pins->reset)) {
42182 + rk808->pins->reset = NULL;
42183 + dev_dbg(dev, "no reset-setting pinctrl state\n");
42187 + ret = pinctrl_select_state(rk808->pins->p, rk808->pins->reset);
42190 - dev_warn(&client->dev,
42191 - "Cannot switch to power down function\n");
42192 + dev_dbg(dev, "failed to activate reset-setting pinctrl state\n");
42217 + dev = &data->rk808->i2c->dev;
42219 + regmap_read(data->rk808->regmap, RK817_POWER_EN_SAVE0,
42222 + regmap_read(data->rk808->regmap, RK817_POWER_EN_SAVE1,
42225 + regmap_write(data->rk808->regmap,
42229 + regmap_write(data->rk808->regmap,
42233 + regmap_write(data->rk808->regmap,
42237 + regmap_write(data->rk808->regmap,
42254 + * In the case of 0b'00, PMIC reset itself which triggers SoC NPOR-reset
42262 + ret = regmap_update_bits(data->rk808->regmap,
42281 + struct device_node *np = dev->of_node;
42283 + ret = of_property_read_u32_index(np, "fb-inner-reg-idxs", 0, &inner);
42285 + regmap_update_bits(rk808->regmap, RK817_POWER_CONFIG,
42289 + regmap_update_bits(rk808->regmap, RK817_POWER_CONFIG,
42294 + ret = of_property_read_u32(np, "pmic-reset-func", &func);
42306 + regmap_update_bits(rk808->regmap, RK817_SYS_CFG(3), msk, val);
42330 @@ -517,13 +1124,20 @@ static int rk808_probe(struct i2c_client *client,
42331 struct device_node *np = client->dev.of_node;
42342 - int msb, lsb;
42343 - unsigned char pmic_id_msb, pmic_id_lsb;
42351 rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
42353 @@ -564,6 +1178,14 @@ static int rk808_probe(struct i2c_client *client,
42364 + rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare;
42367 rk808->regmap_cfg = &rk808_regmap_config;
42368 @@ -572,6 +1194,23 @@ static int rk808_probe(struct i2c_client *client,
42375 + rk808->regmap_cfg = &rk816_regmap_config;
42376 + rk808->regmap_irq_chip = &rk816_irq_chip;
42391 rk808->regmap_cfg = &rk818_regmap_config;
42392 @@ -580,6 +1219,13 @@ static int rk808_probe(struct i2c_client *client,
42406 @@ -589,6 +1235,11 @@ static int rk808_probe(struct i2c_client *client,
42412 + rk808->pm_pwroff_prep_fn = rk817_shutdown_prepare;
42417 dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
42418 @@ -597,6 +1248,7 @@ static int rk808_probe(struct i2c_client *client,
42421 rk808->i2c = client;
42425 rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
42426 @@ -605,11 +1257,50 @@ static int rk808_probe(struct i2c_client *client,
42427 return PTR_ERR(rk808->regmap);
42431 + ret = regmap_read(rk808->regmap, on_source, &on);
42433 + dev_err(&client->dev, "read 0x%x failed\n", on_source);
42437 + ret = regmap_read(rk808->regmap, off_source, &off);
42439 + dev_err(&client->dev, "read 0x%x failed\n", off_source);
42443 + dev_info(&client->dev, "source: on=0x%02x, off=0x%02x\n",
42447 if (!client->irq) {
42448 dev_err(&client->dev, "No interrupt support, no core IRQ\n");
42449 return -EINVAL;
42453 + of_property_prepare_fn(rk808, &client->dev);
42456 + ret = regmap_update_bits(rk808->regmap,
42461 + dev_err(&client->dev,
42469 + ret = pinctrl_init(&client->dev, rk808);
42474 ret = regmap_add_irq_chip(rk808->regmap, client->irq,
42475 IRQF_ONESHOT, -1,
42476 rk808->regmap_irq_chip, &rk808->irq_data);
42477 @@ -618,15 +1309,15 @@ static int rk808_probe(struct i2c_client *client,
42481 - for (i = 0; i < nr_pre_init_regs; i++) {
42482 - ret = regmap_update_bits(rk808->regmap,
42483 - pre_init_reg[i].addr,
42484 - pre_init_reg[i].mask,
42485 - pre_init_reg[i].value);
42487 + ret = regmap_add_irq_chip(rk808->regmap, client->irq,
42488 + IRQF_ONESHOT | IRQF_SHARED, -1,
42490 + &rk808->battery_irq_data);
42492 dev_err(&client->dev,
42493 - "0x%x write err\n",
42494 - pre_init_reg[i].addr);
42496 + regmap_del_irq_chip(client->irq, rk808->irq_data);
42500 @@ -639,15 +1330,34 @@ static int rk808_probe(struct i2c_client *client,
42504 - if (of_property_read_bool(np, "rockchip,system-power-controller")) {
42505 - rk808_i2c_client = client;
42506 - pm_power_off = rk808_pm_power_off;
42507 + pm_off = of_property_read_bool(np, "rockchip,system-power-controller");
42510 + pm_power_off_prepare = rk808->pm_pwroff_prep_fn;
42523 + dev_err(&client->dev, "create rk8xx sysfs error\n");
42532 regmap_del_irq_chip(client->irq, rk808->irq_data);
42534 + regmap_del_irq_chip(client->irq, rk808->battery_irq_data);
42538 @@ -656,21 +1366,45 @@ static int rk808_remove(struct i2c_client *client)
42541 regmap_del_irq_chip(client->irq, rk808->irq_data);
42542 + mfd_remove_devices(&client->dev);
42548 - if (pm_power_off == rk808_pm_power_off)
42555 + if (rk808->pm_pwroff_prep_fn &&
42556 + pm_power_off_prepare == rk808->pm_pwroff_prep_fn)
42567 - struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
42568 - int ret = 0;
42574 + ret = regmap_update_bits(rk808->regmap,
42585 switch (rk808->variant) {
42587 @@ -681,10 +1415,34 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
42591 - ret = regmap_update_bits(rk808->regmap,
42592 - RK817_SYS_CFG(3),
42593 - RK817_SLPPIN_FUNC_MSK,
42594 - SLPPIN_SLP_FUN);
42595 + if (rk808->pins && rk808->pins->p && rk808->pins->sleep) {
42596 + ret = regmap_update_bits(rk808->regmap,
42605 + ret = regmap_update_bits(rk808->regmap,
42615 + regmap_read(rk808->regmap, RK817_SYS_STS, &value);
42617 + ret = pinctrl_select_state(rk808->pins->p, rk808->pins->sleep);
42626 @@ -695,16 +1453,51 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
42630 - struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
42631 - int ret = 0;
42637 + ret = regmap_update_bits(rk808->regmap,
42648 switch (rk808->variant) {
42651 - ret = regmap_update_bits(rk808->regmap,
42652 - RK817_SYS_CFG(3),
42653 - RK817_SLPPIN_FUNC_MSK,
42654 - SLPPIN_NULL_FUN);
42655 + if (rk808->pins && rk808->pins->p && rk808->pins->reset) {
42656 + ret = regmap_update_bits(rk808->regmap,
42665 + ret = regmap_update_bits(rk808->regmap,
42675 + regmap_read(rk808->regmap, RK817_SYS_STS, &value);
42677 + ret = pinctrl_select_state(rk808->pins->p, rk808->pins->reset);
42684 @@ -712,7 +1505,7 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
42688 -static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
42693 @@ -722,10 +1515,23 @@ static struct i2c_driver rk808_i2c_driver = {
42697 - .shutdown = rk8xx_shutdown,
42717 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
42718 diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
42720 --- a/drivers/mmc/core/block.c
42722 @@ -2893,6 +2893,9 @@ static void mmc_blk_remove_debugfs(struct mmc_card *card,
42732 diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h
42734 --- a/drivers/mmc/core/block.h
42736 @@ -17,4 +17,5 @@ struct work_struct;
42742 diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
42744 --- a/drivers/mmc/core/core.h
42746 @@ -81,6 +81,8 @@ int mmc_attach_mmc(struct mmc_host *host);
42755 diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
42757 --- a/drivers/mmc/core/host.c
42759 @@ -513,6 +513,9 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
42767 * mmc_add_host - initialise host hardware
42769 @@ -580,3 +583,45 @@ void mmc_free_host(struct mmc_host *host)
42775 + * mmc_host_rescan - triger software rescan flow
42794 + return -ENOMEDIUM;
42799 + /* 0: oob 1:cap-sdio-irq */
42801 + host->caps |= MMC_CAP_SDIO_IRQ;
42803 + host->caps &= ~MMC_CAP_SDIO_IRQ;
42805 + dev_err(&host->class_dev, "sdio: host doesn't identify oob or sdio_irq mode!\n");
42806 + return -ENOMEDIUM;
42809 + if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->set_sdio_status)
42810 + host->ops->set_sdio_status(host, val);
42815 diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
42817 --- a/drivers/mmc/core/sdio.c
42819 @@ -3,9 +3,15 @@
42822 * Copyright 2006-2007 Pierre Ossman
42835 @@ -27,48 +33,6 @@
42839 -MMC_DEV_ATTR(vendor, "0x%04x\n", card->cis.vendor);
42840 -MMC_DEV_ATTR(device, "0x%04x\n", card->cis.device);
42841 -MMC_DEV_ATTR(revision, "%u.%u\n", card->major_rev, card->minor_rev);
42842 -MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
42843 -MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
42844 -
42845 -#define sdio_info_attr(num) \
42846 -static ssize_t info##num##_show(struct device *dev, struct device_attribute *attr, char *buf) \
42847 -{ \
42848 - struct mmc_card *card = mmc_dev_to_card(dev); \
42849 - \
42850 - if (num > card->num_info) \
42851 - return -ENODATA; \
42852 - if (!card->info[num-1][0]) \
42853 - return 0; \
42854 - return sprintf(buf, "%s\n", card->info[num-1]); \
42855 -} \
42856 -static DEVICE_ATTR_RO(info##num)
42857 -
42858 -sdio_info_attr(1);
42859 -sdio_info_attr(2);
42860 -sdio_info_attr(3);
42861 -sdio_info_attr(4);
42862 -
42863 -static struct attribute *sdio_std_attrs[] = {
42864 - &dev_attr_vendor.attr,
42865 - &dev_attr_device.attr,
42866 - &dev_attr_revision.attr,
42867 - &dev_attr_info1.attr,
42868 - &dev_attr_info2.attr,
42869 - &dev_attr_info3.attr,
42870 - &dev_attr_info4.attr,
42871 - &dev_attr_ocr.attr,
42872 - &dev_attr_rca.attr,
42873 - NULL,
42874 -};
42875 -ATTRIBUTE_GROUPS(sdio_std);
42876 -
42877 -static struct device_type sdio_type = {
42878 - .groups = sdio_std_groups,
42879 -};
42880 -
42884 @@ -200,18 +164,15 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
42885 if (mmc_host_uhs(card->host)) {
42887 card->sw_caps.sd3_bus_mode
42888 - |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50
42889 - | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
42893 card->sw_caps.sd3_bus_mode
42894 - |= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25
42895 - | SD_MODE_UHS_SDR12;
42899 card->sw_caps.sd3_bus_mode
42900 - |= SD_MODE_UHS_SDR104 | SD_MODE_UHS_SDR50
42901 - | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
42906 @@ -330,49 +291,30 @@ static int sdio_disable_wide(struct mmc_card *card)
42910 -static int sdio_disable_4bit_bus(struct mmc_card *card)
42911 -{
42912 - int err;
42913 -
42914 - if (card->type == MMC_TYPE_SDIO)
42915 - goto out;
42916 -
42917 - if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
42918 - return 0;
42919 -
42920 - if (!(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
42921 - return 0;
42922 -
42923 - err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1);
42924 - if (err)
42925 - return err;
42926 -
42927 -out:
42928 - return sdio_disable_wide(card);
42929 -}
42930 -
42936 - err = sdio_enable_wide(card);
42937 - if (err <= 0)
42938 - return err;
42939 if (card->type == MMC_TYPE_SDIO)
42940 - goto out;
42941 -
42942 - if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) {
42944 + else if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
42945 + (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
42947 - if (err) {
42948 - sdio_disable_wide(card);
42951 - }
42959 + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
42962 -out:
42963 - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
42965 - return 0;
42970 @@ -564,8 +506,10 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card)
42971 max_rate = min_not_zero(card->quirk_max_rate,
42972 card->sw_caps.uhs_max_dtr);
42974 - mmc_set_timing(card->host, timing);
42975 - mmc_set_clock(card->host, max_rate);
42977 + mmc_set_timing(card->host, timing);
42978 + mmc_set_clock(card->host, max_rate);
42983 @@ -605,33 +549,13 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card)
42987 -static int mmc_sdio_pre_init(struct mmc_host *host, u32 ocr,
42988 - struct mmc_card *card)
42992 - if (card)
42993 - mmc_remove_card(card);
42994 -
42995 - /*
42996 - * Reset the card by performing the same steps that are taken by
42997 - * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
42998 - *
42999 - * sdio_reset() is technically not needed. Having just powered up the
43000 - * hardware, it should already be in reset state. However, some
43001 - * platforms (such as SD8686 on OLPC) do not instantly cut power,
43002 - * meaning that a reset is required when restoring power soon after
43003 - * powering off. It is harmless in other cases.
43004 - *
43005 - * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec,
43006 - * is not necessary for non-removable cards. However, it is required
43007 - * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
43008 - * harmless in other situations.
43009 - *
43010 - */
43011 -
43014 - mmc_send_if_cond(host, ocr);
43015 - return mmc_send_io_op_cond(host, 0, NULL);
43016 + mmc_send_if_cond(host, host->ocr_avail);
43021 @@ -641,7 +565,7 @@ static int mmc_sdio_pre_init(struct mmc_host *host, u32 ocr,
43025 - struct mmc_card *oldcard)
43030 @@ -664,9 +588,25 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43034 - err = mmc_send_io_op_cond(host, ocr, &rocr);
43035 - if (err)
43036 - return err;
43038 + if (!(host->chip_alive)) {
43059 @@ -674,15 +614,17 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43063 - return err;
43070 - card = mmc_alloc_card(host, &sdio_type);
43071 - if (IS_ERR(card))
43072 - return PTR_ERR(card);
43080 mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
43081 @@ -690,15 +632,15 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43083 if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
43084 memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
43085 - err = -ENOENT;
43086 - goto mismatch;
43088 + return -ENOENT;
43091 card->type = MMC_TYPE_SDIO;
43093 if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
43094 - err = -ENOENT;
43095 - goto mismatch;
43097 + return -ENOENT;
43101 @@ -719,10 +661,10 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43105 - if (rocr & ocr & R4_18V_PRESENT) {
43108 if (err == -EAGAIN) {
43109 - mmc_sdio_pre_init(host, ocr_card, card);
43111 retries--;
43114 @@ -733,10 +675,20 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43118 - if (!mmc_host_is_spi(host)) {
43121 + if (!(host->chip_alive)) {
43122 + err = mmc_send_relative_addr(host, &card->rca);
43126 + card->rca = 1;
43129 err = mmc_send_relative_addr(host, &card->rca);
43136 @@ -753,7 +705,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43137 if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
43140 - goto remove;
43145 @@ -761,7 +713,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43149 - if (!mmc_host_is_spi(host)) {
43154 @@ -780,12 +732,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43155 mmc_set_timing(card->host, MMC_TIMING_SD_HS);
43158 - if (oldcard)
43159 - mmc_remove_card(card);
43160 - else
43161 - host->card = card;
43162 -
43163 - return 0;
43168 @@ -794,7 +741,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43172 - mmc_sdio_pre_init(host, ocr_card, card);
43177 @@ -811,14 +758,13 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43181 - if (card->cis.vendor == oldcard->cis.vendor &&
43182 - card->cis.device == oldcard->cis.device) {
43183 - mmc_remove_card(card);
43184 - card = oldcard;
43185 - } else {
43186 - err = -ENOENT;
43187 - goto mismatch;
43188 - }
43189 + int same = (card->cis.vendor == oldcard->cis.vendor &&
43190 + card->cis.device == oldcard->cis.device);
43193 + return -ENOENT;
43197 card->ocr = ocr_card;
43199 @@ -879,27 +825,33 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
43200 err = -EINVAL;
43203 -
43204 - host->card = card;
43207 + host->card = card;
43210 -mismatch:
43211 - pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host));
43213 - if (oldcard != card)
43221 -static int mmc_sdio_reinit_card(struct mmc_host *host)
43226 - ret = mmc_sdio_pre_init(host, host->card->ocr, NULL);
43229 + mmc_send_if_cond(host, host->card->ocr);
43235 - return mmc_sdio_init_card(host, host->card->ocr, host->card);
43236 + return mmc_sdio_init_card(host, host->card->ocr, host->card,
43241 @@ -985,37 +937,21 @@ static void mmc_sdio_detect(struct mmc_host *host)
43245 - int i;
43248 for (i = 0; i < host->card->sdio_funcs; i++) {
43249 struct sdio_func *func = host->card->sdio_func[i];
43250 if (func && sdio_func_present(func) && func->dev.driver) {
43251 const struct dev_pm_ops *pmops = func->dev.driver->pm;
43252 - if (!pmops || !pmops->suspend || !pmops->resume)
43253 + if (!pmops || !pmops->suspend || !pmops->resume) {
43255 - goto remove;
43256 + err = -ENOSYS;
43262 - return 0;
43263 -
43264 -remove:
43265 - if (!mmc_card_is_removable(host)) {
43266 - dev_warn(mmc_dev(host),
43267 - "missing suspend/resume ops for non-removable SDIO card\n");
43268 - /* Don't remove a non-removable card - we can't re-detect it. */
43269 - return 0;
43270 - }
43271 -
43272 - /* Remove the SDIO card and let it be re-detected later on. */
43273 - mmc_sdio_remove(host);
43274 - mmc_claim_host(host);
43275 - mmc_detach_bus(host);
43276 - mmc_power_off(host);
43277 - mmc_release_host(host);
43278 - host->pm_flags = 0;
43279 -
43280 - return 0;
43285 @@ -1023,8 +959,6 @@ static int mmc_sdio_pre_suspend(struct mmc_host *host)
43289 - WARN_ON(host->sdio_irqs && !mmc_card_keep_power(host));
43290 -
43292 mmc_card_set_suspended(host->card);
43293 cancel_delayed_work_sync(&host->sdio_irq_work);
43294 @@ -1032,7 +966,7 @@ static int mmc_sdio_suspend(struct mmc_host *host)
43298 - sdio_disable_4bit_bus(host->card);
43299 + sdio_disable_wide(host->card);
43303 @@ -1053,11 +987,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
43307 - /*
43308 - * Restore power and reinitialize the card when needed. Note that a
43309 - * removable card is checked from a detect work later on in the resume
43310 - * process.
43311 - */
43314 mmc_power_up(host, host->card->ocr);
43316 @@ -1071,8 +1001,12 @@ static int mmc_sdio_resume(struct mmc_host *host)
43317 pm_runtime_set_active(&host->card->dev);
43318 pm_runtime_enable(&host->card->dev);
43320 - err = mmc_sdio_reinit_card(host);
43321 - } else if (mmc_card_wake_sdio_irq(host)) {
43324 + /* No need to reinitialize powered-resumed nonremovable cards */
43328 /* We may have switched to 1-bit mode during suspend */
43329 err = sdio_enable_4bit_bus(host->card);
43331 @@ -1087,7 +1021,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
43332 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD))
43333 wake_up_process(host->sdio_irq_thread);
43334 else if (host->caps & MMC_CAP_SDIO_IRQ)
43335 - queue_delayed_work(system_wq, &host->sdio_irq_work, 0);
43336 + host->ops->enable_sdio_irq(host, 1);
43340 @@ -1097,6 +1031,38 @@ static int mmc_sdio_resume(struct mmc_host *host)
43359 + * is not necessary for non-removable cards. However, it is required
43368 + if (!ret && host->sdio_irqs)
43379 @@ -1114,42 +1080,16 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
43380 /* Restore power and re-initialize. */
43382 mmc_power_up(host, host->card->ocr);
43383 - ret = mmc_sdio_reinit_card(host);
43390 -/*
43391 - * SDIO HW reset
43392 - *
43393 - * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW
43394 - * reset was asynchronously scheduled, else a negative error code.
43395 - */
43398 - struct mmc_card *card = host->card;
43399 -
43400 - /*
43401 - * In case the card is shared among multiple func drivers, reset the
43402 - * card through a rescan work. In this way it will be removed and
43403 - * re-detected, thus all func drivers becomes informed about it.
43404 - */
43405 - if (atomic_read(&card->sdio_funcs_probed) > 1) {
43406 - if (mmc_card_removed(card))
43407 - return 1;
43408 - host->rescan_entered = 0;
43409 - mmc_card_set_removed(card);
43410 - _mmc_detect_change(host, 0, false);
43411 - return 1;
43412 - }
43413 -
43414 - /*
43415 - * A single func driver has been probed, then let's skip the heavy
43416 - * hotplug dance above and execute the reset immediately.
43417 - */
43418 - mmc_power_cycle(host, card->ocr);
43419 - return mmc_sdio_reinit_card(host);
43420 + mmc_power_cycle(host, host->card->ocr);
43425 @@ -1161,7 +1101,7 @@ static int mmc_sdio_sw_reset(struct mmc_host *host)
43429 - return mmc_sdio_reinit_card(host);
43434 @@ -1189,9 +1129,21 @@ int mmc_attach_sdio(struct mmc_host *host)
43436 WARN_ON(!host->claimed);
43439 + if (!(host->chip_alive)) {
43455 if (host->ocr_avail_sdio)
43456 @@ -1211,7 +1163,7 @@ int mmc_attach_sdio(struct mmc_host *host)
43460 - err = mmc_sdio_init_card(host, rocr, NULL);
43465 @@ -1262,6 +1214,11 @@ int mmc_attach_sdio(struct mmc_host *host)
43466 pm_runtime_enable(&card->sdio_func[i]->dev);
43470 + if (host->card->sdio_func[1])
43471 + host->card->sdio_func[1]->card_alive = host->chip_alive;
43477 @@ -1306,3 +1263,48 @@ int mmc_attach_sdio(struct mmc_host *host)
43483 + struct mmc_host *host = card->host;
43489 + if (host->chip_alive)
43490 + host->chip_alive = 0;
43498 + mmc_power_cycle(host, host->card->ocr);
43501 + mmc_set_clock(host, host->f_min);
43509 + err = -EINVAL;
43526 diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
43528 --- a/drivers/mmc/host/Makefile
43530 @@ -61,6 +61,7 @@ obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o
43531 obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
43532 obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
43533 obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
43534 +obj-$(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE) += ../../$(VENDOR_DRIVER_DIR)/mmc/host/
43535 obj-$(CONFIG_MMC_DW_ZX) += dw_mmc-zx.o
43536 obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
43537 obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
43538 diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
43540 --- a/drivers/mmc/host/dw_mmc-rockchip.c
43541 +++ b/drivers/mmc/host/dw_mmc-rockchip.c
43542 @@ -22,6 +22,9 @@ struct dw_mci_rockchip_priv_data {
43552 @@ -43,6 +46,9 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
43554 * DDR52 8-bit mode.
43556 + if (ios->clock < priv->f_min)
43557 + ios->clock = priv->f_min;
43559 if (ios->bus_width == MMC_BUS_WIDTH_8 &&
43560 ios->timing == MMC_TIMING_MMC_DDR52)
43561 cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
43562 @@ -61,7 +67,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
43566 - if (!IS_ERR(priv->sample_clk))
43567 + if (!IS_ERR(priv->sample_clk) && ios->timing <= MMC_TIMING_SD_HS)
43568 clk_set_phase(priv->sample_clk, priv->default_sample_phase);
43571 @@ -132,6 +138,42 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
43577 + struct dw_mci *host = slot->host;
43578 + struct dw_mci_rockchip_priv_data *priv = host->priv;
43579 + struct mmc_host *mmc = slot->mmc;
43586 + i = clk_get_phase(priv->sample_clk) / 90 - 1;
43592 + if (degrees[i] == priv->last_degree)
43595 + clk_set_phase(priv->sample_clk, degrees[i]);
43601 + dev_warn(host->dev, "All phases bad!");
43602 + return -EIO;
43606 + dev_info(host->dev, "Successfully tuned phase to %d\n", degrees[i]);
43607 + priv->last_degree = degrees[i];
43613 struct dw_mci *host = slot->host;
43614 @@ -155,6 +197,13 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
43615 return -EIO;
43618 + if (priv->use_v2_tuning) {
43625 ranges = kmalloc_array(priv->num_phases / 2 + 1,
43628 @@ -267,6 +316,17 @@ static int dw_mci_rk3288_parse_dt(struct dw_mci *host)
43630 return -ENOMEM;
43637 + if (of_device_is_compatible(host->dev->of_node,
43638 + "rockchip,rk3568-dw-mshc"))
43639 + priv->f_min = 375000;
43641 + priv->f_min = 100000;
43643 if (of_property_read_u32(np, "rockchip,desired-num-phases",
43644 &priv->num_phases))
43645 priv->num_phases = 360;
43646 @@ -275,6 +335,9 @@ static int dw_mci_rk3288_parse_dt(struct dw_mci *host)
43647 &priv->default_sample_phase))
43648 priv->default_sample_phase = 0;
43650 + if (of_property_read_bool(np, "rockchip,use-v2-tuning"))
43651 + priv->use_v2_tuning = true;
43653 priv->drv_clk = devm_clk_get(host->dev, "ciu-drive");
43654 if (IS_ERR(priv->drv_clk))
43655 dev_dbg(host->dev, "ciu-drive not available\n");
43656 @@ -297,6 +360,7 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
43657 "rockchip,rk3288-dw-mshc"))
43658 host->bus_hz /= RK3288_CLKGEN_DIV;
43660 + host->need_xfer_timer = true;
43664 @@ -335,28 +399,43 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
43670 if (!pdev->dev.of_node)
43671 return -ENODEV;
43673 + if (!device_property_read_bool(&pdev->dev, "non-removable") &&
43674 + !device_property_read_bool(&pdev->dev, "cd-gpios"))
43677 match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
43678 drv_data = match->data;
43684 pm_runtime_get_noresume(&pdev->dev);
43685 - pm_runtime_set_active(&pdev->dev);
43686 - pm_runtime_enable(&pdev->dev);
43687 - pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
43688 - pm_runtime_use_autosuspend(&pdev->dev);
43691 + pm_runtime_set_active(&pdev->dev);
43692 + pm_runtime_enable(&pdev->dev);
43693 + pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
43694 + pm_runtime_use_autosuspend(&pdev->dev);
43699 - pm_runtime_disable(&pdev->dev);
43700 - pm_runtime_set_suspended(&pdev->dev);
43702 + pm_runtime_disable(&pdev->dev);
43703 + pm_runtime_set_suspended(&pdev->dev);
43705 pm_runtime_put_noidle(&pdev->dev);
43709 - pm_runtime_put_autosuspend(&pdev->dev);
43711 + pm_runtime_put_autosuspend(&pdev->dev);
43715 diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
43717 --- a/drivers/mmc/host/dw_mmc.h
43719 @@ -230,6 +230,8 @@ struct dw_mci {
43728 diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
43730 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
43731 +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
43732 @@ -9,9 +9,12 @@
43735 #include <linux/dma-mapping.h>
43744 #include "sdhci-pltfm.h"
43745 @@ -21,11 +24,47 @@
43781 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
43793 @@ -100,6 +139,104 @@ static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
43804 + if (ios->enhanced_strobe)
43819 + host->mmc->actual_clock = 0;
43829 + err = clk_set_rate(pltfm_host->clk, clock);
43831 + dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock);
43867 + err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0,
43871 + dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n");
43876 + 0x2 << 17 | /* pre-change delay */
43877 + 0x3 << 19; /* post-change delay */
43880 + if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
43881 + host->mmc->ios.timing == MMC_TIMING_MMC_HS400)
43882 + txclk_tapnum = priv->txclk_tapnum;
43898 @@ -109,21 +246,89 @@ static const struct sdhci_ops sdhci_dwcmshc_ops = {
43929 + priv->rockchip_clks[0].id = "axi";
43930 + priv->rockchip_clks[1].id = "block";
43931 + priv->rockchip_clks[2].id = "timer";
43932 + err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), ROCKCHIP_MAX_CLKS,
43933 + priv->rockchip_clks);
43935 + dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err);
43939 + err = clk_bulk_prepare_enable(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
43941 + dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err);
43945 + if (of_property_read_u32(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum",
43946 + &priv->txclk_tapnum))
43947 + priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT;
43959 + .compatible = "snps,dwcmshc-sdhci",
43963 + .compatible = "rockchip,dwcmshc-sdhci",
43978 - host = sdhci_pltfm_init(pdev, &sdhci_dwcmshc_pdata,
43979 + pltfm_data = of_device_get_match_data(&pdev->dev);
43981 + dev_err(&pdev->dev, "Error: No device match data found\n");
43982 + return -ENODEV;
43989 @@ -160,16 +365,32 @@ static int dwcmshc_probe(struct platform_device *pdev)
43992 host->mmc_host_ops.request = dwcmshc_request;
43993 + host->mmc_host_ops.hs400_enhanced_strobe =
44006 + pm_runtime_get_noresume(&pdev->dev);
44007 + pm_runtime_set_active(&pdev->dev);
44008 + pm_runtime_enable(&pdev->dev);
44009 + pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
44010 + pm_runtime_use_autosuspend(&pdev->dev);
44011 + pm_runtime_put_autosuspend(&pdev->dev);
44016 clk_disable_unprepare(pltfm_host->clk);
44017 clk_disable_unprepare(priv->bus_clk);
44018 + clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
44022 @@ -185,6 +406,7 @@ static int dwcmshc_remove(struct platform_device *pdev)
44024 clk_disable_unprepare(pltfm_host->clk);
44025 clk_disable_unprepare(priv->bus_clk);
44026 + clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
44030 @@ -207,6 +429,7 @@ static int dwcmshc_suspend(struct device *dev)
44031 if (!IS_ERR(priv->bus_clk))
44032 clk_disable_unprepare(priv->bus_clk);
44034 + clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
44038 @@ -227,15 +450,40 @@ static int dwcmshc_resume(struct device *dev)
44042 + ret = clk_bulk_prepare_enable(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
44048 -#endif
44050 -static SIMPLE_DEV_PM_OPS(dwcmshc_pmops, dwcmshc_suspend, dwcmshc_resume);
44057 -static const struct of_device_id sdhci_dwcmshc_dt_ids[] = {
44058 - { .compatible = "snps,dwcmshc-sdhci" },
44059 - {}
44060 + priv->actual_clk = host->mmc->actual_clock;
44072 + sdhci_set_clock(host, priv->actual_clk);
44084 diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Mak…
44086 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
44088 @@ -19,7 +19,8 @@ obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
44089 obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
44090 obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
44091 obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
44092 -obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
44093 +obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rockchip.o
44094 +dwmac-rockchip-objs := dwmac-rk.o dwmac-rk-tool.o
44095 obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
44096 obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
44097 obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
44098 diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/d…
44100 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
44101 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
44102 @@ -11,6 +11,7 @@
44110 @@ -22,22 +23,30 @@
44114 -
44117 +#include "dwmac-rk-tool.h"
44142 @@ -56,6 +65,7 @@ struct rk_priv_data {
44150 @@ -63,8 +73,132 @@ struct rk_priv_data {
44182 + (((x) == 0) ? SR_MII_BASE : (SR_MII1_BASE + ((x) - 1) * 0x10000)); \
44190 + ret = regmap_read(bsp_priv->xpcs,
44203 + return regmap_write(bsp_priv->xpcs,
44218 + } while (ret & MDIO_CTRL1_RESET && --retries);
44220 + return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
44237 + int ret, i, id = bsp_priv->bus_id;
44245 + dev_err(&bsp_priv->pdev->dev, "xpcs_soft_reset fail %d\n", ret);
44283 @@ -72,8 +206,16 @@ struct rk_priv_data {
44286 #define DELAY_ENABLE(soc, tx, rx) \
44287 - (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
44288 - ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
44289 + ((((tx) >= 0) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
44292 +#define DELAY_ENABLE_BY_ID(soc, tx, rx, id) \
44293 + ((((tx) >= 0) ? soc##_GMAC_TXCLK_DLY_ENABLE(id) : soc##_GMAC_TXCLK_DLY_DISABLE(id)) | \
44296 +#define DELAY_VALUE(soc, tx, rx) \
44297 + ((((tx) >= 0) ? soc##_GMAC_CLK_TX_DL_CFG(tx) : 0) | \
44302 @@ -133,6 +275,127 @@ static const struct rk_gmac_ops px30_ops = {
44330 + struct device *dev = &bsp_priv->pdev->dev;
44332 + if (IS_ERR(bsp_priv->grf)) {
44337 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44341 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON0,
44347 + struct device *dev = &bsp_priv->pdev->dev;
44349 + if (IS_ERR(bsp_priv->grf)) {
44354 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44360 + struct device *dev = &bsp_priv->pdev->dev;
44363 + if (IS_ERR(bsp_priv->grf)) {
44369 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
44374 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
44379 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 125000000);
44390 + struct device *dev = &bsp_priv->pdev->dev;
44393 + if (IS_ERR(bsp_priv->clk_mac_speed)) {
44399 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44402 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
44407 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44410 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
44430 @@ -176,8 +439,7 @@ static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
44432 regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
44434 - RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
44435 - RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
44440 @@ -293,8 +555,7 @@ static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
44443 regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
44444 - RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
44445 - RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
44450 @@ -414,8 +675,7 @@ static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
44452 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
44454 - RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
44455 - RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
44460 @@ -482,6 +742,64 @@ static const struct rk_gmac_ops rk3288_ops = {
44474 + struct device *dev = &bsp_priv->pdev->dev;
44476 + if (IS_ERR(bsp_priv->grf)) {
44481 + regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
44487 + struct device *dev = &bsp_priv->pdev->dev;
44490 + if (IS_ERR(bsp_priv->clk_mac_speed)) {
44496 + regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
44499 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
44504 + regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
44507 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
44525 @@ -528,12 +846,10 @@ static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
44526 regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
44529 - RK3328_GMAC_RXCLK_DLY_ENABLE |
44530 - RK3328_GMAC_TXCLK_DLY_ENABLE);
44533 regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
44534 - RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
44535 - RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
44540 @@ -658,8 +974,7 @@ static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
44542 regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
44544 - RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
44545 - RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
44550 @@ -769,8 +1084,7 @@ static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
44552 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
44554 - RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
44555 - RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
44560 @@ -880,8 +1194,7 @@ static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
44562 regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
44564 - RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
44565 - RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
44570 @@ -948,6 +1261,283 @@ static const struct rk_gmac_ops rk3399_ops = {
44604 + struct device *dev = &bsp_priv->pdev->dev;
44607 + if (IS_ERR(bsp_priv->grf)) {
44612 + offset_con1 = bsp_priv->bus_id == 1 ? RK3568_GRF_GMAC1_CON1 :
44614 + regmap_write(bsp_priv->grf, offset_con1, RK3568_GMAC_GMII_MODE);
44621 + struct device *dev = &bsp_priv->pdev->dev;
44624 + if (IS_ERR(bsp_priv->grf)) {
44629 + offset_con1 = bsp_priv->bus_id == 1 ? RK3568_GRF_GMAC1_CON1 :
44631 + regmap_write(bsp_priv->grf, offset_con1, RK3568_GMAC_GMII_MODE);
44639 + struct device *dev = &bsp_priv->pdev->dev;
44642 + if (IS_ERR(bsp_priv->grf)) {
44647 + offset_con0 = (bsp_priv->bus_id == 1) ? RK3568_GRF_GMAC1_CON0 :
44649 + offset_con1 = (bsp_priv->bus_id == 1) ? RK3568_GRF_GMAC1_CON1 :
44652 + regmap_write(bsp_priv->grf, offset_con1,
44656 + regmap_write(bsp_priv->grf, offset_con0,
44662 + struct device *dev = &bsp_priv->pdev->dev;
44665 + if (IS_ERR(bsp_priv->grf)) {
44670 + offset_con1 = (bsp_priv->bus_id == 1) ? RK3568_GRF_GMAC1_CON1 :
44673 + regmap_write(bsp_priv->grf, offset_con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
44678 + struct device *dev = &bsp_priv->pdev->dev;
44697 + ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
44756 + struct device *dev = &bsp_priv->pdev->dev;
44757 + u32 offset_con, id = bsp_priv->bus_id;
44759 + if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
44764 + offset_con = bsp_priv->bus_id == 1 ? RK3588_GRF_GMAC_CON9 :
44767 + regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
44770 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
44773 + regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
44776 + regmap_write(bsp_priv->grf, offset_con,
44782 + struct device *dev = &bsp_priv->pdev->dev;
44784 + if (IS_ERR(bsp_priv->php_grf)) {
44789 + regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
44790 + RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->bus_id));
44792 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
44793 + RK3588_GMAC_CLK_RMII_MODE(bsp_priv->bus_id));
44798 + struct device *dev = &bsp_priv->pdev->dev;
44799 + unsigned int val = 0, id = bsp_priv->bus_id;
44803 + if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
44809 + if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
44815 + if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
44824 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
44834 + unsigned int val = input ? RK3588_GMAC_CLK_SELET_IO(bsp_priv->bus_id) :
44835 + RK3588_GMAC_CLK_SELET_CRU(bsp_priv->bus_id);
44837 + val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->bus_id) :
44838 + RK3588_GMAC_CLK_RMII_GATE(bsp_priv->bus_id);
44840 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
44854 @@ -1000,6 +1590,123 @@ static const struct rk_gmac_ops rv1108_ops = {
44885 + struct device *dev = &bsp_priv->pdev->dev;
44887 + if (IS_ERR(bsp_priv->grf)) {
44892 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
44897 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
44900 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
44906 + struct device *dev = &bsp_priv->pdev->dev;
44908 + if (IS_ERR(bsp_priv->grf)) {
44913 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
44919 + struct device *dev = &bsp_priv->pdev->dev;
44938 + ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
44946 + struct device *dev = &bsp_priv->pdev->dev;
44962 + ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
44978 @@ -1090,6 +1797,12 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
44982 + } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_SGMII ||
44983 + bsp_priv->phy_iface == PHY_INTERFACE_MODE_QSGMII) {
44984 + bsp_priv->pclk_xpcs = devm_clk_get(dev, "pclk_xpcs");
44985 + if (IS_ERR(bsp_priv->pclk_xpcs))
44990 bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
44991 @@ -1103,14 +1816,17 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
44992 clk_set_rate(bsp_priv->clk_mac, 50000000);
44995 - if (plat->phy_node && bsp_priv->integrated_phy) {
44996 + if (plat->phy_node) {
44997 bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
44998 - if (IS_ERR(bsp_priv->clk_phy)) {
44999 - ret = PTR_ERR(bsp_priv->clk_phy);
45000 - dev_err(dev, "Cannot get PHY clock: %d\n", ret);
45001 - return -EINVAL;
45003 + if (bsp_priv->integrated_phy) {
45004 + if (IS_ERR(bsp_priv->clk_phy)) {
45005 + ret = PTR_ERR(bsp_priv->clk_phy);
45007 + return -EINVAL;
45009 + clk_set_rate(bsp_priv->clk_phy, 50000000);
45011 - clk_set_rate(bsp_priv->clk_phy, 50000000);
45015 @@ -1151,11 +1867,18 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
45016 if (!IS_ERR(bsp_priv->clk_mac_speed))
45017 clk_prepare_enable(bsp_priv->clk_mac_speed);
45019 + if (!IS_ERR(bsp_priv->pclk_xpcs))
45020 + clk_prepare_enable(bsp_priv->pclk_xpcs);
45022 + if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
45023 + bsp_priv->ops->set_clock_selection(bsp_priv,
45024 + bsp_priv->clock_input, true);
45027 * if (!IS_ERR(bsp_priv->clk_mac))
45028 * clk_prepare_enable(bsp_priv->clk_mac);
45030 - mdelay(5);
45032 bsp_priv->clk_enabled = true;
45035 @@ -1177,6 +1900,12 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
45036 clk_disable_unprepare(bsp_priv->mac_clk_tx);
45038 clk_disable_unprepare(bsp_priv->clk_mac_speed);
45040 + clk_disable_unprepare(bsp_priv->pclk_xpcs);
45042 + if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
45043 + bsp_priv->ops->set_clock_selection(bsp_priv,
45044 + bsp_priv->clock_input, false);
45046 * if (!IS_ERR(bsp_priv->clk_mac))
45047 * clk_disable_unprepare(bsp_priv->clk_mac);
45048 @@ -1188,7 +1917,7 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
45052 -static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
45055 struct regulator *ldo = bsp_priv->regulator;
45057 @@ -1226,6 +1955,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
45059 of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
45060 bsp_priv->ops = ops;
45061 + bsp_priv->bus_id = plat->bus_id;
45063 bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
45064 if (IS_ERR(bsp_priv->regulator)) {
45065 @@ -1252,7 +1982,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
45067 ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
45069 - bsp_priv->tx_delay = 0x30;
45070 + bsp_priv->tx_delay = -1;
45073 bsp_priv->tx_delay);
45074 @@ -1263,7 +1993,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
45076 ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
45078 - bsp_priv->rx_delay = 0x10;
45079 + bsp_priv->rx_delay = -1;
45082 bsp_priv->rx_delay);
45083 @@ -1274,6 +2004,20 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
45085 bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
45087 + bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
45089 + bsp_priv->xpcs = syscon_regmap_lookup_by_phandle(dev->of_node,
45091 + if (!IS_ERR(bsp_priv->xpcs)) {
45094 + comphy = devm_of_phy_get(&pdev->dev, dev->of_node, NULL);
45102 if (plat->phy_node) {
45103 bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
45104 @@ -1307,30 +2051,45 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
45105 switch (bsp_priv->phy_iface) {
45108 - bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
45109 - bsp_priv->rx_delay);
45110 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
45111 + bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
45112 + bsp_priv->rx_delay);
45116 - bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
45117 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
45118 + bsp_priv->ops->set_to_rgmii(bsp_priv, -1, -1);
45122 - bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
45123 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
45124 + bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, -1);
45128 - bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
45129 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
45130 + bsp_priv->ops->set_to_rgmii(bsp_priv, -1, bsp_priv->rx_delay);
45134 - bsp_priv->ops->set_to_rmii(bsp_priv);
45135 + if (bsp_priv->ops && bsp_priv->ops->set_to_rmii)
45136 + bsp_priv->ops->set_to_rmii(bsp_priv);
45140 + if (bsp_priv->ops && bsp_priv->ops->set_to_sgmii)
45141 + bsp_priv->ops->set_to_sgmii(bsp_priv);
45145 + if (bsp_priv->ops && bsp_priv->ops->set_to_qsgmii)
45146 + bsp_priv->ops->set_to_qsgmii(bsp_priv);
45152 - ret = phy_power_on(bsp_priv, true);
45157 @@ -1351,7 +2110,7 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac)
45159 pm_runtime_put_sync(&gmac->pdev->dev);
45161 - phy_power_on(gmac, false);
45166 @@ -1365,16 +2124,96 @@ static void rk_fix_speed(void *priv, unsigned int speed)
45170 - bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
45171 + if (bsp_priv->ops && bsp_priv->ops->set_rgmii_speed)
45172 + bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
45175 - bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
45176 + if (bsp_priv->ops && bsp_priv->ops->set_rmii_speed)
45177 + bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
45183 dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
45190 + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv;
45192 + if (bsp_priv->ops->set_to_rgmii) {
45193 + bsp_priv->ops->set_to_rgmii(bsp_priv, tx_delay, rx_delay);
45194 + bsp_priv->tx_delay = tx_delay;
45195 + bsp_priv->rx_delay = rx_delay;
45203 + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv;
45205 + if (!bsp_priv->ops->set_to_rgmii)
45208 + *tx_delay = bsp_priv->tx_delay;
45209 + *rx_delay = bsp_priv->rx_delay;
45215 + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv;
45217 + return bsp_priv->phy_iface;
45224 + struct device *dev = &bsp_priv->pdev->dev;
45226 + int ret, id = bsp_priv->bus_id;
45265 @@ -1396,8 +2235,11 @@ static int rk_gmac_probe(struct platform_device *pdev)
45269 - plat_dat->has_gmac = true;
45270 + if (!of_device_is_compatible(pdev->dev.of_node, "snps,dwmac-4.20a"))
45271 + plat_dat->has_gmac = true;
45273 plat_dat->fix_mac_speed = rk_fix_speed;
45274 + plat_dat->get_eth_addr = rk_get_eth_addr;
45276 plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
45277 if (IS_ERR(plat_dat->bsp_priv)) {
45278 @@ -1417,6 +2259,10 @@ static int rk_gmac_probe(struct platform_device *pdev)
45282 + ret = dwmac_rk_create_loopback_sysfs(&pdev->dev);
45289 @@ -1433,6 +2279,7 @@ static int rk_gmac_remove(struct platform_device *pdev)
45290 int ret = stmmac_dvr_remove(&pdev->dev);
45293 + dwmac_rk_remove_loopback_sysfs(&pdev->dev);
45297 @@ -1470,14 +2317,19 @@ static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
45300 { .compatible = "rockchip,px30-gmac", .data = &px30_ops },
45301 + { .compatible = "rockchip,rk1808-gmac", .data = &rk1808_ops },
45302 { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
45303 { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
45304 { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
45305 + { .compatible = "rockchip,rk3308-mac", .data = &rk3308_ops },
45306 { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
45307 { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
45308 { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
45309 { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
45310 + { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
45311 + { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
45312 { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
45313 + { .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
45317 diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
45319 --- a/drivers/net/wireless/Kconfig
45321 @@ -48,6 +48,7 @@ source "drivers/net/wireless/st/Kconfig"
45329 diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
45331 --- a/drivers/net/wireless/Makefile
45333 @@ -30,3 +30,4 @@ obj-$(CONFIG_USB_NET_RNDIS_WLAN) += rndis_wlan.o
45334 obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
45336 obj-$(CONFIG_VIRT_WIFI) += virt_wifi.o
45337 +obj-$(CONFIG_WL_ROCKCHIP) += rockchip_wlan/
45338 diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
45340 --- a/drivers/nvmem/core.c
45342 @@ -1665,7 +1665,11 @@ static void __exit nvmem_exit(void)
45354 diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c
45356 --- a/drivers/nvmem/rockchip-efuse.c
45357 +++ b/drivers/nvmem/rockchip-efuse.c
45358 @@ -7,6 +7,7 @@
45362 +#include <linux/clk-provider.h>
45366 @@ -16,7 +17,53 @@
45370 -
45421 @@ -49,9 +96,149 @@
45425 - struct clk *clk;
45479 + mutex_lock(&efuse->mutex);
45481 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45483 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45490 + addr_len = addr_end - addr_start;
45494 + ret = -ENOMEM;
45498 + rk1808_efuse_timing_init(efuse->base);
45500 + while (addr_len--) {
45503 + efuse->base + RK1808_AUTO_CTRL);
45505 + status = readl(efuse->base + RK1808_INT_STATUS);
45507 + ret = -EIO;
45510 + out_value = readl(efuse->base + RK1808_DOUT);
45511 + writel(RK1808_INT_FINISH, efuse->base + RK1808_INT_STATUS);
45518 + rk1808_efuse_timing_deinit(efuse->base);
45521 + rk1808_efuse_timing_deinit(efuse->base);
45522 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45524 + mutex_unlock(&efuse->mutex);
45536 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45538 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45542 + writel(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL);
45544 + while (bytes--) {
45545 + writel(readl(efuse->base + REG_EFUSE_CTRL) &
45547 + efuse->base + REG_EFUSE_CTRL);
45548 + writel(readl(efuse->base + REG_EFUSE_CTRL) |
45550 + efuse->base + REG_EFUSE_CTRL);
45552 + writel(readl(efuse->base + REG_EFUSE_CTRL) |
45553 + RK3288_STROBE, efuse->base + REG_EFUSE_CTRL);
45555 + *buf++ = readb(efuse->base + REG_EFUSE_DOUT);
45556 + writel(readl(efuse->base + REG_EFUSE_CTRL) &
45557 + (~RK3288_STROBE), efuse->base + REG_EFUSE_CTRL);
45562 + writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL);
45564 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45572 @@ -59,7 +246,7 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
45576 - ret = clk_prepare_enable(efuse->clk);
45577 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45579 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45581 @@ -87,7 +274,53 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
45583 writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL);
45585 - clk_disable_unprepare(efuse->clk);
45586 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45600 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45602 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45606 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45609 + while (bytes--) {
45610 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45612 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45613 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45615 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45617 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45619 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45621 + *buf++ = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_DOUT);
45622 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45624 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45629 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45632 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45636 @@ -101,7 +334,7 @@ static int rockchip_rk3328_efuse_read(void *context, unsigned int offset,
45640 - ret = clk_prepare_enable(efuse->clk);
45641 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45643 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45645 @@ -142,11 +375,56 @@ static int rockchip_rk3328_efuse_read(void *context, unsigned int offset,
45649 - clk_disable_unprepare(efuse->clk);
45650 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45663 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45665 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45669 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45672 + while (bytes--) {
45673 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45675 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45676 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45678 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45680 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45682 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45684 + *buf++ = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_DOUT);
45685 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45687 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45692 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45695 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45703 @@ -156,7 +434,7 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
45707 - ret = clk_prepare_enable(efuse->clk);
45708 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45710 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45712 @@ -170,8 +448,8 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
45716 - clk_disable_unprepare(efuse->clk);
45717 - return -ENOMEM;
45718 + ret = -ENOMEM;
45723 @@ -198,9 +476,10 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
45727 - clk_disable_unprepare(efuse->clk);
45729 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45731 - return 0;
45736 @@ -212,6 +491,10 @@ static struct nvmem_config econfig = {
45741 + .compatible = "rockchip,rk1808-efuse",
45745 .compatible = "rockchip,rockchip-efuse",
45747 @@ -220,6 +503,10 @@ static const struct of_device_id rockchip_efuse_match[] = {
45748 .compatible = "rockchip,rk3066a-efuse",
45752 + .compatible = "rockchip,rk3128-efuse",
45756 .compatible = "rockchip,rk3188-efuse",
45758 @@ -233,13 +520,17 @@ static const struct of_device_id rockchip_efuse_match[] = {
45762 - .compatible = "rockchip,rk3368-efuse",
45763 - .data = (void *)&rockchip_rk3288_efuse_read,
45764 + .compatible = "rockchip,rk3288-secure-efuse",
45768 .compatible = "rockchip,rk3328-efuse",
45772 + .compatible = "rockchip,rk3368-efuse",
45776 .compatible = "rockchip,rk3399-efuse",
45778 @@ -268,13 +559,16 @@ static int rockchip_efuse_probe(struct platform_device *pdev)
45779 return -ENOMEM;
45782 + efuse->phys = res->start;
45783 efuse->base = devm_ioremap_resource(dev, res);
45784 if (IS_ERR(efuse->base))
45785 return PTR_ERR(efuse->base);
45787 - efuse->clk = devm_clk_get(dev, "pclk_efuse");
45788 - if (IS_ERR(efuse->clk))
45789 - return PTR_ERR(efuse->clk);
45790 + efuse->num_clks = devm_clk_bulk_get_all(dev, &efuse->clks);
45791 + if (efuse->num_clks < 1)
45792 + return -ENODEV;
45794 + mutex_init(&efuse->mutex);
45796 efuse->dev = dev;
45797 if (of_property_read_u32(dev->of_node, "rockchip,efuse-size",
45798 @@ -296,6 +590,26 @@ static struct platform_driver rockchip_efuse_driver = {
45802 -module_platform_driver(rockchip_efuse_driver);
45826 diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
45828 --- a/drivers/nvmem/rockchip-otp.c
45829 +++ b/drivers/nvmem/rockchip-otp.c
45830 @@ -263,6 +263,26 @@ static struct platform_driver rockchip_otp_driver = {
45834 -module_platform_driver(rockchip_otp_driver);
45858 diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
45860 --- a/drivers/opp/debugfs.c
45862 @@ -239,11 +239,55 @@ void opp_debug_unregister(struct opp_device *opp_dev,
45863 opp_dev->dentry = NULL;
45868 + struct list_head *lists = (struct list_head *)s->private;
45875 + seq_puts(s, "-------------------------------------------------------------------\n");
45878 + seq_printf(s, " %s\n", opp_table->dentry_name);
45879 + mutex_lock(&opp_table->lock);
45880 + list_for_each_entry(opp, &opp_table->opp_list, node) {
45882 + opp->rate,
45883 + opp->supplies[0].u_volt,
45884 + opp->supplies[0].u_volt_min,
45885 + opp->supplies[0].u_volt_max);
45887 + mutex_unlock(&opp_table->lock);
45897 + return single_open(file, opp_summary_show, inode->i_private);
45918 diff --git a/drivers/opp/of.c b/drivers/opp/of.c
45920 --- a/drivers/opp/of.c
45922 @@ -1328,7 +1328,7 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
45926 - ret = em_dev_register_perf_domain(dev, nr_opp, &em_cb, cpus);
45931 diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
45933 --- a/drivers/pci/controller/Makefile
45935 @@ -23,9 +23,9 @@ obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
45936 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
45937 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
45938 obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
45939 -obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
45940 -obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o
45941 -obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
45942 +obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o pcie-rockchip.o
45943 +pcierockchiphost-y := pcie-rockchip-host.o pcie-rockchip.o
45944 +obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcierockchiphost.o
45945 obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
45946 obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
45947 obj-$(CONFIG_VMD) += vmd.o
45948 diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
45950 --- a/drivers/pci/controller/dwc/Kconfig
45952 @@ -82,6 +82,15 @@ config PCIE_DW_PLAT_EP
45953 order to enable device-specific features PCI_DW_PLAT_EP must be
45968 diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
45970 --- a/drivers/pci/controller/dwc/Makefile
45972 @@ -20,6 +20,7 @@ obj-$(CONFIG_PCI_MESON) += pci-meson.o
45973 obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
45974 obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
45975 obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
45976 +obj-$(CONFIG_PCIE_DW_ROCKCHIP) += ../../../$(VENDOR_DRIVER_DIR)/pci/controller/dwc/
45980 diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designw…
45982 --- a/drivers/pci/controller/dwc/pcie-designware.h
45983 +++ b/drivers/pci/controller/dwc/pcie-designware.h
45984 @@ -42,6 +42,7 @@
45992 diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
45994 --- a/drivers/pci/controller/pcie-rockchip.c
45995 +++ b/drivers/pci/controller/pcie-rockchip.c
45996 @@ -14,6 +14,7 @@
46004 @@ -421,3 +422,7 @@ void rockchip_pcie_cfg_configuration_accesses(
46012 diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
46014 --- a/drivers/phy/rockchip/Kconfig
46016 @@ -2,6 +2,15 @@
46022 + tristate "Rockchip CSI2 D-PHY Driver"
46032 @@ -28,6 +37,14 @@ config PHY_ROCKCHIP_EMMC
46047 @@ -47,6 +64,14 @@ config PHY_ROCKCHIP_INNO_USB2
46062 @@ -56,6 +81,40 @@ config PHY_ROCKCHIP_INNO_DSIDPHY
46067 + tristate "Rockchip MIPI RX D-PHY Driver"
46072 + Enable this to support the Rockchip MIPI D-PHY with Synopsys or Innosilicon IP block.
46103 @@ -65,6 +124,38 @@ config PHY_ROCKCHIP_PCIE
46142 @@ -80,3 +171,12 @@ config PHY_ROCKCHIP_USB
46155 diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
46157 --- a/drivers/phy/rockchip/Makefile
46159 @@ -1,10 +1,20 @@
46160 # SPDX-License-Identifier: GPL-2.0
46161 +obj-$(CONFIG_PHY_ROCKCHIP_CSI2_DPHY) += phy-rockchip-csi2-dphy-hw.o \
46162 + phy-rockchip-csi2-dphy.o
46163 obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
46164 obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0.o
46165 obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
46166 +obj-$(CONFIG_PHY_ROCKCHIP_INNO_COMBPHY) += phy-rockchip-inno-combphy.o
46167 obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
46168 -obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
46169 +obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi-phy.o
46170 obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
46171 +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o
46172 +obj-$(CONFIG_PHY_ROCKCHIP_MIPI_RX) += phy-rockchip-mipi-rx.o
46173 +obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
46174 +obj-$(CONFIG_PHY_ROCKCHIP_NANENG_EDP) += phy-rockchip-naneng-edp.o
46175 +obj-$(CONFIG_PHY_ROCKCHIP_NANENG_USB2) += phy-rockchip-naneng-usb2.o
46176 obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
46177 +obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o
46178 obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
46179 obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
46180 +obj-$(CONFIG_PHY_ROCKCHIP_USBDP) += phy-rockchip-usbdp.o
46181 diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-i…
46183 --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
46184 +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
46185 @@ -83,9 +83,31 @@
46217 @@ -101,20 +123,22 @@
46226 -#define T_HS_ZERO_CNT_MASK GENMASK(5, 0)
46227 -#define T_HS_ZERO_CNT(x) UPDATE(x, 5, 0)
46234 -#define T_HS_EXIT_CNT_MASK GENMASK(4, 0)
46235 -#define T_HS_EXIT_CNT(x) UPDATE(x, 4, 0)
46239 -#define T_CLK_POST_CNT_MASK GENMASK(3, 0)
46240 -#define T_CLK_POST_CNT(x) UPDATE(x, 3, 0)
46246 @@ -128,9 +152,13 @@
46260 @@ -168,6 +196,20 @@
46281 @@ -176,8 +218,9 @@ struct inno_dsidphy {
46285 - enum phy_mode mode;
46292 @@ -188,6 +231,12 @@ struct inno_dsidphy {
46305 @@ -199,6 +248,44 @@ enum {
46350 @@ -216,6 +303,17 @@ static void phy_update_bits(struct inno_dsidphy *inno,
46351 writel(tmp, inno->phy_base + reg);
46359 + orig = readl(inno->host_base + reg);
46362 + writel(tmp, inno->host_base + reg);
46368 @@ -286,39 +384,48 @@ static unsigned long inno_dsidphy_pll_calc_rate(struct inno_dsidphy *inno,
46372 -static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46376 - struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg;
46377 - const struct {
46378 - unsigned long rate;
46379 - u8 hs_prepare;
46380 - u8 clk_lane_hs_zero;
46381 - u8 data_lane_hs_zero;
46382 - u8 hs_trail;
46383 - } timings[] = {
46384 - { 110000000, 0x20, 0x16, 0x02, 0x22},
46385 - { 150000000, 0x06, 0x16, 0x03, 0x45},
46386 - { 200000000, 0x18, 0x17, 0x04, 0x0b},
46387 - { 250000000, 0x05, 0x17, 0x05, 0x16},
46388 - { 300000000, 0x51, 0x18, 0x06, 0x2c},
46389 - { 400000000, 0x64, 0x19, 0x07, 0x33},
46390 - { 500000000, 0x20, 0x1b, 0x07, 0x4e},
46391 - { 600000000, 0x6a, 0x1d, 0x08, 0x3a},
46392 - { 700000000, 0x3e, 0x1e, 0x08, 0x6a},
46393 - { 800000000, 0x21, 0x1f, 0x09, 0x29},
46394 - {1000000000, 0x09, 0x20, 0x09, 0x27},
46395 - };
46396 - u32 t_txbyteclkhs, t_txclkesc;
46397 - u32 txbyteclkhs, txclkesc, esc_clk_div;
46398 - u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait;
46399 - u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero;
46402 + unsigned int lane_mbps = inno->pll.rate / USEC_PER_SEC;
46405 - inno_dsidphy_pll_calc_rate(inno, cfg->hs_clk_rate);
46406 + timings = inno->pdata->inno_mipi_dphy_timing_table;
46407 + num_timings = inno->pdata->num_timings;
46409 - /* Select MIPI mode */
46410 - phy_update_bits(inno, REGISTER_PART_LVDS, 0x03,
46411 - MODE_ENABLE_MASK, MIPI_MODE_ENABLE);
46417 + --i;
46426 + REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv));
46428 + REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv));
46430 + REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv));
46445 REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv));
46446 @@ -330,6 +437,10 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46457 @@ -342,6 +453,17 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46465 + struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg;
46473 txbyteclkhs = inno->pll.rate / 8;
46475 @@ -365,15 +487,6 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46476 * Tclk-pre = Tpin_txbyteclkhs * value
46478 clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
46479 -
46480 - /*
46481 - * The value of counter for HS Tlpx Time
46482 - * Tlpx = Tpin_txbyteclkhs * (2 + value)
46483 - */
46484 - lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs);
46485 - if (lpx >= 2)
46486 - lpx -= 2;
46487 -
46489 * The value of counter for HS Tta-go
46490 * Tta-go for turnaround
46491 @@ -393,17 +506,22 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46493 ta_wait = DIV_ROUND_UP(cfg->ta_get, t_txclkesc);
46495 - for (i = 0; i < ARRAY_SIZE(timings); i++)
46496 - if (inno->pll.rate <= timings[i].rate)
46497 - break;
46498 -
46499 - if (i == ARRAY_SIZE(timings))
46500 - --i;
46501 -
46502 - hs_prepare = timings[i].hs_prepare;
46503 - hs_trail = timings[i].hs_trail;
46504 - clk_lane_hs_zero = timings[i].clk_lane_hs_zero;
46505 - data_lane_hs_zero = timings[i].data_lane_hs_zero;
46511 + if (inno->pdata->max_rate == MAX_1GHZ) {
46512 + lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs);
46514 + lpx -= 2;
46516 + lpx = timing->lpx;
46518 + hs_prepare = timing->hs_prepare;
46519 + hs_trail = timing->hs_trail;
46520 + clk_lane_hs_zero = timing->clk_lane_hs_zero;
46521 + data_lane_hs_zero = timing->data_lane_hs_zero;
46525 @@ -416,14 +534,29 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46529 - phy_update_bits(inno, i, 0x07, T_HS_ZERO_CNT_MASK,
46530 - T_HS_ZERO_CNT(hs_zero));
46532 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46540 - phy_update_bits(inno, i, 0x09, T_HS_EXIT_CNT_MASK,
46541 - T_HS_EXIT_CNT(hs_exit));
46542 - phy_update_bits(inno, i, 0x0a, T_CLK_POST_CNT_MASK,
46543 - T_CLK_POST_CNT(clk_post));
46545 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46552 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46561 @@ -437,11 +570,46 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46567 - /* Enable all lanes on analog part */
46568 - phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00,
46569 - LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 |
46570 - LANE_EN_1 | LANE_EN_0);
46575 + switch (inno->lanes) {
46600 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46612 @@ -451,8 +619,9 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
46616 - SAMPLE_CLOCK_DIRECTION_MASK,
46617 - SAMPLE_CLOCK_DIRECTION_REVERSE);
46624 @@ -472,6 +641,10 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
46635 @@ -491,9 +664,36 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
46670 clk_prepare_enable(inno->pclk_phy);
46671 clk_prepare_enable(inno->ref_clk);
46672 @@ -506,7 +706,7 @@ static int inno_dsidphy_power_on(struct phy *phy)
46676 - switch (inno->mode) {
46681 @@ -514,7 +714,7 @@ static int inno_dsidphy_power_on(struct phy *phy)
46685 - return -EINVAL;
46690 @@ -551,17 +751,6 @@ static int inno_dsidphy_power_off(struct phy *phy)
46694 - struct inno_dsidphy *inno = phy_get_drvdata(phy);
46695 -
46696 - switch (mode) {
46697 - case PHY_MODE_MIPI_DPHY:
46698 - case PHY_MODE_LVDS:
46699 - inno->mode = mode;
46700 - break;
46701 - default:
46702 - return -EINVAL;
46703 - }
46704 -
46708 @@ -569,9 +758,11 @@ static int inno_dsidphy_configure(struct phy *phy,
46712 + struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg;
46716 - if (inno->mode != PHY_MODE_MIPI_DPHY)
46718 return -EINVAL;
46720 ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
46721 @@ -580,6 +771,32 @@ static int inno_dsidphy_configure(struct phy *phy,
46723 memcpy(&inno->dphy_cfg, &opts->mipi_dphy, sizeof(inno->dphy_cfg));
46725 + inno_dsidphy_pll_calc_rate(inno, cfg->hs_clk_rate);
46726 + cfg->hs_clk_rate = inno->pll.rate;
46727 + opts->mipi_dphy.hs_clk_rate = inno->pll.rate;
46736 + clk_prepare_enable(inno->pclk_phy);
46737 + clk_prepare_enable(inno->ref_clk);
46738 + pm_runtime_get_sync(inno->dev);
46747 + pm_runtime_put(inno->dev);
46748 + clk_disable_unprepare(inno->ref_clk);
46749 + clk_disable_unprepare(inno->pclk_phy);
46754 @@ -588,6 +805,8 @@ static const struct phy_ops inno_dsidphy_ops = {
46763 @@ -597,6 +816,7 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46771 @@ -604,12 +824,23 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46772 return -ENOMEM;
46774 inno->dev = dev;
46775 + inno->pdata = of_device_get_match_data(inno->dev);
46778 - inno->phy_base = devm_platform_ioremap_resource(pdev, 0);
46779 + inno->phy_base = devm_platform_ioremap_resource_byname(pdev, "phy");
46780 if (IS_ERR(inno->phy_base))
46781 return PTR_ERR(inno->phy_base);
46786 + return -EINVAL;
46789 + inno->host_base = devm_ioremap(dev, res->start, resource_size(res));
46790 + if (IS_ERR(inno->host_base))
46791 + return PTR_ERR(inno->host_base);
46793 inno->ref_clk = devm_clk_get(dev, "ref");
46794 if (IS_ERR(inno->ref_clk)) {
46795 ret = PTR_ERR(inno->ref_clk);
46796 @@ -624,6 +855,13 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46800 + inno->pclk_host = devm_clk_get(dev, "pclk_host");
46801 + if (IS_ERR(inno->pclk_host)) {
46802 + ret = PTR_ERR(inno->pclk_host);
46807 inno->rst = devm_reset_control_get(dev, "apb");
46808 if (IS_ERR(inno->rst)) {
46809 ret = PTR_ERR(inno->rst);
46810 @@ -638,6 +876,9 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46814 + if (of_property_read_u32(dev->of_node, "inno,lanes", &inno->lanes))
46815 + inno->lanes = 4;
46820 @@ -652,6 +893,18 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46839 @@ -662,9 +915,18 @@ static int inno_dsidphy_remove(struct platform_device *pdev)
46843 - { .compatible = "rockchip,px30-dsi-dphy", },
46844 - { .compatible = "rockchip,rk3128-dsi-dphy", },
46845 - { .compatible = "rockchip,rk3368-dsi-dphy", },
46846 + { .compatible = "rockchip,px30-dsi-dphy",
46849 + .compatible = "rockchip,rk3128-dsi-dphy",
46852 + .compatible = "rockchip,rk3368-dsi-dphy",
46855 + .compatible = "rockchip,rk3568-dsi-dphy",
46861 diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno…
46863 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
46864 +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
46865 @@ -22,15 +22,22 @@
46880 -#define OTG_SCHEDULE_DELAY (2 * HZ)
46889 @@ -69,6 +76,7 @@ enum usb_chg_state {
46897 @@ -95,7 +103,7 @@ struct usb2phy_reg {
46901 - * @opmode: utmi operational mode.
46906 @@ -107,7 +115,7 @@ struct rockchip_chg_det_reg {
46910 - struct usb2phy_reg opmode;
46915 @@ -116,32 +124,81 @@ struct rockchip_chg_det_reg {
46989 * struct rockchip_usb2phy_cfg - usb-phy configuration.
46990 * @reg: the address offset of grf for usb-phy config.
46995 * @port_cfgs: usb-phy port configurations.
46997 @@ -149,6 +206,8 @@ struct rockchip_usb2phy_port_cfg {
47006 @@ -158,16 +217,30 @@ struct rockchip_usb2phy_cfg {
47007 * struct rockchip_usb2phy_port - usb-phy port data.
47014 + * @typec_vbus_det: Type-C otg vbus detect.
47016 + * true - use avalid to get vbus status
47017 + * false - use bvalid to get vbus status
47026 * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
47027 * irqs to one irq in otg-port.
47037 @@ -176,17 +249,30 @@ struct rockchip_usb2phy_cfg {
47068 @@ -196,6 +282,8 @@ struct rockchip_usb2phy_port {
47077 @@ -203,6 +291,12 @@ struct rockchip_usb2phy_port {
47090 @@ -211,12 +305,18 @@ struct rockchip_usb2phy {
47109 @@ -254,6 +354,25 @@ static inline bool property_enabled(struct regmap *base,
47110 return tmp == reg->enable;
47117 + ret = reset_control_assert(rphy->phy_reset);
47123 + ret = reset_control_deassert(rphy->phy_reset);
47135 @@ -319,7 +438,7 @@ static int
47138 struct device_node *node = rphy->dev->of_node;
47139 - struct clk_init_data init;
47144 @@ -393,6 +512,8 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
47145 dev_err(rphy->dev, "failed to register extcon device\n");
47149 + rphy->edev_self = true;
47152 rphy->edev = edev;
47153 @@ -400,6 +521,177 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
47157 +/* The caller must hold rport->mutex lock */
47164 + ret = property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr, true);
47168 + ret = property_enable(rphy->grf, &rport->port_cfg->idfall_det_en, en);
47172 + ret = property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr, true);
47176 + ret = property_enable(rphy->grf, &rport->port_cfg->idrise_det_en, en);
47181 +/* The caller must hold rport->mutex lock */
47188 + ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
47192 + ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_en, en);
47203 + ret = property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
47207 + ret = property_enable(rphy->grf, &rport->port_cfg->ls_det_en, en);
47218 + ret = property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true);
47222 + ret = property_enable(rphy->grf, &rport->port_cfg->disfall_en, en);
47226 + ret = property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true);
47230 + ret = property_enable(rphy->grf, &rport->port_cfg->disrise_en, en);
47238 + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47239 + const struct usb2phy_reg *iomux = &rport->port_cfg->bypass_iomux;
47243 + mutex_lock(&rport->mutex);
47245 + if (en == property_enabled(base, &rport->port_cfg->bypass_sel)) {
47246 + dev_info(&rport->phy->dev,
47251 + dev_info(&rport->phy->dev, "bypass uart %s\n", en ? "on" : "off");
47260 + * in non-driving mode to disable resistance when use USB
47262 + * set phy in non-driving mode, it will cause UART to print
47265 + ret |= property_enable(base, &rport->port_cfg->bypass_sel,
47267 + ret |= property_enable(base, &rport->port_cfg->bypass_dm_en,
47271 + if (iomux->offset)
47272 + ret |= property_enable(rphy->grf, iomux, true);
47275 + ret |= property_enable(base, &rport->port_cfg->bypass_sel,
47277 + ret |= property_enable(base, &rport->port_cfg->bypass_dm_en,
47281 + if (iomux->offset)
47282 + ret |= property_enable(rphy->grf, iomux, false);
47286 + mutex_unlock(&rport->mutex);
47296 + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47300 + mutex_lock(&rport->mutex);
47302 + iddig = property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig);
47304 + if (rport->utmi_avalid)
47305 + vbus = property_enabled(rphy->grf, &rport->port_cfg->utmi_avalid);
47307 + vbus = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
47309 + mutex_unlock(&rport->mutex);
47320 + dev_warn(&rport->phy->dev,
47323 + schedule_delayed_work(&rport->bypass_uart_work,
47331 @@ -408,39 +700,50 @@ static int rockchip_usb2phy_init(struct phy *phy)
47333 mutex_lock(&rport->mutex);
47335 - if (rport->port_id == USB2PHY_PORT_OTG) {
47336 - if (rport->mode != USB_DR_MODE_HOST &&
47337 - rport->mode != USB_DR_MODE_UNKNOWN) {
47338 - /* clear bvalid status and enable bvalid detect irq */
47339 - ret = property_enable(rphy->grf,
47340 - &rport->port_cfg->bvalid_det_clr,
47341 - true);
47342 - if (ret)
47343 + if (rport->port_id == USB2PHY_PORT_OTG &&
47344 + (rport->mode == USB_DR_MODE_PERIPHERAL ||
47345 + rport->mode == USB_DR_MODE_OTG)) {
47347 + if (rport->id_irq > 0 || rport->otg_mux_irq > 0 ||
47348 + rphy->irq > 0) {
47352 + dev_err(rphy->dev,
47358 - ret = property_enable(rphy->grf,
47359 - &rport->port_cfg->bvalid_det_en,
47360 - true);
47361 - if (ret)
47363 + if ((rport->bvalid_irq > 0 || rport->otg_mux_irq > 0 ||
47364 + rphy->irq > 0) && !rport->vbus_always_on) {
47368 + dev_err(rphy->dev,
47373 - schedule_delayed_work(&rport->otg_sm_work,
47374 - OTG_SCHEDULE_DELAY * 3);
47375 - } else {
47376 - /* If OTG works in host only mode, do nothing. */
47377 - dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
47378 + schedule_delayed_work(&rport->otg_sm_work, 0);
47380 } else if (rport->port_id == USB2PHY_PORT_HOST) {
47381 - /* clear linestate and enable linestate detect irq */
47382 - ret = property_enable(rphy->grf,
47383 - &rport->port_cfg->ls_det_clr, true);
47384 - if (ret)
47385 - goto out;
47386 + if (rport->port_cfg->disfall_en.offset) {
47387 + rport->host_disconnect = true;
47390 + dev_err(rphy->dev, "failed to enable disconnect irq\n");
47395 - ret = property_enable(rphy->grf,
47396 - &rport->port_cfg->ls_det_en, true);
47397 - if (ret)
47401 + dev_err(rphy->dev, "failed to enable linestate irq\n");
47405 schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
47407 @@ -459,22 +762,56 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
47409 dev_dbg(&rport->phy->dev, "port power on\n");
47411 - if (!rport->suspended)
47412 - return 0;
47413 + if (rport->bypass_uart_en) {
47416 + dev_warn(&rport->phy->dev,
47422 + mutex_lock(&rport->mutex);
47424 + if (!rport->suspended) {
47429 ret = clk_prepare_enable(rphy->clk480m);
47431 - return ret;
47434 ret = property_enable(base, &rport->port_cfg->phy_sus, false);
47436 - return ret;
47454 rport->suspended = false;
47455 - return 0;
47458 + mutex_unlock(&rport->mutex);
47461 + if (rport->bypass_uart_en)
47462 + schedule_delayed_work(&rport->bypass_uart_work, 0);
47469 @@ -486,42 +823,258 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
47471 dev_dbg(&rport->phy->dev, "port power off\n");
47473 - if (rport->suspended)
47474 - return 0;
47475 + mutex_lock(&rport->mutex);
47477 + if (rport->suspended) {
47482 ret = property_enable(base, &rport->port_cfg->phy_sus, true);
47484 - return ret;
47487 rport->suspended = true;
47488 clk_disable_unprepare(rphy->clk480m);
47490 - return 0;
47492 + mutex_unlock(&rport->mutex);
47495 + if (rport->bypass_uart_en)
47496 + schedule_delayed_work(&rport->bypass_uart_work, 0);
47505 - if (rport->port_id == USB2PHY_PORT_OTG &&
47506 - rport->mode != USB_DR_MODE_HOST &&
47507 - rport->mode != USB_DR_MODE_UNKNOWN) {
47508 - cancel_delayed_work_sync(&rport->otg_sm_work);
47509 - cancel_delayed_work_sync(&rport->chg_work);
47510 - } else if (rport->port_id == USB2PHY_PORT_HOST)
47511 + if (rport->port_id == USB2PHY_PORT_HOST)
47512 cancel_delayed_work_sync(&rport->sm_work);
47513 + else if (rport->port_id == USB2PHY_PORT_OTG &&
47514 + rport->bvalid_irq > 0)
47515 + flush_delayed_work(&rport->otg_sm_work);
47525 + if (!rport->vbus)
47528 + if (en && !rport->vbus_enabled) {
47529 + ret = regulator_enable(rport->vbus);
47531 + dev_err(&rport->phy->dev,
47533 + } else if (!en && rport->vbus_enabled) {
47534 + ret = regulator_disable(rport->vbus);
47538 + rport->vbus_enabled = en;
47547 + struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
47551 + if (rport->port_id != USB2PHY_PORT_OTG)
47564 + extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, false);
47566 + extcon_set_state(rphy->edev, EXTCON_USB, true);
47567 + rport->perip_connected = true;
47574 + dev_err(&rport->phy->dev,
47579 + extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, true);
47581 + extcon_set_state(rphy->edev, EXTCON_USB, false);
47582 + rport->perip_connected = false;
47588 + dev_info(&rport->phy->dev, "illegal mode\n");
47592 + if (rphy->phy_cfg->vbus_detect)
47593 + rphy->phy_cfg->vbus_detect(rphy, vbus_det_en);
47595 + ret = property_enable(rphy->grf, &rport->port_cfg->vbus_det_en,
47619 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
47620 + rport = &rphy->ports[index];
47621 + if (rport->port_id == USB2PHY_PORT_OTG)
47626 + dev_err(rphy->dev, "Fail to get otg port\n");
47627 + return -EINVAL;
47628 + } else if (rport->port_id != USB2PHY_PORT_OTG) {
47629 + dev_err(rphy->dev, "No support otg\n");
47630 + return -EINVAL;
47633 + switch (rport->mode) {
47644 + return -EINVAL;
47658 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
47659 + rport = &rphy->ports[index];
47660 + if (rport->port_id == USB2PHY_PORT_OTG)
47665 + dev_err(rphy->dev, "Fail to get otg port\n");
47666 + rc = -EINVAL;
47668 + } else if (rport->port_id != USB2PHY_PORT_OTG ||
47669 + rport->mode == USB_DR_MODE_UNKNOWN) {
47670 + dev_err(rphy->dev, "No support otg\n");
47671 + rc = -EINVAL;
47675 + mutex_lock(&rport->mutex);
47684 + dev_err(rphy->dev, "Error mode! Input 'otg' or 'host' or 'peripheral'\n");
47685 + rc = -EINVAL;
47689 + if (rport->mode == new_dr_mode) {
47690 + dev_warn(rphy->dev, "Same as current mode\n");
47694 + rport->mode = new_dr_mode;
47696 + switch (rport->mode) {
47698 + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST, 0);
47699 + property_enable(base, &rport->port_cfg->iddig_output, false);
47700 + property_enable(base, &rport->port_cfg->iddig_en, true);
47703 + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_DEVICE, 0);
47704 + property_enable(base, &rport->port_cfg->iddig_output, true);
47705 + property_enable(base, &rport->port_cfg->iddig_en, true);
47708 + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_OTG, 0);
47709 + property_enable(base, &rport->port_cfg->iddig_output, false);
47710 + property_enable(base, &rport->port_cfg->iddig_en, false);
47717 + mutex_unlock(&rport->mutex);
47738 @@ -530,59 +1083,80 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
47739 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47742 - bool vbus_attach, sch_work, notify_charger;
47745 + mutex_lock(&rport->mutex);
47747 - vbus_attach = property_enabled(rphy->grf,
47748 - &rport->port_cfg->utmi_bvalid);
47749 + if (rport->port_cfg->bvalid_grf_con.enable && rport->typec_vbus_det)
47750 + rport->vbus_attached =
47751 + property_enabled(rphy->grf, &rport->port_cfg->bvalid_grf_con);
47752 + else if (rport->utmi_avalid)
47753 + rport->vbus_attached =
47754 + property_enabled(rphy->grf, &rport->port_cfg->utmi_avalid);
47756 + rport->vbus_attached =
47757 + property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
47760 - notify_charger = false;
47763 dev_dbg(&rport->phy->dev, "%s otg sm work\n",
47764 usb_otg_state_string(rport->state));
47766 switch (rport->state) {
47768 rport->state = OTG_STATE_B_IDLE;
47769 - if (!vbus_attach)
47770 + if (!rport->vbus_attached) {
47771 + mutex_unlock(&rport->mutex);
47772 rockchip_usb2phy_power_off(rport->phy);
47773 + mutex_lock(&rport->mutex);
47777 - if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
47778 + if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0 ||
47779 + extcon_get_state(rphy->edev, EXTCON_USB_VBUS_EN) > 0) {
47780 dev_dbg(&rport->phy->dev, "usb otg host connect\n");
47781 rport->state = OTG_STATE_A_HOST;
47782 + rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47783 + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47784 + mutex_unlock(&rport->mutex);
47785 rockchip_usb2phy_power_on(rport->phy);
47787 - } else if (vbus_attach) {
47788 + } else if (rport->vbus_attached) {
47789 dev_dbg(&rport->phy->dev, "vbus_attach\n");
47790 switch (rphy->chg_state) {
47792 + mutex_unlock(&rport->mutex);
47793 schedule_delayed_work(&rport->chg_work, 0);
47796 switch (rphy->chg_type) {
47798 dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
47799 + wake_lock(&rport->wakelock);
47801 + mutex_unlock(&rport->mutex);
47802 rockchip_usb2phy_power_on(rport->phy);
47803 + mutex_lock(&rport->mutex);
47804 rport->state = OTG_STATE_B_PERIPHERAL;
47805 - notify_charger = true;
47806 + rport->perip_connected = true;
47808 - cable = EXTCON_CHG_USB_SDP;
47811 dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
47812 - rockchip_usb2phy_power_off(rport->phy);
47813 - notify_charger = true;
47814 - sch_work = true;
47819 dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
47820 + wake_lock(&rport->wakelock);
47822 + mutex_unlock(&rport->mutex);
47823 rockchip_usb2phy_power_on(rport->phy);
47824 + mutex_lock(&rport->mutex);
47825 rport->state = OTG_STATE_B_PERIPHERAL;
47826 - notify_charger = true;
47827 + rport->perip_connected = true;
47829 - cable = EXTCON_CHG_USB_CDP;
47833 @@ -592,32 +1166,34 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
47837 - notify_charger = true;
47838 rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47839 rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47840 - }
47841 -
47842 - if (rport->vbus_attached != vbus_attach) {
47843 - rport->vbus_attached = vbus_attach;
47844 -
47845 - if (notify_charger && rphy->edev) {
47846 - extcon_set_state_sync(rphy->edev,
47847 - cable, vbus_attach);
47848 - if (cable == EXTCON_CHG_USB_SDP)
47849 - extcon_set_state_sync(rphy->edev,
47850 - EXTCON_USB,
47851 - vbus_attach);
47852 - }
47853 + mutex_unlock(&rport->mutex);
47854 + rockchip_usb2phy_power_off(rport->phy);
47855 + mutex_lock(&rport->mutex);
47859 - if (!vbus_attach) {
47860 - dev_dbg(&rport->phy->dev, "usb disconnect\n");
47863 + if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0 ||
47864 + extcon_get_state(rphy->edev,
47866 + dev_dbg(&rport->phy->dev, "usb otg host connect\n");
47867 + rport->state = OTG_STATE_A_HOST;
47868 rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47869 rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47870 + rport->perip_connected = false;
47872 + wake_unlock(&rport->wakelock);
47873 + } else if (!rport->vbus_attached) {
47874 + dev_dbg(&rport->phy->dev, "usb disconnect\n");
47875 rport->state = OTG_STATE_B_IDLE;
47876 - delay = 0;
47877 - rockchip_usb2phy_power_off(rport->phy);
47878 + rport->perip_connected = false;
47879 + rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47880 + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47882 + wake_unlock(&rport->wakelock);
47886 @@ -625,15 +1201,47 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
47887 if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
47888 dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
47889 rport->state = OTG_STATE_B_IDLE;
47890 - rockchip_usb2phy_power_off(rport->phy);
47893 + mutex_unlock(&rport->mutex);
47898 - break;
47899 + mutex_unlock(&rport->mutex);
47903 + if (extcon_get_state(rphy->edev, cable) != rport->vbus_attached) {
47904 + extcon_set_state_sync(rphy->edev,
47905 + cable, rport->vbus_attached);
47907 + if (!rport->vbus_attached)
47909 + } else if (rport->state == OTG_STATE_A_HOST &&
47910 + extcon_get_state(rphy->edev, cable)) {
47914 + * in high, so the rport->vbus_attached may not be
47917 + extcon_set_state_sync(rphy->edev, cable, false);
47921 + if (rphy->edev_self &&
47922 + (extcon_get_state(rphy->edev, EXTCON_USB) !=
47923 + rport->perip_connected)) {
47924 + extcon_set_state_sync(rphy->edev,
47926 + rport->perip_connected);
47927 + extcon_sync(rphy->edev, EXTCON_USB_HOST);
47930 schedule_delayed_work(&rport->otg_sm_work, delay);
47932 + mutex_unlock(&rport->mutex);
47936 @@ -687,21 +1295,45 @@ static void rockchip_chg_detect_work(struct work_struct *work)
47938 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47946 dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
47947 rphy->chg_state);
47952 + * 2. Set the utmi_opmode in non-driving mode.
47957 switch (rphy->chg_state) {
47959 - if (!rport->suspended)
47960 - rockchip_usb2phy_power_off(rport->phy);
47961 - /* put the controller in non-driving mode */
47962 - property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
47963 + mutex_lock(&rport->mutex);
47965 + phy_sus_reg = &rport->port_cfg->phy_sus;
47966 + ret = regmap_read(base, phy_sus_reg->offset,
47967 + &rphy->phy_sus_cfg);
47969 + dev_err(&rport->phy->dev,
47971 + phy_sus_reg->offset, ret);
47972 + mutex_unlock(&rport->mutex);
47977 + property_enable(base, &rphy->phy_cfg->chg_det.chg_mode, true);
47980 rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
47981 rphy->dcd_retries = 0;
47982 + rphy->primary_retries = 0;
47986 @@ -739,6 +1371,19 @@ static void rockchip_chg_detect_work(struct work_struct *work)
47987 rphy->chg_state = USB_CHG_STATE_DETECTED;
47990 + if (rphy->primary_retries < 2) {
47997 + rphy->chg_state =
47999 + rphy->primary_retries++;
48003 rphy->chg_type = POWER_SUPPLY_TYPE_USB;
48004 rphy->chg_state = USB_CHG_STATE_DETECTED;
48006 @@ -757,19 +1402,36 @@ static void rockchip_chg_detect_work(struct work_struct *work)
48009 rphy->chg_state = USB_CHG_STATE_DETECTED;
48010 - delay = 0;
48013 - /* put the controller in normal mode */
48014 - property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
48015 + if (rphy->phy_cfg->chg_det.chg_mode.offset !=
48016 + rport->port_cfg->phy_sus.offset)
48017 + property_enable(base, &rphy->phy_cfg->chg_det.chg_mode, false);
48020 + phy_sus_reg = &rport->port_cfg->phy_sus;
48021 + mask = GENMASK(phy_sus_reg->bitend, phy_sus_reg->bitstart);
48022 + ret = regmap_write(base, phy_sus_reg->offset,
48023 + (rphy->phy_sus_cfg | (mask << BIT_WRITEABLE_SHIFT)));
48025 + dev_err(&rport->phy->dev,
48027 + phy_sus_reg->offset, ret);
48028 + mutex_unlock(&rport->mutex);
48029 rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
48030 dev_dbg(&rport->phy->dev, "charger = %s\n",
48031 chg_to_string(rphy->chg_type));
48034 + mutex_unlock(&rport->mutex);
48043 schedule_delayed_work(&rport->chg_work, delay);
48046 @@ -791,30 +1453,43 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
48049 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
48050 - unsigned int sh = rport->port_cfg->utmi_hstdet.bitend -
48051 - rport->port_cfg->utmi_hstdet.bitstart + 1;
48052 - unsigned int ul, uhd, state;
48057 + if (!rport->port_cfg->utmi_ls.offset ||
48058 + (!rport->port_cfg->utmi_hstdet.offset &&
48059 + !rport->port_cfg->disfall_en.offset)) {
48060 + dev_dbg(&rport->phy->dev, "some property may not be specified\n");
48064 mutex_lock(&rport->mutex);
48066 ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
48070 - ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
48071 - if (ret < 0)
48072 - goto next_schedule;
48073 -
48074 - uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
48075 - rport->port_cfg->utmi_hstdet.bitstart);
48076 ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
48077 rport->port_cfg->utmi_ls.bitstart);
48079 - /* stitch on utmi_ls and utmi_hstdet as phy state */
48080 - state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
48081 - (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
48082 + if (rport->port_cfg->utmi_hstdet.offset) {
48083 + ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
48087 + uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
48088 + rport->port_cfg->utmi_hstdet.bitstart);
48090 + sh = rport->port_cfg->utmi_hstdet.bitend -
48091 + rport->port_cfg->utmi_hstdet.bitstart + 1;
48093 + state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
48094 + (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
48096 + state = ((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << 1 |
48097 + rport->host_disconnect;
48102 @@ -839,7 +1514,9 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
48104 if (rport->suspended) {
48105 dev_dbg(&rport->phy->dev, "Connected\n");
48106 + mutex_unlock(&rport->mutex);
48107 rockchip_usb2phy_power_on(rport->phy);
48108 + mutex_lock(&rport->mutex);
48109 rport->suspended = false;
48111 /* D+ line pull-up, D- line pull-down */
48112 @@ -849,7 +1526,9 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
48114 if (!rport->suspended) {
48115 dev_dbg(&rport->phy->dev, "Disconnected\n");
48116 + mutex_unlock(&rport->mutex);
48117 rockchip_usb2phy_power_off(rport->phy);
48118 + mutex_lock(&rport->mutex);
48119 rport->suspended = true;
48122 @@ -857,8 +1536,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
48124 * plug-in irq.
48126 - property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
48127 - property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
48132 @@ -867,7 +1545,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
48133 mutex_unlock(&rport->mutex);
48136 - dev_dbg(&rport->phy->dev, "unknown phy state\n");
48137 + dev_dbg(&rport->phy->dev, "unknown phy state %d\n", state);
48141 @@ -884,11 +1562,12 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
48142 if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
48145 + dev_dbg(&rport->phy->dev, "linestate interrupt\n");
48147 mutex_lock(&rport->mutex);
48150 - property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
48151 - property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
48154 mutex_unlock(&rport->mutex);
48156 @@ -918,99 +1597,157 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
48158 mutex_unlock(&rport->mutex);
48160 + if (rport->bypass_uart_en)
48163 + cancel_delayed_work_sync(&rport->otg_sm_work);
48164 rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
48169 -static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
48173 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
48176 - if (property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
48177 - return rockchip_usb2phy_bvalid_irq(irq, data);
48178 - else
48179 + if (!property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st) &&
48180 + !property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st))
48183 + mutex_lock(&rport->mutex);
48186 + if (property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st)) {
48187 + property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr,
48190 + } else if (property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st)) {
48191 + property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr,
48196 + extcon_set_state(rphy->edev, EXTCON_USB_HOST, cable_vbus_state);
48197 + extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, cable_vbus_state);
48199 + extcon_sync(rphy->edev, EXTCON_USB_HOST);
48200 + extcon_sync(rphy->edev, EXTCON_USB_VBUS_EN);
48204 + mutex_unlock(&rport->mutex);
48209 -static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
48210 - struct rockchip_usb2phy_port *rport,
48211 - struct device_node *child_np)
48214 - int ret;
48216 + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
48218 - rport->port_id = USB2PHY_PORT_HOST;
48219 - rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
48220 - rport->suspended = true;
48221 + if (!property_enabled(rphy->grf, &rport->port_cfg->disfall_st) &&
48222 + !property_enabled(rphy->grf, &rport->port_cfg->disrise_st))
48225 - mutex_init(&rport->mutex);
48226 - INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
48227 + mutex_lock(&rport->mutex);
48229 - rport->ls_irq = of_irq_get_byname(child_np, "linestate");
48230 - if (rport->ls_irq < 0) {
48231 - dev_err(rphy->dev, "no linestate irq provided\n");
48232 - return rport->ls_irq;
48234 + if (property_enabled(rphy->grf, &rport->port_cfg->disfall_st)) {
48235 + property_enable(rphy->grf, &rport->port_cfg->disfall_clr,
48237 + rport->host_disconnect = false;
48238 + } else if (property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) {
48239 + property_enable(rphy->grf, &rport->port_cfg->disrise_clr,
48241 + rport->host_disconnect = true;
48244 - ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
48245 - rockchip_usb2phy_linestate_irq,
48246 - IRQF_ONESHOT,
48247 - "rockchip_usb2phy", rport);
48248 - if (ret) {
48249 - dev_err(rphy->dev, "failed to request linestate irq handle\n");
48250 - return ret;
48251 - }
48252 + mutex_unlock(&rport->mutex);
48254 - return 0;
48258 -static int rockchip_otg_event(struct notifier_block *nb,
48259 - unsigned long event, void *ptr)
48262 - struct rockchip_usb2phy_port *rport =
48263 - container_of(nb, struct rockchip_usb2phy_port, event_nb);
48266 - schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
48271 - return NOTIFY_DONE;
48275 -static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
48276 - struct rockchip_usb2phy_port *rport,
48277 - struct device_node *child_np)
48280 - int ret;
48287 - rport->port_id = USB2PHY_PORT_OTG;
48288 - rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
48289 - rport->state = OTG_STATE_UNDEFINED;
48290 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
48291 + rport = &rphy->ports[index];
48292 + if (!rport->phy)
48295 - /*
48296 - * set suspended flag to true, but actually don't
48297 - * put phy in suspend mode, it aims to enable usb
48298 - * phy and clock in power_on() called by usb controller
48299 - * driver during probe.
48300 - */
48301 - rport->suspended = true;
48302 - rport->vbus_attached = false;
48303 + if (rport->port_id == USB2PHY_PORT_HOST &&
48304 + rport->port_cfg->disfall_en.offset)
48307 - mutex_init(&rport->mutex);
48311 - rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
48312 - if (rport->mode == USB_DR_MODE_HOST ||
48313 - rport->mode == USB_DR_MODE_UNKNOWN) {
48314 - ret = 0;
48315 - goto out;
48320 + if (rport->port_id == USB2PHY_PORT_OTG &&
48321 + rport->mode != USB_DR_MODE_UNKNOWN) {
48322 + if (rport->mode == USB_DR_MODE_HOST) {
48331 + force_mode = property_enabled(rphy->grf,
48332 + &rport->port_cfg->iddig_en);
48337 + if (!rport->vbus_always_on)
48344 - INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
48345 - INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
48359 + if (rphy->irq > 0)
48363 - * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
48364 - * interrupts muxed together, so probe the otg-mux interrupt first,
48365 - * if not found, then look for the regular interrupts one by one.
48367 + * the irqs of otg port. So probe the otg-mux interrupt first,
48370 rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
48371 if (rport->otg_mux_irq > 0) {
48372 @@ -1020,20 +1757,50 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
48376 - if (ret) {
48378 dev_err(rphy->dev,
48379 "failed to request otg-mux irq handle\n");
48380 - goto out;
48381 - }
48382 - } else {
48383 - rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
48384 - if (rport->bvalid_irq < 0) {
48385 - dev_err(rphy->dev, "no vbus valid irq provided\n");
48386 - ret = rport->bvalid_irq;
48387 - goto out;
48393 + rport->ls_irq = of_irq_get_byname(child_np, "linestate");
48394 + if (rport->ls_irq <= 0) {
48395 + dev_err(rphy->dev, "no linestate irq provided\n");
48396 + return -EINVAL;
48399 + ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
48404 + dev_err(rphy->dev, "failed to request linestate irq handle\n");
48413 + if (rport->port_id == USB2PHY_PORT_HOST ||
48414 + rport->mode == USB_DR_MODE_HOST ||
48415 + rport->mode == USB_DR_MODE_UNKNOWN)
48419 + if (!rport->vbus_always_on) {
48420 + rport->bvalid_irq = of_irq_get_byname(child_np,
48421 + "otg-bvalid");
48422 + if (rport->bvalid_irq <= 0) {
48423 + dev_err(rphy->dev, "no bvalid irq provided\n");
48424 + return -EINVAL;
48427 - ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
48428 + ret = devm_request_threaded_irq(rphy->dev,
48429 + rport->bvalid_irq,
48433 @@ -1042,187 +1809,1023 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
48435 dev_err(rphy->dev,
48436 "failed to request otg-bvalid irq handle\n");
48437 - goto out;
48442 - if (!IS_ERR(rphy->edev)) {
48443 - rport->event_nb.notifier_call = rockchip_otg_event;
48445 + if (rphy->edev_self) {
48446 + rport->id_irq = of_irq_get_byname(child_np, "otg-id");
48447 + if (rport->id_irq <= 0) {
48448 + dev_err(rphy->dev, "no otg id irq provided\n");
48449 + return -EINVAL;
48452 - ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
48453 - EXTCON_USB_HOST, &rport->event_nb);
48454 - if (ret)
48455 - dev_err(rphy->dev, "register USB HOST notifier failed\n");
48456 + ret = devm_request_threaded_irq(rphy->dev,
48457 + rport->id_irq, NULL,
48463 + dev_err(rphy->dev,
48464 + "failed to request otg-id irq handle\n");
48469 -out:
48473 -static int rockchip_usb2phy_probe(struct platform_device *pdev)
48478 - struct device *dev = &pdev->dev;
48479 - struct device_node *np = dev->of_node;
48480 - struct device_node *child_np;
48481 - struct phy_provider *provider;
48482 - struct rockchip_usb2phy *rphy;
48483 - const struct rockchip_usb2phy_cfg *phy_cfgs;
48484 - const struct of_device_id *match;
48485 - unsigned int reg;
48486 - int index, ret;
48487 -
48488 - rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
48489 - if (!rphy)
48490 - return -ENOMEM;
48491 -
48492 - match = of_match_device(dev->driver->of_match_table, dev);
48493 - if (!match || !match->data) {
48494 - dev_err(dev, "phy configs are not assigned!\n");
48495 - return -EINVAL;
48496 - }
48500 - if (!dev->parent || !dev->parent->of_node)
48501 - return -EINVAL;
48502 + rport->port_id = USB2PHY_PORT_HOST;
48503 + rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
48505 - rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
48506 - if (IS_ERR(rphy->grf))
48507 - return PTR_ERR(rphy->grf);
48509 + rport->low_power_en =
48510 + of_property_read_bool(child_np, "rockchip,low-power-mode");
48512 - if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
48513 - rphy->usbgrf =
48514 - syscon_regmap_lookup_by_phandle(dev->of_node,
48515 - "rockchip,usbgrf");
48516 - if (IS_ERR(rphy->usbgrf))
48517 - return PTR_ERR(rphy->usbgrf);
48518 - } else {
48519 - rphy->usbgrf = NULL;
48520 - }
48521 + mutex_init(&rport->mutex);
48522 + INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
48524 - if (of_property_read_u32(np, "reg", ®)) {
48525 - dev_err(dev, "the reg property is not assigned in %pOFn node\n",
48526 - np);
48527 - return -EINVAL;
48530 + dev_err(rphy->dev, "failed to init irq for host port\n");
48534 - rphy->dev = dev;
48535 - phy_cfgs = match->data;
48536 - rphy->chg_state = USB_CHG_STATE_UNDEFINED;
48537 - rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
48538 - platform_set_drvdata(pdev, rphy);
48539 -
48540 - ret = rockchip_usb2phy_extcon_register(rphy);
48542 + * Let us put phy-port into suspend mode here for saving power
48546 + ret = property_enable(base, &rport->port_cfg->phy_sus, true);
48549 + rport->suspended = true;
48551 - /* find out a proper config which can be matched with dt. */
48552 - index = 0;
48553 - while (phy_cfgs[index].reg) {
48554 - if (phy_cfgs[index].reg == reg) {
48555 - rphy->phy_cfg = &phy_cfgs[index];
48556 - break;
48557 - }
48561 - ++index;
48562 - }
48569 - if (!rphy->phy_cfg) {
48570 - dev_err(dev, "no phy-config can be matched with %pOFn node\n",
48571 - np);
48572 - return -EINVAL;
48573 - }
48574 + schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
48576 - rphy->clk = of_clk_get_by_name(np, "phyclk");
48577 - if (!IS_ERR(rphy->clk)) {
48589 + rport->port_id = USB2PHY_PORT_OTG;
48590 + rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
48591 + rport->state = OTG_STATE_UNDEFINED;
48592 + rport->vbus_attached = false;
48593 + rport->vbus_enabled = false;
48594 + rport->perip_connected = false;
48595 + rport->prev_iddig = true;
48597 + mutex_init(&rport->mutex);
48600 + rport->bypass_uart_en =
48601 + of_property_read_bool(child_np, "rockchip,bypass-uart");
48602 + rport->vbus_always_on =
48603 + of_property_read_bool(child_np, "rockchip,vbus-always-on");
48604 + rport->utmi_avalid =
48605 + of_property_read_bool(child_np, "rockchip,utmi-avalid");
48608 + rport->low_power_en =
48609 + of_property_read_bool(child_np, "rockchip,low-power-mode");
48611 + /* For type-c with vbus_det always pull up */
48612 + rport->typec_vbus_det =
48613 + of_property_read_bool(child_np, "rockchip,typec-vbus-det");
48616 + rport->vbus = devm_regulator_get_optional(&rport->phy->dev, "vbus");
48617 + if (IS_ERR(rport->vbus)) {
48618 + ret = PTR_ERR(rport->vbus);
48619 + if (ret == -EPROBE_DEFER)
48622 + if (rport->mode == USB_DR_MODE_OTG)
48623 + dev_warn(&rport->phy->dev, "No vbus specified for otg port\n");
48624 + rport->vbus = NULL;
48627 + rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
48628 + iddig = property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig);
48629 + if (rphy->edev_self && (rport->mode == USB_DR_MODE_HOST ||
48630 + rport->mode == USB_DR_MODE_UNKNOWN || !iddig)) {
48632 + extcon_set_state(rphy->edev, EXTCON_USB, false);
48633 + extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
48634 + extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
48642 + dev_err(rphy->dev, "failed to init irq for otg port\n");
48646 + if (rport->vbus_always_on || rport->mode == USB_DR_MODE_HOST ||
48647 + rport->mode == USB_DR_MODE_UNKNOWN)
48651 + if (rport->port_cfg->bvalid_grf_con.enable != 0)
48652 + property_enable(base, &rport->port_cfg->bvalid_grf_con, false);
48654 + wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg");
48655 + INIT_DELAYED_WORK(&rport->bypass_uart_work,
48657 + INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
48658 + INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
48660 + if (!IS_ERR(rphy->edev)) {
48661 + rport->event_nb.notifier_call = rockchip_otg_event;
48663 + ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
48664 + EXTCON_USB_HOST, &rport->event_nb);
48666 + dev_err(rphy->dev, "register USB HOST notifier failed\n");
48673 + * Let us put phy-port into suspend mode here for saving power
48677 + ret = property_enable(base, &rport->port_cfg->phy_sus, true);
48680 + rport->suspended = true;
48685 + wake_lock_destroy(&rport->wakelock);
48691 + struct device *dev = &pdev->dev;
48692 + struct device_node *np = dev->of_node;
48705 + return -ENOMEM;
48707 + match = of_match_device(dev->driver->of_match_table, dev);
48708 + if (!match || !match->data) {
48710 + return -EINVAL;
48713 + if (!dev->parent || !dev->parent->of_node) {
48717 + return -ENODEV;
48720 + rphy->phy_base = devm_ioremap_resource(dev, res);
48721 + if (IS_ERR(rphy->phy_base))
48722 + return PTR_ERR(rphy->phy_base);
48724 + rphy->grf = syscon_regmap_lookup_by_phandle(np,
48726 + if (IS_ERR(rphy->grf))
48727 + return PTR_ERR(rphy->grf);
48729 + reg = res->start;
48731 + rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
48732 + if (IS_ERR(rphy->grf))
48733 + return PTR_ERR(rphy->grf);
48735 + if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
48736 + rphy->usbgrf =
48737 + syscon_regmap_lookup_by_phandle(dev->of_node,
48739 + if (IS_ERR(rphy->usbgrf))
48740 + return PTR_ERR(rphy->usbgrf);
48742 + rphy->usbgrf = NULL;
48747 + np->name);
48748 + return -EINVAL;
48752 + rphy->dev = dev;
48753 + phy_cfgs = match->data;
48754 + rphy->chg_state = USB_CHG_STATE_UNDEFINED;
48755 + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
48756 + rphy->edev_self = false;
48757 + rphy->irq = platform_get_irq(pdev, 0);
48768 + rphy->phy_cfg = &phy_cfgs[index];
48775 + if (!rphy->phy_cfg) {
48776 + dev_err(dev, "no phy-config can be matched with %pOFn node\n",
48778 + return -EINVAL;
48786 + rphy->phy_reset = devm_reset_control_get_optional(dev, "phy");
48787 + if (IS_ERR(rphy->phy_reset))
48788 + return PTR_ERR(rphy->phy_reset);
48790 + rphy->clk = of_clk_get_by_name(np, "phyclk");
48791 + if (!IS_ERR(rphy->clk)) {
48792 clk_prepare_enable(rphy->clk);
48794 dev_info(&pdev->dev, "no phyclk specified\n");
48795 rphy->clk = NULL;
48798 - ret = rockchip_usb2phy_clk480m_register(rphy);
48799 - if (ret) {
48800 - dev_err(dev, "failed to register 480m output clock\n");
48801 - goto disable_clks;
48802 - }
48803 + if (rphy->phy_cfg->phy_tuning) {
48804 + ret = rphy->phy_cfg->phy_tuning(rphy);
48811 + struct rockchip_usb2phy_port *rport = &rphy->ports[index];
48814 + /* This driver aims to support both otg-port and host-port */
48815 + if (!of_node_name_eq(child_np, "host-port") &&
48816 + !of_node_name_eq(child_np, "otg-port"))
48826 + rport->phy = phy;
48827 + phy_set_drvdata(rport->phy, rport);
48830 + if (of_node_name_eq(child_np, "host-port")) {
48844 + if (++index >= rphy->phy_cfg->num_ports)
48856 + ret = sysfs_create_group(&dev->kobj, &usb2_phy_attr_group);
48868 + if (rphy->irq > 0) {
48869 + ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
48875 + dev_err(rphy->dev,
48881 + if (of_property_read_bool(np, "wakeup-source"))
48882 + device_init_wakeup(rphy->dev, true);
48884 + device_init_wakeup(rphy->dev, false);
48893 + if (rphy->clk) {
48894 + clk_disable_unprepare(rphy->clk);
48895 + clk_put(rphy->clk);
48907 + if (!rport->low_power_en)
48910 + if (rport->port_id == USB2PHY_PORT_OTG) {
48911 + dev_info(&rport->phy->dev, "set otg port low power state %d\n",
48913 + ret = property_enable(rphy->grf, &rport->port_cfg->bypass_bc,
48918 + ret = property_enable(rphy->grf, &rport->port_cfg->bypass_otg,
48923 + ret = property_enable(rphy->grf, &rport->port_cfg->vbus_det_en,
48925 + } else if (rport->port_id == USB2PHY_PORT_HOST) {
48926 + dev_info(&rport->phy->dev, "set host port low power state %d\n",
48929 + ret = property_enable(rphy->grf, &rport->port_cfg->bypass_host,
48941 + ret = regmap_write(rphy->grf, 0x298, 0x00040000);
48952 + /* Open pre-emphasize in non-chirp state for PHY0 otg port */
48953 + if (rphy->phy_cfg->reg == 0x760)
48954 + ret = regmap_write(rphy->grf, 0x76c, 0x00070004);
48963 + /* Open pre-emphasize in non-chirp state for otg port */
48964 + ret = regmap_write(rphy->grf, 0x0, 0x00070004);
48968 + /* Open pre-emphasize in non-chirp state for host port */
48969 + ret = regmap_write(rphy->grf, 0x30, 0x00070004);
48974 + ret = regmap_write(rphy->grf, 0x18, 0x00040000);
48986 + ret = regmap_write(rphy->grf, 0x2c, 0xffff0400);
48990 + /* Open pre-emphasize in non-chirp state for otg port */
48991 + ret = regmap_write(rphy->grf, 0x0, 0x00070004);
48995 + /* Open pre-emphasize in non-chirp state for host port */
48996 + ret = regmap_write(rphy->grf, 0x30, 0x00070004);
49001 + ret = regmap_write(rphy->grf, 0x18, 0x00040000);
49015 + /* open HS pre-emphasize to expand HS slew rate for each port. */
49016 + ret |= regmap_write(rphy->grf, 0x0780, open_pre_emphasize);
49017 + ret |= regmap_write(rphy->grf, 0x079c, eye_height_tuning);
49018 + ret |= regmap_write(rphy->grf, 0x07b0, open_pre_emphasize);
49019 + ret |= regmap_write(rphy->grf, 0x07cc, eye_height_tuning);
49022 + ret |= regmap_write(rphy->grf, 0x078c, compensation_tuning);
49029 + struct device_node *node = rphy->dev->of_node;
49032 + if (rphy->phy_cfg->reg == 0xe450) {
49034 + * Disable the pre-emphasize in eop state
49035 + * and chirp state to avoid mis-trigger the
49039 + ret |= regmap_write(rphy->grf, 0x4480,
49041 + ret |= regmap_write(rphy->grf, 0x44b4,
49045 + * Disable the pre-emphasize in eop state
49046 + * and chirp state to avoid mis-trigger the
49050 + ret |= regmap_write(rphy->grf, 0x4500,
49052 + ret |= regmap_write(rphy->grf, 0x4534,
49056 + if (!of_property_read_bool(node, "rockchip,u2phy-tuning"))
49059 + if (rphy->phy_cfg->reg == 0xe450) {
49064 + ret |= regmap_write(rphy->grf, 0x448c,
49067 + /* Set max pre-emphasis level for PHY0 */
49068 + ret |= regmap_write(rphy->grf, 0x44b0,
49074 + ret |= regmap_write(rphy->grf, 0x4480,
49081 + ret |= regmap_write(rphy->grf, 0x450c,
49084 + /* Set max pre-emphasis level for PHY1 */
49085 + ret |= regmap_write(rphy->grf, 0x4530,
49091 + ret |= regmap_write(rphy->grf, 0x4500,
49103 + reg = readl(rphy->phy_base + 0x30);
49105 + writel(reg & ~BIT(2), rphy->phy_base + 0x30);
49107 + reg = readl(rphy->phy_base);
49108 + /* Enable otg port pre-emphasis during non-chirp phase */
49111 + writel(reg, rphy->phy_base);
49113 + reg = readl(rphy->phy_base + 0x0400);
49114 + /* Enable host port pre-emphasis during non-chirp phase */
49117 + writel(reg, rphy->phy_base + 0x0400);
49119 + if (rphy->phy_cfg->reg == 0xfe8a0000) {
49121 + reg = readl(rphy->phy_base + 0x30);
49124 + writel(reg, rphy->phy_base + 0x30);
49130 + ret |= regmap_write(rphy->grf, 0x0048, FILTER_COUNTER);
49136 + ret |= regmap_write(rphy->grf, 0x004c, FILTER_COUNTER);
49147 + reg = readl(rphy->phy_base + 0x3c);
49149 + writel(reg & ~BIT(7), rphy->phy_base + 0x3c);
49151 + reg = readl(rphy->phy_base + 0x3c);
49153 + writel(reg | BIT(7), rphy->phy_base + 0x3c);
49164 + ret = regmap_write(rphy->grf, 0x0008,
49174 + if (rphy->phy_cfg->reg == 0x0000) {
49179 + * 3. Set utmi_opmode to 2'b01 (no-driving)
49181 + ret |= regmap_write(rphy->grf, 0x000c,
49185 + ret |= regmap_write(rphy->grf, 0x0004,
49188 - index = 0;
49189 - for_each_available_child_of_node(np, child_np) {
49190 - struct rockchip_usb2phy_port *rport = &rphy->ports[index];
49191 - struct phy *phy;
49192 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
49193 + ret |= regmap_write(rphy->grf, 0x0008,
49196 - /* This driver aims to support both otg-port and host-port */
49197 - if (!of_node_name_eq(child_np, "host-port") &&
49198 - !of_node_name_eq(child_np, "otg-port"))
49199 - goto next_child;
49201 + ret |= regmap_write(rphy->grf, 0x0010,
49203 + } else if (rphy->phy_cfg->reg == 0x4000) {
49208 + * 3. Set utmi_opmode to 2'b01 (no-driving)
49210 + ret |= regmap_write(rphy->grf, 0x000c,
49213 - phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
49214 - if (IS_ERR(phy)) {
49215 - dev_err(dev, "failed to create phy\n");
49216 - ret = PTR_ERR(phy);
49217 - goto put_child;
49219 + ret |= regmap_write(rphy->grf, 0x0004,
49222 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
49223 + ret |= regmap_write(rphy->grf, 0x0008,
49227 + ret |= regmap_write(rphy->grf, 0x0010,
49229 + } else if (rphy->phy_cfg->reg == 0x8000) {
49236 + ret |= regmap_write(rphy->grf, 0x000c,
49240 + ret |= regmap_write(rphy->grf, 0x0004,
49243 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
49244 + ret |= regmap_write(rphy->grf, 0x0008,
49246 + } else if (rphy->phy_cfg->reg == 0xc000) {
49253 + ret |= regmap_write(rphy->grf, 0x000c,
49257 + ret |= regmap_write(rphy->grf, 0x0004,
49260 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
49261 + ret |= regmap_write(rphy->grf, 0x0008,
49277 + if (device_may_wakeup(rphy->dev))
49280 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
49281 + rport = &rphy->ports[index];
49282 + if (!rport->phy)
49285 + if (rport->port_id == USB2PHY_PORT_OTG &&
49286 + (rport->id_irq > 0 || rphy->irq > 0)) {
49287 + mutex_lock(&rport->mutex);
49288 + rport->prev_iddig = property_enabled(rphy->grf,
49289 + &rport->port_cfg->utmi_iddig);
49292 + mutex_unlock(&rport->mutex);
49294 + dev_err(rphy->dev,
49300 - rport->phy = phy;
49301 - phy_set_drvdata(rport->phy, rport);
49302 + if (rport->port_id == USB2PHY_PORT_OTG && wakeup_enable &&
49303 + rport->bvalid_irq > 0)
49304 + enable_irq_wake(rport->bvalid_irq);
49306 - /* initialize otg/host port separately */
49307 - if (of_node_name_eq(child_np, "host-port")) {
49308 - ret = rockchip_usb2phy_host_port_init(rphy, rport,
49309 - child_np);
49310 - if (ret)
49311 - goto put_child;
49312 - } else {
49313 - ret = rockchip_usb2phy_otg_port_init(rphy, rport,
49314 - child_np);
49315 - if (ret)
49316 - goto put_child;
49318 + mutex_lock(&rport->mutex);
49320 + mutex_unlock(&rport->mutex);
49322 + dev_err(rphy->dev, "failed to enable linestate irq\n");
49326 -next_child:
49327 - /* to prevent out of boundary */
49328 - if (++index >= rphy->phy_cfg->num_ports)
49329 - break;
49330 + if (wakeup_enable && rport->ls_irq > 0)
49331 + enable_irq_wake(rport->ls_irq);
49337 - provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
49338 - return PTR_ERR_OR_ZERO(provider);
49342 -put_child:
49343 - of_node_put(child_np);
49344 -disable_clks:
49345 - if (rphy->clk) {
49346 - clk_disable_unprepare(rphy->clk);
49347 - clk_put(rphy->clk);
49357 + if (device_may_wakeup(rphy->dev))
49360 + if (rphy->phy_cfg->phy_tuning)
49361 + ret = rphy->phy_cfg->phy_tuning(rphy);
49363 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
49364 + rport = &rphy->ports[index];
49365 + if (!rport->phy)
49368 + if (rport->port_id == USB2PHY_PORT_OTG &&
49369 + (rport->id_irq > 0 || rphy->irq > 0)) {
49370 + mutex_lock(&rport->mutex);
49371 + iddig = property_enabled(rphy->grf,
49372 + &rport->port_cfg->utmi_iddig);
49375 + mutex_unlock(&rport->mutex);
49377 + dev_err(rphy->dev,
49382 + if (iddig != rport->prev_iddig) {
49383 + dev_dbg(&rport->phy->dev,
49385 + rport->prev_iddig = iddig;
49386 + extcon_set_state_sync(rphy->edev,
49389 + extcon_set_state_sync(rphy->edev,
49398 + if (rport->port_id == USB2PHY_PORT_OTG && wakeup_enable &&
49399 + rport->bvalid_irq > 0)
49400 + disable_irq_wake(rport->bvalid_irq);
49402 + if (wakeup_enable && rport->ls_irq > 0)
49403 + disable_irq_wake(rport->ls_irq);
49537 - .phy_sus = { 0x0760, 15, 0, 0, 0x1d1 },
49559 - .phy_sus = { 0x0764, 15, 0, 0, 0x1d1 },
49567 - .opmode = { 0x0760, 3, 0, 5, 1 },
49572 @@ -1240,18 +2843,72 @@ static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
49576 - .phy_sus = { 0x800, 15, 0, 0, 0x1d1 },
49623 - .phy_sus = { 0x804, 15, 0, 0, 0x1d1 },
49624 - .ls_det_en = { 0x0684, 1, 1, 0, 1 },
49625 - .ls_det_st = { 0x0694, 1, 1, 0, 1 },
49626 - .ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
49650 @@ -1260,22 +2917,36 @@ static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
49658 - .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
49683 - .phy_sus = { 0x104, 15, 0, 0, 0x1d1 },
49689 @@ -1284,7 +2955,7 @@ static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
49693 - .opmode = { 0x0100, 3, 0, 5, 1 },
49698 @@ -1303,10 +2974,11 @@ static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
49706 - .phy_sus = { 0x0728, 15, 0, 0, 0x1d1 },
49711 @@ -1318,19 +2990,86 @@ static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
49773 - .phy_sus = { 0xe454, 1, 0, 2, 1 },
49799 @@ -1342,7 +3081,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
49803 - .opmode = { 0xe454, 3, 0, 5, 1 },
49808 @@ -1357,15 +3096,30 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
49816 - .phy_sus = { 0xe464, 1, 0, 2, 1 },
49840 @@ -1376,6 +3130,246 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
50087 @@ -1407,7 +3401,7 @@ static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
50091 - .opmode = { 0x0100, 3, 0, 5, 1 },
50096 @@ -1424,10 +3418,16 @@ static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
50099 { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
50100 + { .compatible = "rockchip,rk1808-usb2phy", .data = &rk1808_phy_cfgs },
50101 + { .compatible = "rockchip,rk3128-usb2phy", .data = &rk312x_phy_cfgs },
50102 { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
50103 + { .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
50104 { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
50105 { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
50106 + { .compatible = "rockchip,rk3368-usb2phy", .data = &rk3368_phy_cfgs },
50107 { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
50108 + { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
50109 + { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
50110 { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
50113 @@ -1437,6 +3437,7 @@ static struct platform_driver rockchip_usb2phy_driver = {
50116 .name = "rockchip-usb2phy",
50121 diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
50123 --- a/drivers/phy/rockchip/phy-rockchip-pcie.c
50124 +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
50125 @@ -182,6 +182,12 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
50127 mutex_lock(&rk_phy->pcie_mutex);
50129 + regmap_write(rk_phy->reg_base,
50130 + rk_phy->phy_data->pcie_laneoff,
50133 + PHY_LANE_IDLE_A_SHIFT + inst->index));
50135 if (rk_phy->pwr_cnt++)
50138 @@ -196,12 +202,6 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
50142 - regmap_write(rk_phy->reg_base,
50143 - rk_phy->phy_data->pcie_laneoff,
50144 - HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
50145 - PHY_LANE_IDLE_MASK,
50146 - PHY_LANE_IDLE_A_SHIFT + inst->index));
50147 -
50150 * so we make it large enough here. And we use loop-break
50151 diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
50153 --- a/drivers/phy/rockchip/phy-rockchip-typec.c
50154 +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
50155 @@ -54,6 +54,7 @@
50159 +#include <linux/phy/phy-rockchip-typec.h>
50163 @@ -285,13 +286,37 @@
50167 -#define PMA_LANE_CFG (0xc000 << 2)
50182 -#define DP_MODE_CTL (0xc008 << 2)
50203 @@ -314,21 +339,29 @@
50207 -#define CLK_PLL_CONFIG 0X30
50223 -#define DP_MODE_A0 BIT(4)
50224 -#define DP_MODE_A2 BIT(6)
50225 -#define DP_MODE_ENTER_A0 0xc101
50226 -#define DP_MODE_ENTER_A2 0xc104
50238 @@ -340,6 +373,10 @@
50249 @@ -368,6 +405,11 @@ struct rockchip_usb3phy_port_cfg {
50261 @@ -384,6 +426,7 @@ struct rockchip_typec_phy {
50269 @@ -408,26 +451,136 @@ static struct phy_reg usb3_pll_cfg[] = {
50273 -static struct phy_reg dp_pll_cfg[] = {
50274 - { 0xf0, CMN_PLL1_VCOCAL_INIT },
50275 - { 0x18, CMN_PLL1_VCOCAL_ITER },
50276 - { 0x30b9, CMN_PLL1_VCOCAL_START },
50277 - { 0x21c, CMN_PLL1_INTDIV },
50278 - { 0, CMN_PLL1_FRACDIV },
50279 - { 0x5, CMN_PLL1_HIGH_THR },
50280 - { 0x35, CMN_PLL1_SS_CTRL1 },
50281 - { 0x7f1e, CMN_PLL1_SS_CTRL2 },
50282 - { 0x20, CMN_PLL1_DSM_DIAG },
50283 - { 0, CMN_PLLSM1_USER_DEF_CTRL },
50284 - { 0, CMN_DIAG_PLL1_OVRD },
50285 - { 0, CMN_DIAG_PLL1_FBH_OVRD },
50286 - { 0, CMN_DIAG_PLL1_FBL_OVRD },
50287 - { 0x6, CMN_DIAG_PLL1_V2I_TUNE },
50288 - { 0x45, CMN_DIAG_PLL1_CP_TUNE },
50289 - { 0x8, CMN_DIAG_PLL1_LF_PROG },
50290 - { 0x100, CMN_DIAG_PLL1_PTATIS_TUNE1 },
50291 - { 0x7, CMN_DIAG_PLL1_PTATIS_TUNE2 },
50292 - { 0x4, CMN_DIAG_PLL1_INCLK_CTRL },
50426 @@ -454,6 +607,134 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
50449 + PHY_DP_POWER_STATE_DISABLED = -1,
50466 + reg = readl(tcphy->base + PMA_CMN_CTRL1);
50468 + dev_err(tcphy->dev, "cmn_ready in the inactive state\n");
50469 + return -EINVAL;
50472 + reg = readl(tcphy->base + PHY_DP_MODE_CTL);
50475 + writel(reg, tcphy->base + PHY_DP_MODE_CTL);
50477 + ret = readl_poll_timeout(tcphy->base + PHY_DP_MODE_CTL,
50482 + dev_err(tcphy->dev, "failed to enter power state %d\n", state);
50504 + * -------------------------------------------------------------------
50506 + * -------------------------------------------------------------------
50507 + * Lane0 (tx_p/m_ln_0) TX1+/TX1- (pins A2/A3)
50508 + * Lane1 (tx_rx_p/m_ln_1) RX1+/RX1- (pins B11/B10)
50509 + * Lane2 (tx_rx_p/m_ln_2) RX2+/RX2- (pins A11/A10)
50510 + * Lane3 (tx_p/m_ln_3) TX2+/TX2- (pins B2/B3)
50511 + * -------------------------------------------------------------------
50517 + * ----------------------------------------------------------------------
50519 + * ----------------------------------------------------------------------
50524 + * ----------------------------------------------------------------------
50545 + tcphy->base + PHY_PMA_LANE_CFG);
50554 + tcphy->base + PHY_PMA_LANE_CFG);
50561 @@ -475,7 +756,7 @@ static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
50563 rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
50565 - rdata |= CLK_PLL_CONFIG;
50567 writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL);
50570 @@ -489,17 +770,44 @@ static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy)
50571 tcphy->base + usb3_pll_cfg[i].addr);
50574 -static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy)
50577 - u32 i;
50582 + hsclk_sel = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
50607 - /* set the default mode to RBR */
50608 - writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR,
50609 - tcphy->base + DP_CLK_CTL);
50611 + writel(clk_ctrl, tcphy->base + PHY_DP_CLK_CTL);
50612 + writel(hsclk_sel, tcphy->base + CMN_DIAG_HSCLK_SEL);
50615 - for (i = 0; i < ARRAY_SIZE(dp_pll_cfg); i++)
50616 - writel(dp_pll_cfg[i].value, tcphy->base + dp_pll_cfg[i].addr);
50618 + writel(phy_cfg[i].value, tcphy->base + phy_cfg[i].addr);
50622 @@ -526,9 +834,10 @@ static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
50623 writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane));
50626 -static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
50630 - u16 rdata;
50633 writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane));
50634 writel(0x6799, tcphy->base + TX_PSC_A0(lane));
50635 @@ -536,27 +845,234 @@ static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
50636 writel(0x98, tcphy->base + TX_PSC_A2(lane));
50637 writel(0x98, tcphy->base + TX_PSC_A3(lane));
50639 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
50640 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_001(lane));
50641 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_010(lane));
50642 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_011(lane));
50643 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_100(lane));
50644 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_101(lane));
50645 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_110(lane));
50646 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_111(lane));
50647 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_10(lane));
50648 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_01(lane));
50649 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
50650 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_11(lane));
50651 -
50652 - writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
50653 - writel(0x400, tcphy->base + TX_DIAG_TX_DRV(lane));
50654 -
50655 - rdata = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50656 - rdata = (rdata & 0x8fff) | 0x6000;
50657 - writel(rdata, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50658 + writel(tcphy->config[swing][pre_emp].swing,
50659 + tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
50660 + writel(tcphy->config[swing][pre_emp].pe,
50661 + tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
50664 + writel(0x700, tcphy->base + TX_DIAG_TX_DRV(lane));
50665 + writel(0x13c, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
50667 + writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
50668 + writel(0x0400, tcphy->base + TX_DIAG_TX_DRV(lane));
50671 + val = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50683 + writel(val, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50692 + if (!phy->power_count)
50693 + return -EPERM;
50695 + if (tcphy->mode == MODE_DFP_DP) {
50699 + if (tcphy->flip) {
50717 + if (!phy->power_count)
50718 + return -EPERM;
50723 + * power-down the unused PHY DP lanes (and their mapped PMA lanes).
50727 + reg = readl(tcphy->base + PHY_DP_MODE_CTL);
50742 + return -EINVAL;
50745 + writel(reg, tcphy->base + PHY_DP_MODE_CTL);
50759 + if (!phy->power_count)
50760 + return -EPERM;
50765 + dev_err(tcphy->dev, "failed to enter A3 state: %d\n", ret);
50770 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50773 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50775 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50779 + dev_err(tcphy->dev, "wait DP PLL clock disabled timeout\n");
50784 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50787 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50789 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50793 + dev_err(tcphy->dev, "wait DP PLL not ready timeout\n");
50797 + /* Re-configure PHY registers for the new data rate */
50798 + cmn_diag_hsclk_sel = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
50801 + phy_dp_clk_ctl = readl(tcphy->base + PHY_DP_CLK_CTL);
50830 + return -EINVAL;
50833 + writel(cmn_diag_hsclk_sel, tcphy->base + CMN_DIAG_HSCLK_SEL);
50834 + writel(phy_dp_clk_ctl, tcphy->base + PHY_DP_CLK_CTL);
50838 + writel(phy_cfg[i].value, tcphy->base + phy_cfg[i].addr);
50841 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50844 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50846 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50850 + dev_err(tcphy->dev, "wait DP PLL ready timeout\n");
50855 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50858 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50860 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50864 + dev_err(tcphy->dev, "wait DP PLL clock enabled timeout\n");
50871 + dev_err(tcphy->dev, "failed to enter A2 state: %d\n", ret);
50878 + dev_err(tcphy->dev, "failed to enter A0 state: %d\n", ret);
50889 @@ -719,6 +1235,18 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
50890 writel(val, tcphy->base + TX_DIG_CTRL_REG_2);
50896 + const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50898 + property_enable(tcphy, &cfg->usb3tousb2_en, value);
50899 + property_enable(tcphy, &cfg->usb3_host_disable, value);
50900 + property_enable(tcphy, &cfg->usb3_host_port, !value);
50907 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50908 @@ -743,32 +1271,33 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
50915 - tcphy_cfg_dp_pll(tcphy);
50919 - tcphy_dp_cfg_lane(tcphy, i);
50920 -
50921 - writel(PIN_ASSIGN_C_E, tcphy->base + PMA_LANE_CFG);
50925 - tcphy_cfg_dp_pll(tcphy);
50927 if (tcphy->flip) {
50930 - tcphy_dp_cfg_lane(tcphy, 0);
50931 - tcphy_dp_cfg_lane(tcphy, 1);
50937 - tcphy_dp_cfg_lane(tcphy, 2);
50938 - tcphy_dp_cfg_lane(tcphy, 3);
50942 -
50943 - writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
50946 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
50947 + val = readl(tcphy->base + PHY_DP_MODE_CTL);
50950 + writel(val, tcphy->base + PHY_DP_MODE_CTL);
50952 reset_control_deassert(tcphy->uphy_rst);
50954 @@ -851,22 +1380,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
50958 -static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
50959 - bool value)
50962 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50963 -
50964 - property_enable(tcphy, &cfg->usb3tousb2_en, value);
50965 - property_enable(tcphy, &cfg->usb3_host_disable, value);
50966 - property_enable(tcphy, &cfg->usb3_host_port, !value);
50967 -
50968 - return 0;
50969 -}
50970 -
50971 -static int rockchip_usb3_phy_power_on(struct phy *phy)
50972 -{
50973 - struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
50974 - const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50975 const struct usb3phy_reg *reg = &cfg->pipe_status;
50978 @@ -917,6 +1433,24 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
50995 + dev_info(tcphy->dev, "Needed %d loops to turn on\n", tries);
51003 @@ -980,8 +1514,8 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
51005 property_enable(tcphy, &cfg->uphy_dp_sel, 1);
51007 - ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
51008 - val, val & DP_MODE_A2, 1000,
51009 + ret = readx_poll_timeout(readl, tcphy->base + PHY_DP_MODE_CTL,
51013 dev_err(tcphy->dev, "failed to wait TCPHY enter A2\n");
51014 @@ -990,14 +1524,10 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
51018 - writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
51019 -
51020 - ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
51021 - val, val & DP_MODE_A0, 1000,
51022 - PHY_MODE_SET_TIMEOUT);
51023 - if (ret < 0) {
51024 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
51025 - dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
51029 + dev_err(tcphy->dev, "failed to enter A0 power state\n");
51033 @@ -1014,6 +1544,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
51039 mutex_lock(&tcphy->lock);
51041 @@ -1022,7 +1553,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
51043 tcphy->mode &= ~MODE_DFP_DP;
51045 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
51048 + dev_err(tcphy->dev, "failed to enter A2 power state\n");
51052 if (tcphy->mode == MODE_DISCONNECT)
51054 @@ -1041,6 +1576,8 @@ static const struct phy_ops rockchip_dp_phy_ops = {
51060 tcphy->grf_regs = syscon_regmap_lookup_by_phandle(dev->of_node,
51062 if (IS_ERR(tcphy->grf_regs)) {
51063 @@ -1078,6 +1615,16 @@ static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
51064 return PTR_ERR(tcphy->tcphy_rst);
51071 + ret = of_property_read_u32_array(dev->of_node, "rockchip,phy-config",
51072 + (u32 *)tcphy->config, sizeof(tcphy->config) / sizeof(u32));
51074 + memcpy(tcphy->config, tcphy_default_config,
51075 + sizeof(tcphy->config));
51080 diff --git a/drivers/phy/rockchip/phy-rockchip-usb.c b/drivers/phy/rockchip/phy-rockchip-usb.c
51082 --- a/drivers/phy/rockchip/phy-rockchip-usb.c
51083 +++ b/drivers/phy/rockchip/phy-rockchip-usb.c
51084 @@ -8,20 +8,26 @@
51087 #include <linux/clk-provider.h>
51089 +#include <linux/extcon-provider.h>
51106 -#include <linux/mfd/syscon.h>
51107 -#include <linux/delay.h>
51113 @@ -45,6 +51,69 @@ static int enable_usb_uart;
51183 @@ -61,20 +130,127 @@ struct rockchip_usb_phy_pdata {
51193 - struct device_node *np;
51194 - unsigned int reg_offset;
51195 - struct clk *clk;
51196 - struct clk *clk480m;
51197 - struct clk_hw clk480m_hw;
51198 - struct phy *phy;
51199 - bool uart_enabled;
51200 - struct reset_control *reset;
51201 - struct regulator *vbus;
51228 + return -EINVAL;
51231 + switch (rk_phy->mode) {
51244 + return -EINVAL;
51257 + return -EINVAL;
51260 + mutex_lock(&rk_phy->mutex);
51269 + dev_err(&rk_phy->phy->dev, "Error mode! Input 'otg' or 'host' or 'peripheral'\n");
51270 + ret = -EINVAL;
51274 + if (rk_phy->mode == new_dr_mode) {
51275 + dev_warn(&rk_phy->phy->dev, "Same as current mode.\n");
51279 + rk_phy->mode = new_dr_mode;
51281 + switch (rk_phy->mode) {
51298 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON3, val);
51301 + mutex_unlock(&rk_phy->mutex);
51320 @@ -136,6 +312,46 @@ static const struct clk_ops rockchip_usb_phy480m_ops = {
51330 + if (phy->bvalid_irq > 0) {
51331 + mutex_lock(&phy->mutex);
51338 + ret = regmap_write(phy->base->reg_base, RK3288_UOC0_CON4, val);
51340 + dev_err(phy->base->dev,
51345 + schedule_delayed_work(&phy->otg_sm_work, OTG_SCHEDULE_DELAY);
51348 + mutex_unlock(&phy->mutex);
51358 + if (phy->bvalid_irq > 0)
51359 + flush_delayed_work(&phy->otg_sm_work);
51367 @@ -179,7 +395,7 @@ static int rockchip_usb_phy_reset(struct phy *_phy)
51371 -static const struct phy_ops ops = {
51376 @@ -199,13 +415,383 @@ static void rockchip_usb_phy_action(void *data)
51377 clk_put(rk_phy->clk);
51383 + struct device_node *node = base->dev->of_node;
51387 + edev = extcon_get_edev_by_phandle(base->dev, 0);
51389 + if (PTR_ERR(edev) != -EPROBE_DEFER)
51390 + dev_err(base->dev,
51396 + edev = devm_extcon_dev_allocate(base->dev,
51400 + return -ENOMEM;
51402 + ret = devm_extcon_dev_register(base->dev, edev);
51404 + dev_err(base->dev,
51410 + base->edev = edev;
51427 + mutex_lock(&rk_phy->mutex);
51431 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS2, &val);
51434 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS2, &val);
51438 + if (!vbus_attached || !id || rk_phy->mode == USB_DR_MODE_HOST) {
51439 + dev_dbg(&rk_phy->phy->dev, "peripheral disconnected\n");
51440 + wake_unlock(&rk_phy->wakelock);
51441 + extcon_set_state_sync(rk_phy->base->edev, cable, false);
51442 + rk_phy->chg_state = USB_CHG_STATE_UNDEFINED;
51452 + switch (rk_phy->chg_state) {
51454 + mutex_unlock(&rk_phy->mutex);
51455 + schedule_delayed_work(&rk_phy->chg_work, 0);
51458 + switch (rk_phy->chg_type) {
51460 + dev_dbg(&rk_phy->phy->dev, "sdp cable is connected\n");
51461 + wake_lock(&rk_phy->wakelock);
51466 + dev_dbg(&rk_phy->phy->dev, "dcp cable is connected\n");
51471 + dev_dbg(&rk_phy->phy->dev, "cdp cable is connected\n");
51472 + wake_lock(&rk_phy->wakelock);
51485 + if (extcon_get_state(rk_phy->base->edev, cable) != vbus_attached)
51486 + extcon_set_state_sync(rk_phy->base->edev, cable,
51491 + schedule_delayed_work(&rk_phy->otg_sm_work, OTG_SCHEDULE_DELAY);
51493 + mutex_unlock(&rk_phy->mutex);
51522 + dev_dbg(&rk_phy->phy->dev, "chg detection work state = %d\n",
51523 + rk_phy->chg_state);
51525 + switch (rk_phy->chg_state) {
51527 + mutex_lock(&rk_phy->mutex);
51528 + /* put the controller in non-driving mode */
51531 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51535 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON3, val);
51539 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51540 + rk_phy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
51547 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS19, &val);
51556 + regmap_write(rk_phy->base->reg_base,
51564 + regmap_write(rk_phy->base->reg_base,
51567 + rk_phy->chg_state = USB_CHG_STATE_DCD_DONE;
51574 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS19, &val);
51579 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51588 + regmap_write(rk_phy->base->reg_base,
51591 + rk_phy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
51595 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
51596 + rk_phy->chg_state = USB_CHG_STATE_DETECTED;
51602 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB;
51603 + rk_phy->chg_state = USB_CHG_STATE_DETECTED;
51609 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS19, &val);
51616 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51618 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
51620 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
51623 + rk_phy->chg_state = USB_CHG_STATE_DETECTED;
51628 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51632 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON3, val);
51633 + mutex_unlock(&rk_phy->mutex);
51634 + rk3288_usb_phy_otg_sm_work(&rk_phy->otg_sm_work.work);
51635 + dev_info(&rk_phy->phy->dev, "charger = %s\n",
51636 + chg_to_string(rk_phy->chg_type));
51639 + mutex_unlock(&rk_phy->mutex);
51648 + schedule_delayed_work(&rk_phy->chg_work, delay);
51657 + ret = regmap_read(rk_phy->base->reg_base, RK3288_UOC0_CON4, &val);
51661 + mutex_lock(&rk_phy->mutex);
51666 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON4, val);
51668 + mutex_unlock(&rk_phy->mutex);
51670 + if (rk_phy->uart_enabled)
51673 + cancel_delayed_work_sync(&rk_phy->otg_sm_work);
51674 + rk3288_usb_phy_otg_sm_work(&rk_phy->otg_sm_work.work);
51684 + if (rk_phy->reg_offset == 0x320) {
51688 + rk_phy->bvalid_irq = of_irq_get_byname(rk_phy->np,
51689 + "otg-bvalid");
51690 + regmap_read(rk_phy->base->reg_base, RK3288_UOC0_CON4, &val);
51691 + if (rk_phy->bvalid_irq <= 0) {
51692 + dev_err(&rk_phy->phy->dev,
51694 + ret = -EINVAL;
51698 + ret = devm_request_threaded_irq(rk_phy->base->dev,
51699 + rk_phy->bvalid_irq,
51706 + dev_err(&rk_phy->phy->dev,
51707 + "failed to request otg-bvalid irq handle\n");
51711 + rk_phy->chg_state = USB_CHG_STATE_UNDEFINED;
51712 + wake_lock_init(&rk_phy->wakelock, WAKE_LOCK_SUSPEND,
51714 + INIT_DELAYED_WORK(&rk_phy->chg_work, rk3288_chg_detect_work);
51715 + INIT_DELAYED_WORK(&rk_phy->otg_sm_work,
51718 + rk_phy->mode = of_usb_get_dr_mode_by_phy(rk_phy->np, -1);
51719 + if (rk_phy->mode == USB_DR_MODE_OTG ||
51720 + rk_phy->mode == USB_DR_MODE_UNKNOWN) {
51721 + ret = sysfs_create_group(&rk_phy->phy->dev.kobj,
51724 + dev_err(&rk_phy->phy->dev,
51729 + } else if (rk_phy->reg_offset == 0x334) {
51733 + * EHCI (auto) suspend causes the corresponding usb-phy into
51735 + * usb-phy if the COMMONONN is set to 1'b1. The PLL output
51740 + * usb-phy always powered.
51742 + regmap_write(rk_phy->base->reg_base, rk_phy->reg_offset,
51752 + struct device_node *np = base->dev->of_node;
51756 - struct clk_init_data init;
51760 rk_phy = devm_kzalloc(base->dev, sizeof(*rk_phy), GFP_KERNEL);
51761 @@ -214,6 +800,7 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
51763 rk_phy->base = base;
51764 rk_phy->np = child;
51765 + mutex_init(&rk_phy->mutex);
51768 dev_err(base->dev, "missing reg property in node %pOFn\n",
51769 @@ -288,6 +875,12 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
51771 phy_set_drvdata(rk_phy->phy, rk_phy);
51773 + if (of_device_is_compatible(np, "rockchip,rk3288-usb-phy")) {
51779 rk_phy->vbus = devm_regulator_get_optional(&rk_phy->phy->dev, "vbus");
51780 if (IS_ERR(rk_phy->vbus)) {
51781 if (PTR_ERR(rk_phy->vbus) == -EPROBE_DEFER)
51782 @@ -402,10 +995,6 @@ static const struct rockchip_usb_phy_pdata rk3188_pdata = {
51786 -#define RK3288_UOC0_CON3 0x32c
51787 -#define RK3288_UOC0_CON3_BYPASSDMEN BIT(6)
51788 -#define RK3288_UOC0_CON3_BYPASSSEL BIT(7)
51789 -
51793 @@ -487,6 +1076,10 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
51794 return PTR_ERR(phy_base->reg_base);
51801 for_each_available_child_of_node(dev->of_node, child) {
51804 @@ -496,6 +1089,7 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
51812 diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
51814 --- a/drivers/pinctrl/Kconfig
51816 @@ -207,13 +207,18 @@ config PINCTRL_OXNAS
51820 - bool
51835 tristate "One-register-per-pin type device tree based pinctrl driver"
51836 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
51838 --- a/drivers/pinctrl/Makefile
51840 @@ -72,3 +72,5 @@ obj-y += mediatek/
51841 obj-$(CONFIG_PINCTRL_ZX) += zte/
51842 obj-y += cirrus/
51843 obj-$(CONFIG_PINCTRL_VISCONTI) += visconti/
51845 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/pinctrl
51846 diff --git a/drivers/pinctrl/pinctrl-rk805.c b/drivers/pinctrl/pinctrl-rk805.c
51848 --- a/drivers/pinctrl/pinctrl-rk805.c
51849 +++ b/drivers/pinctrl/pinctrl-rk805.c
51850 @@ -78,6 +78,7 @@ struct rk805_pctrl_info {
51858 @@ -132,12 +133,167 @@ static const struct rk805_pin_config rk805_gpio_cfgs[] = {
52017 + if (!pci->pin_cfg[offset].val_msk) {
52018 + dev_dbg(pci->dev, "getting gpio%d value is not support\n",
52020 + return -1;
52023 ret = regmap_read(pci->rk808->regmap, pci->pin_cfg[offset].reg, &val);
52025 dev_err(pci->dev, "get gpio%d value failed\n", offset);
52026 @@ -154,6 +310,9 @@ static void rk805_gpio_set(struct gpio_chip *chip,
52030 + if (!pci->pin_cfg[offset].val_msk)
52033 ret = regmap_update_bits(pci->rk808->regmap,
52034 pci->pin_cfg[offset].reg,
52035 pci->pin_cfg[offset].val_msk,
52036 @@ -214,6 +373,34 @@ static const struct gpio_chip rk805_gpio_chip = {
52041 + .label = "rk816-gpio",
52050 + .base = -1,
52055 + .label = "rk817-gpio",
52064 + .base = -1,
52071 @@ -289,7 +476,7 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
52072 if (!pci->pin_cfg[offset].fun_msk)
52075 - if (mux == RK805_PINMUX_GPIO) {
52077 ret = regmap_update_bits(pci->rk808->regmap,
52078 pci->pin_cfg[offset].reg,
52079 pci->pin_cfg[offset].fun_msk,
52080 @@ -298,6 +485,15 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
52081 dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
52085 + ret = regmap_update_bits(pci->rk808->regmap,
52086 + pci->pin_cfg[offset].reg,
52087 + pci->pin_cfg[offset].fun_msk,
52090 + dev_err(pci->dev, "set gpio%d TS failed\n", offset);
52094 dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
52095 return -EINVAL;
52096 @@ -306,6 +502,27 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
52107 + if (!pci->pin_cfg[offset].fun_msk)
52110 + mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1;
52111 + ret = regmap_update_bits(pci->rk808->regmap,
52112 + pci->pin_cfg[offset].reg,
52113 + pci->pin_cfg[offset].fun_msk, mux);
52116 + dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux);
52124 @@ -314,7 +531,18 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
52125 int mux = pci->functions[function].mux_option;
52128 - return _rk805_pinctrl_set_mux(pctldev, offset, mux);
52129 + switch (pci->rk808->variant) {
52138 + dev_err(pci->dev, "Couldn't find the variant id\n");
52139 + return -EINVAL;
52144 @@ -324,13 +552,6 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
52148 - /* switch to gpio function */
52149 - ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
52150 - if (ret) {
52151 - dev_err(pci->dev, "set gpio%d mux failed\n", offset);
52152 - return ret;
52153 - }
52154 -
52156 if (!pci->pin_cfg[offset].dir_msk)
52158 @@ -347,7 +568,25 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
52169 + switch (pci->rk808->variant) {
52184 @@ -364,6 +603,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
52189 arg = rk805_gpio_get(&pci->gpio_chip, pin);
52192 @@ -390,8 +630,13 @@ static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
52196 - rk805_gpio_set(&pci->gpio_chip, pin, arg);
52198 + rk805_gpio_set(&pci->gpio_chip, pin, arg);
52206 dev_err(pci->dev, "Properties not supported\n");
52207 @@ -415,9 +660,26 @@ static const struct pinctrl_desc rk805_pinctrl_desc = {
52212 + .name = "rk816-pinctrl",
52220 + .name = "rk817-pinctrl",
52233 pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
52234 @@ -425,18 +687,19 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
52235 return -ENOMEM;
52237 pci->dev = &pdev->dev;
52238 - pci->dev->of_node = pdev->dev.parent->of_node;
52239 + np = of_get_child_by_name(pdev->dev.parent->of_node, "pinctrl_rk8xx");
52241 + pci->dev->of_node = np;
52243 + pci->dev->of_node = pdev->dev.parent->of_node;
52244 pci->rk808 = dev_get_drvdata(pdev->dev.parent);
52246 - pci->pinctrl_desc = rk805_pinctrl_desc;
52247 - pci->gpio_chip = rk805_gpio_chip;
52248 - pci->gpio_chip.parent = &pdev->dev;
52249 - pci->gpio_chip.of_node = pdev->dev.parent->of_node;
52250 -
52253 switch (pci->rk808->variant) {
52255 + pci->pinctrl_desc = rk805_pinctrl_desc;
52256 + pci->gpio_chip = rk805_gpio_chip;
52257 pci->pins = rk805_pins_desc;
52258 pci->num_pins = ARRAY_SIZE(rk805_pins_desc);
52259 pci->functions = rk805_pin_functions;
52260 @@ -448,13 +711,59 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
52261 pci->pin_cfg = rk805_gpio_cfgs;
52262 pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
52266 + pci->pinctrl_desc = rk816_pinctrl_desc;
52267 + pci->gpio_chip = rk816_gpio_chip;
52268 + pci->pins = rk816_pins_desc;
52269 + pci->num_pins = ARRAY_SIZE(rk816_pins_desc);
52270 + pci->functions = rk816_pin_functions;
52271 + pci->num_functions = ARRAY_SIZE(rk816_pin_functions);
52272 + pci->groups = rk816_pin_groups;
52273 + pci->num_pin_groups = ARRAY_SIZE(rk816_pin_groups);
52274 + pci->pinctrl_desc.pins = rk816_pins_desc;
52275 + pci->pinctrl_desc.npins = ARRAY_SIZE(rk816_pins_desc);
52276 + pci->pin_cfg = rk816_gpio_cfgs;
52277 + pci->gpio_chip.ngpio = ARRAY_SIZE(rk816_gpio_cfgs);
52282 + pci->pinctrl_desc = rk817_pinctrl_desc;
52283 + pci->gpio_chip = rk817_gpio_chip;
52284 + pci->pins = rk817_pins_desc;
52285 + pci->num_pins = ARRAY_SIZE(rk817_pins_desc);
52286 + pci->functions = rk817_pin_functions;
52287 + pci->num_functions = ARRAY_SIZE(rk817_pin_functions);
52288 + pci->groups = rk817_pin_groups;
52289 + pci->num_pin_groups = ARRAY_SIZE(rk817_pin_groups);
52290 + pci->pinctrl_desc.pins = rk817_pins_desc;
52291 + pci->pinctrl_desc.npins = ARRAY_SIZE(rk817_pins_desc);
52292 + pci->pin_cfg = rk817_gpio_cfgs;
52293 + pci->gpio_chip.ngpio = ARRAY_SIZE(rk817_gpio_cfgs);
52295 + if (pci->rk808->variant == RK809_ID) {
52296 + pci->pinctrl_desc.npins = 1;
52297 + pci->num_pin_groups = 1;
52298 + pci->num_pins = 1;
52299 + pci->gpio_chip.ngpio = 1;
52304 dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
52305 pci->rk808->variant);
52306 return -EINVAL;
52309 - /* Add gpio chip */
52310 + pci->gpio_chip.parent = &pdev->dev;
52313 + pci->gpio_chip.of_node = np;
52315 + pci->gpio_chip.of_node = pdev->dev.parent->of_node;
52318 ret = devm_gpiochip_add_data(&pdev->dev, &pci->gpio_chip, pci);
52320 dev_err(&pdev->dev, "Couldn't add gpiochip\n");
52321 @@ -485,7 +794,12 @@ static struct platform_driver rk805_pinctrl_driver = {
52322 .name = "rk805-pinctrl",
52325 -module_platform_driver(rk805_pinctrl_driver);
52334 MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
52335 diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
52337 --- a/drivers/pinctrl/pinctrl-rockchip.c
52338 +++ b/drivers/pinctrl/pinctrl-rockchip.c
52339 @@ -16,12 +16,14 @@
52347 -#include <linux/gpio/driver.h>
52355 @@ -31,37 +33,19 @@
52360 #include <dt-bindings/pinctrl/rockchip.h>
52364 +#include "pinctrl-rockchip.h"
52366 -/* GPIO control registers */
52367 -#define GPIO_SWPORT_DR 0x00
52368 -#define GPIO_SWPORT_DDR 0x04
52369 -#define GPIO_INTEN 0x30
52370 -#define GPIO_INTMASK 0x34
52371 -#define GPIO_INTTYPE_LEVEL 0x38
52372 -#define GPIO_INT_POLARITY 0x3c
52373 -#define GPIO_INT_STATUS 0x40
52374 -#define GPIO_INT_RAWSTATUS 0x44
52375 -#define GPIO_DEBOUNCE 0x48
52376 -#define GPIO_PORTS_EOI 0x4c
52377 -#define GPIO_EXT_PORT 0x50
52378 -#define GPIO_LS_SYNC 0x60
52379 -
52380 -enum rockchip_pinctrl_type {
52381 - PX30,
52382 - RV1108,
52383 - RK2928,
52384 - RK3066B,
52385 - RK3128,
52386 - RK3188,
52387 - RK3288,
52388 - RK3308,
52389 - RK3368,
52390 - RK3399,
52391 -};
52401 @@ -72,103 +56,8 @@ enum rockchip_pinctrl_type {
52405 -
52406 -/**
52407 - * struct rockchip_iomux
52408 - * @type: iomux variant using IOMUX_* constants
52409 - * @offset: if initialized to -1 it will be autocalculated, by specifying
52410 - * an initial offset value the relevant source offset can be reset
52411 - * to a new value for autocalculating the following iomux registers.
52412 - */
52413 -struct rockchip_iomux {
52414 - int type;
52415 - int offset;
52416 -};
52417 -
52418 -/*
52419 - * enum type index corresponding to rockchip_perpin_drv_list arrays index.
52420 - */
52421 -enum rockchip_pin_drv_type {
52422 - DRV_TYPE_IO_DEFAULT = 0,
52423 - DRV_TYPE_IO_1V8_OR_3V0,
52424 - DRV_TYPE_IO_1V8_ONLY,
52425 - DRV_TYPE_IO_1V8_3V0_AUTO,
52426 - DRV_TYPE_IO_3V3_ONLY,
52427 - DRV_TYPE_MAX
52428 -};
52429 -
52430 -/*
52431 - * enum type index corresponding to rockchip_pull_list arrays index.
52432 - */
52433 -enum rockchip_pin_pull_type {
52434 - PULL_TYPE_IO_DEFAULT = 0,
52435 - PULL_TYPE_IO_1V8_ONLY,
52436 - PULL_TYPE_MAX
52437 -};
52438 -
52439 -/**
52440 - * struct rockchip_drv
52441 - * @drv_type: drive strength variant using rockchip_perpin_drv_type
52442 - * @offset: if initialized to -1 it will be autocalculated, by specifying
52443 - * an initial offset value the relevant source offset can be reset
52444 - * to a new value for autocalculating the following drive strength
52445 - * registers. if used chips own cal_drv func instead to calculate
52446 - * registers offset, the variant could be ignored.
52447 - */
52448 -struct rockchip_drv {
52449 - enum rockchip_pin_drv_type drv_type;
52450 - int offset;
52451 -};
52452 -
52453 -/**
52454 - * struct rockchip_pin_bank
52455 - * @reg_base: register base of the gpio bank
52456 - * @regmap_pull: optional separate register for additional pull settings
52457 - * @clk: clock of the gpio bank
52458 - * @irq: interrupt of the gpio bank
52459 - * @saved_masks: Saved content of GPIO_INTEN at suspend time.
52460 - * @pin_base: first pin number
52461 - * @nr_pins: number of pins in this bank
52462 - * @name: name of the bank
52463 - * @bank_num: number of the bank, to account for holes
52464 - * @iomux: array describing the 4 iomux sources of the bank
52465 - * @drv: array describing the 4 drive strength sources of the bank
52466 - * @pull_type: array describing the 4 pull type sources of the bank
52467 - * @valid: is all necessary information present
52468 - * @of_node: dt node of this bank
52469 - * @drvdata: common pinctrl basedata
52470 - * @domain: irqdomain of the gpio bank
52471 - * @gpio_chip: gpiolib chip
52472 - * @grange: gpio range
52473 - * @slock: spinlock for the gpio bank
52474 - * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode
52475 - * @recalced_mask: bit mask to indicate a need to recalulate the mask
52476 - * @route_mask: bits describing the routing pins of per bank
52477 - */
52478 -struct rockchip_pin_bank {
52479 - void __iomem *reg_base;
52480 - struct regmap *regmap_pull;
52481 - struct clk *clk;
52482 - int irq;
52483 - u32 saved_masks;
52484 - u32 pin_base;
52485 - u8 nr_pins;
52486 - char *name;
52487 - u8 bank_num;
52488 - struct rockchip_iomux iomux[4];
52489 - struct rockchip_drv drv[4];
52490 - enum rockchip_pin_pull_type pull_type[4];
52491 - bool valid;
52492 - struct device_node *of_node;
52493 - struct rockchip_pinctrl *drvdata;
52494 - struct irq_domain *domain;
52495 - struct gpio_chip gpio_chip;
52496 - struct pinctrl_gpio_range grange;
52497 - raw_spinlock_t slock;
52498 - u32 toggle_edge_mode;
52499 - u32 recalced_mask;
52500 - u32 route_mask;
52501 -};
52507 @@ -196,6 +85,21 @@ struct rockchip_pin_bank {
52529 @@ -290,118 +194,24 @@ struct rockchip_pin_bank {
52533 -/**
52534 - * struct rockchip_mux_recalced_data: represent a pin iomux data.
52535 - * @num: bank number.
52536 - * @pin: pin number.
52537 - * @bit: index at register.
52538 - * @reg: register offset.
52539 - * @mask: mask bit
52540 - */
52541 -struct rockchip_mux_recalced_data {
52542 - u8 num;
52543 - u8 pin;
52544 - u32 reg;
52545 - u8 bit;
52546 - u8 mask;
52547 -};
52548 -
52549 -enum rockchip_mux_route_location {
52550 - ROCKCHIP_ROUTE_SAME = 0,
52551 - ROCKCHIP_ROUTE_PMU,
52552 - ROCKCHIP_ROUTE_GRF,
52553 -};
52554 -
52555 -/**
52556 - * struct rockchip_mux_recalced_data: represent a pin iomux data.
52557 - * @bank_num: bank number.
52558 - * @pin: index at register or used to calc index.
52559 - * @func: the min pin.
52560 - * @route_location: the mux route location (same, pmu, grf).
52561 - * @route_offset: the max pin.
52562 - * @route_val: the register offset.
52563 - */
52564 -struct rockchip_mux_route_data {
52565 - u8 bank_num;
52566 - u8 pin;
52567 - u8 func;
52568 - enum rockchip_mux_route_location route_location;
52569 - u32 route_offset;
52570 - u32 route_val;
52571 -};
52572 -
52573 -struct rockchip_pin_ctrl {
52574 - struct rockchip_pin_bank *pin_banks;
52575 - u32 nr_banks;
52576 - u32 nr_pins;
52577 - char *label;
52578 - enum rockchip_pinctrl_type type;
52579 - int grf_mux_offset;
52580 - int pmu_mux_offset;
52581 - int grf_drv_offset;
52582 - int pmu_drv_offset;
52583 - struct rockchip_mux_recalced_data *iomux_recalced;
52584 - u32 niomux_recalced;
52585 - struct rockchip_mux_route_data *iomux_routes;
52586 - u32 niomux_routes;
52587 -
52588 - void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
52589 - int pin_num, struct regmap **regmap,
52590 - int *reg, u8 *bit);
52591 - void (*drv_calc_reg)(struct rockchip_pin_bank *bank,
52592 - int pin_num, struct regmap **regmap,
52593 - int *reg, u8 *bit);
52594 - int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
52595 - int pin_num, struct regmap **regmap,
52596 - int *reg, u8 *bit);
52597 -};
52598 -
52599 -struct rockchip_pin_config {
52600 - unsigned int func;
52601 - unsigned long *configs;
52602 - unsigned int nconfigs;
52603 -};
52614 -/**
52615 - * struct rockchip_pin_group: represent group of pins of a pinmux function.
52616 - * @name: name of the pin group, used to lookup the group.
52617 - * @pins: the pins included in this group.
52618 - * @npins: number of pins included in this group.
52619 - * @data: local pin configuration
52620 - */
52621 -struct rockchip_pin_group {
52622 - const char *name;
52623 - unsigned int npins;
52624 - unsigned int *pins;
52625 - struct rockchip_pin_config *data;
52626 -};
52630 -/**
52631 - * struct rockchip_pmx_func: represent a pin function.
52632 - * @name: name of the pin function, used to lookup the function.
52633 - * @groups: one or more names of pin groups that provide this function.
52634 - * @ngroups: number of groups included in @groups.
52635 - */
52636 -struct rockchip_pmx_func {
52637 - const char *name;
52638 - const char **groups;
52639 - u8 ngroups;
52640 -};
52644 -struct rockchip_pinctrl {
52645 - struct regmap *regmap_base;
52646 - int reg_size;
52647 - struct regmap *regmap_pull;
52648 - struct regmap *regmap_pmu;
52649 - struct device *dev;
52650 - struct rockchip_pin_ctrl *ctrl;
52651 - struct pinctrl_desc pctl;
52652 - struct pinctrl_dev *pctl_dev;
52653 - struct rockchip_pin_group *groups;
52654 - unsigned int ngroups;
52655 - struct rockchip_pmx_func *functions;
52656 - unsigned int nfunctions;
52657 -};
52663 @@ -627,6 +437,37 @@ static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
52701 @@ -757,11 +598,47 @@ static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
52749 @@ -777,6 +654,103 @@ static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
52853 @@ -800,598 +774,218 @@ static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int p…
52854 *bit = data->bit;
52872 - {
52873 - /* cif-d2m0 */
52874 - .bank_num = 2,
52875 - .pin = 0,
52876 - .func = 1,
52877 - .route_offset = 0x184,
52878 - .route_val = BIT(16 + 7),
52879 - }, {
52880 - /* cif-d2m1 */
52881 - .bank_num = 3,
52882 - .pin = 3,
52883 - .func = 3,
52884 - .route_offset = 0x184,
52885 - .route_val = BIT(16 + 7) | BIT(7),
52886 - }, {
52887 - /* pdm-m0 */
52888 - .bank_num = 3,
52889 - .pin = 22,
52890 - .func = 2,
52891 - .route_offset = 0x184,
52892 - .route_val = BIT(16 + 8),
52893 - }, {
52894 - /* pdm-m1 */
52895 - .bank_num = 2,
52896 - .pin = 22,
52897 - .func = 1,
52898 - .route_offset = 0x184,
52899 - .route_val = BIT(16 + 8) | BIT(8),
52900 - }, {
52901 - /* uart2-rxm0 */
52902 - .bank_num = 1,
52903 - .pin = 27,
52904 - .func = 2,
52905 - .route_offset = 0x184,
52906 - .route_val = BIT(16 + 10),
52907 - }, {
52908 - /* uart2-rxm1 */
52909 - .bank_num = 2,
52910 - .pin = 14,
52911 - .func = 2,
52912 - .route_offset = 0x184,
52913 - .route_val = BIT(16 + 10) | BIT(10),
52914 - }, {
52915 - /* uart3-rxm0 */
52916 - .bank_num = 0,
52917 - .pin = 17,
52918 - .func = 2,
52919 - .route_offset = 0x184,
52920 - .route_val = BIT(16 + 9),
52921 - }, {
52922 - /* uart3-rxm1 */
52923 - .bank_num = 1,
52924 - .pin = 15,
52925 - .func = 2,
52926 - .route_offset = 0x184,
52927 - .route_val = BIT(16 + 9) | BIT(9),
52928 - },
52929 + RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */
52930 + RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */
52931 + RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */
52932 + RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */
52933 + RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */
52934 + RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */
52935 + RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */
52936 + RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */
52940 - {
52941 - /* spi-0 */
52942 - .bank_num = 1,
52943 - .pin = 10,
52944 - .func = 1,
52945 - .route_offset = 0x144,
52946 - .route_val = BIT(16 + 3) | BIT(16 + 4),
52947 - }, {
52948 - /* spi-1 */
52949 - .bank_num = 1,
52950 - .pin = 27,
52951 - .func = 3,
52952 - .route_offset = 0x144,
52953 - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3),
52954 - }, {
52955 - /* spi-2 */
52956 - .bank_num = 0,
52957 - .pin = 13,
52958 - .func = 2,
52959 - .route_offset = 0x144,
52960 - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4),
52961 - }, {
52962 - /* i2s-0 */
52963 - .bank_num = 1,
52964 - .pin = 5,
52965 - .func = 1,
52966 - .route_offset = 0x144,
52967 - .route_val = BIT(16 + 5),
52968 - }, {
52969 - /* i2s-1 */
52970 - .bank_num = 0,
52971 - .pin = 14,
52972 - .func = 1,
52973 - .route_offset = 0x144,
52974 - .route_val = BIT(16 + 5) | BIT(5),
52975 - }, {
52976 - /* emmc-0 */
52977 - .bank_num = 1,
52978 - .pin = 22,
52979 - .func = 2,
52980 - .route_offset = 0x144,
52981 - .route_val = BIT(16 + 6),
52982 - }, {
52983 - /* emmc-1 */
52984 - .bank_num = 2,
52985 - .pin = 4,
52986 - .func = 2,
52987 - .route_offset = 0x144,
52988 - .route_val = BIT(16 + 6) | BIT(6),
52989 - },
52990 + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */
52991 + RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */
52992 + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */
52993 + RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */
52994 + RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */
52995 + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */
52996 + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */
53000 - {
53001 - /* non-iomuxed emmc/flash pins on flash-dqs */
53002 - .bank_num = 0,
53003 - .pin = 24,
53004 - .func = 1,
53005 - .route_location = ROCKCHIP_ROUTE_GRF,
53006 - .route_offset = 0xa0,
53007 - .route_val = BIT(16 + 11),
53008 - }, {
53009 - /* non-iomuxed emmc/flash pins on emmc-clk */
53010 - .bank_num = 0,
53011 - .pin = 24,
53012 - .func = 2,
53013 - .route_location = ROCKCHIP_ROUTE_GRF,
53014 - .route_offset = 0xa0,
53015 - .route_val = BIT(16 + 11) | BIT(11),
53016 - },
53017 + RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
53018 …UTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
53022 - {
53023 - /* pwm0-0 */
53024 - .bank_num = 0,
53025 - .pin = 26,
53026 - .func = 1,
53027 - .route_offset = 0x50,
53028 - .route_val = BIT(16),
53029 - }, {
53030 - /* pwm0-1 */
53031 - .bank_num = 3,
53032 - .pin = 21,
53033 - .func = 1,
53034 - .route_offset = 0x50,
53035 - .route_val = BIT(16) | BIT(0),
53036 - }, {
53037 - /* pwm1-0 */
53038 - .bank_num = 0,
53039 - .pin = 27,
53040 - .func = 1,
53041 - .route_offset = 0x50,
53042 - .route_val = BIT(16 + 1),
53043 - }, {
53044 - /* pwm1-1 */
53045 - .bank_num = 0,
53046 - .pin = 30,
53047 - .func = 2,
53048 - .route_offset = 0x50,
53049 - .route_val = BIT(16 + 1) | BIT(1),
53050 - }, {
53051 - /* pwm2-0 */
53052 - .bank_num = 0,
53053 - .pin = 28,
53054 - .func = 1,
53055 - .route_offset = 0x50,
53056 - .route_val = BIT(16 + 2),
53057 - }, {
53058 - /* pwm2-1 */
53059 - .bank_num = 1,
53060 - .pin = 12,
53061 - .func = 2,
53062 - .route_offset = 0x50,
53063 - .route_val = BIT(16 + 2) | BIT(2),
53064 - }, {
53065 - /* pwm3-0 */
53066 - .bank_num = 3,
53067 - .pin = 26,
53068 - .func = 1,
53069 - .route_offset = 0x50,
53070 - .route_val = BIT(16 + 3),
53071 - }, {
53072 - /* pwm3-1 */
53073 - .bank_num = 1,
53074 - .pin = 11,
53075 - .func = 2,
53076 - .route_offset = 0x50,
53077 - .route_val = BIT(16 + 3) | BIT(3),
53078 - }, {
53079 - /* sdio-0_d0 */
53080 - .bank_num = 1,
53081 - .pin = 1,
53082 - .func = 1,
53083 - .route_offset = 0x50,
53084 - .route_val = BIT(16 + 4),
53085 - }, {
53086 - /* sdio-1_d0 */
53087 - .bank_num = 3,
53088 - .pin = 2,
53089 - .func = 1,
53090 - .route_offset = 0x50,
53091 - .route_val = BIT(16 + 4) | BIT(4),
53092 - }, {
53093 - /* spi-0_rx */
53094 - .bank_num = 0,
53095 - .pin = 13,
53096 - .func = 2,
53097 - .route_offset = 0x50,
53098 - .route_val = BIT(16 + 5),
53099 - }, {
53100 - /* spi-1_rx */
53101 - .bank_num = 2,
53102 - .pin = 0,
53103 - .func = 2,
53104 - .route_offset = 0x50,
53105 - .route_val = BIT(16 + 5) | BIT(5),
53106 - }, {
53107 - /* emmc-0_cmd */
53108 - .bank_num = 1,
53109 - .pin = 22,
53110 - .func = 2,
53111 - .route_offset = 0x50,
53112 - .route_val = BIT(16 + 7),
53113 - }, {
53114 - /* emmc-1_cmd */
53115 - .bank_num = 2,
53116 - .pin = 4,
53117 - .func = 2,
53118 - .route_offset = 0x50,
53119 - .route_val = BIT(16 + 7) | BIT(7),
53120 - }, {
53121 - /* uart2-0_rx */
53122 - .bank_num = 1,
53123 - .pin = 19,
53124 - .func = 2,
53125 - .route_offset = 0x50,
53126 - .route_val = BIT(16 + 8),
53127 - }, {
53128 - /* uart2-1_rx */
53129 - .bank_num = 1,
53130 - .pin = 10,
53131 - .func = 2,
53132 - .route_offset = 0x50,
53133 - .route_val = BIT(16 + 8) | BIT(8),
53134 - }, {
53135 - /* uart1-0_rx */
53136 - .bank_num = 1,
53137 - .pin = 10,
53138 - .func = 1,
53139 - .route_offset = 0x50,
53140 - .route_val = BIT(16 + 11),
53141 - }, {
53142 - /* uart1-1_rx */
53143 - .bank_num = 3,
53144 - .pin = 13,
53145 - .func = 1,
53146 - .route_offset = 0x50,
53147 - .route_val = BIT(16 + 11) | BIT(11),
53148 - },
53149 + RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */
53150 + RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */
53151 + RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */
53152 + RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */
53153 + RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */
53154 + RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */
53155 + RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */
53156 + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */
53157 + RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */
53158 + RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */
53159 + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */
53160 + RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */
53161 + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */
53162 + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */
53163 + RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */
53164 + RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */
53165 + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */
53166 + RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */
53170 - {
53171 - /* edphdmi_cecinoutt1 */
53172 - .bank_num = 7,
53173 - .pin = 16,
53174 - .func = 2,
53175 - .route_offset = 0x264,
53176 - .route_val = BIT(16 + 12) | BIT(12),
53177 - }, {
53178 - /* edphdmi_cecinout */
53179 - .bank_num = 7,
53180 - .pin = 23,
53181 - .func = 4,
53182 - .route_offset = 0x264,
53183 - .route_val = BIT(16 + 12),
53184 - },
53190 - {
53191 - /* rtc_clk */
53192 - .bank_num = 0,
53193 - .pin = 19,
53194 - .func = 1,
53195 - .route_offset = 0x314,
53196 - .route_val = BIT(16 + 0) | BIT(0),
53197 - }, {
53198 - /* uart2_rxm0 */
53199 - .bank_num = 1,
53200 - .pin = 22,
53201 - .func = 2,
53202 - .route_offset = 0x314,
53203 - .route_val = BIT(16 + 2) | BIT(16 + 3),
53204 - }, {
53205 - /* uart2_rxm1 */
53206 - .bank_num = 4,
53207 - .pin = 26,
53208 - .func = 2,
53209 - .route_offset = 0x314,
53210 - .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
53211 - }, {
53212 - /* i2c3_sdam0 */
53213 - .bank_num = 0,
53214 - .pin = 15,
53215 - .func = 2,
53216 - .route_offset = 0x608,
53217 - .route_val = BIT(16 + 8) | BIT(16 + 9),
53218 - }, {
53219 - /* i2c3_sdam1 */
53220 - .bank_num = 3,
53221 - .pin = 12,
53222 - .func = 2,
53223 - .route_offset = 0x608,
53224 - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8),
53225 - }, {
53226 - /* i2c3_sdam2 */
53227 - .bank_num = 2,
53228 - .pin = 0,
53229 - .func = 3,
53230 - .route_offset = 0x608,
53231 - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9),
53232 - }, {
53233 - /* i2s-8ch-1-sclktxm0 */
53234 - .bank_num = 1,
53235 - .pin = 3,
53236 - .func = 2,
53237 - .route_offset = 0x308,
53238 - .route_val = BIT(16 + 3),
53239 - }, {
53240 - /* i2s-8ch-1-sclkrxm0 */
53241 - .bank_num = 1,
53242 - .pin = 4,
53243 - .func = 2,
53244 - .route_offset = 0x308,
53245 - .route_val = BIT(16 + 3),
53246 - }, {
53247 - /* i2s-8ch-1-sclktxm1 */
53248 - .bank_num = 1,
53249 - .pin = 13,
53250 - .func = 2,
53251 - .route_offset = 0x308,
53252 - .route_val = BIT(16 + 3) | BIT(3),
53253 - }, {
53254 - /* i2s-8ch-1-sclkrxm1 */
53255 - .bank_num = 1,
53256 - .pin = 14,
53257 - .func = 2,
53258 - .route_offset = 0x308,
53259 - .route_val = BIT(16 + 3) | BIT(3),
53260 - }, {
53261 - /* pdm-clkm0 */
53262 - .bank_num = 1,
53263 - .pin = 4,
53264 - .func = 3,
53265 - .route_offset = 0x308,
53266 - .route_val = BIT(16 + 12) | BIT(16 + 13),
53267 - }, {
53268 - /* pdm-clkm1 */
53269 - .bank_num = 1,
53270 - .pin = 14,
53271 - .func = 4,
53272 - .route_offset = 0x308,
53273 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
53274 - }, {
53275 - /* pdm-clkm2 */
53276 - .bank_num = 2,
53277 - .pin = 6,
53278 - .func = 2,
53279 - .route_offset = 0x308,
53280 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
53281 - }, {
53282 - /* pdm-clkm-m2 */
53283 - .bank_num = 2,
53284 - .pin = 4,
53285 - .func = 3,
53286 - .route_offset = 0x600,
53287 - .route_val = BIT(16 + 2) | BIT(2),
53288 - }, {
53289 - /* spi1_miso */
53290 - .bank_num = 3,
53291 - .pin = 10,
53292 - .func = 3,
53293 - .route_offset = 0x314,
53294 - .route_val = BIT(16 + 9),
53295 - }, {
53296 - /* spi1_miso_m1 */
53297 - .bank_num = 2,
53298 - .pin = 4,
53299 - .func = 2,
53300 - .route_offset = 0x314,
53301 - .route_val = BIT(16 + 9) | BIT(9),
53302 - }, {
53303 - /* owire_m0 */
53304 - .bank_num = 0,
53305 - .pin = 11,
53306 - .func = 3,
53307 - .route_offset = 0x314,
53308 - .route_val = BIT(16 + 10) | BIT(16 + 11),
53309 - }, {
53310 - /* owire_m1 */
53311 - .bank_num = 1,
53312 - .pin = 22,
53313 - .func = 7,
53314 - .route_offset = 0x314,
53315 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
53316 - }, {
53317 - /* owire_m2 */
53318 - .bank_num = 2,
53319 - .pin = 2,
53320 - .func = 5,
53321 - .route_offset = 0x314,
53322 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
53323 - }, {
53324 - /* can_rxd_m0 */
53325 - .bank_num = 0,
53326 - .pin = 11,
53327 - .func = 2,
53328 - .route_offset = 0x314,
53329 - .route_val = BIT(16 + 12) | BIT(16 + 13),
53330 - }, {
53331 - /* can_rxd_m1 */
53332 - .bank_num = 1,
53333 - .pin = 22,
53334 - .func = 5,
53335 - .route_offset = 0x314,
53336 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
53337 - }, {
53338 - /* can_rxd_m2 */
53339 - .bank_num = 2,
53340 - .pin = 2,
53341 - .func = 4,
53342 - .route_offset = 0x314,
53343 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
53344 - }, {
53345 - /* mac_rxd0_m0 */
53346 - .bank_num = 1,
53347 - .pin = 20,
53348 - .func = 3,
53349 - .route_offset = 0x314,
53350 - .route_val = BIT(16 + 14),
53351 - }, {
53352 - /* mac_rxd0_m1 */
53353 - .bank_num = 4,
53354 - .pin = 2,
53355 - .func = 2,
53356 - .route_offset = 0x314,
53357 - .route_val = BIT(16 + 14) | BIT(14),
53358 - }, {
53359 - /* uart3_rx */
53360 - .bank_num = 3,
53361 - .pin = 12,
53362 - .func = 4,
53363 - .route_offset = 0x314,
53364 - .route_val = BIT(16 + 15),
53365 - }, {
53366 - /* uart3_rx_m1 */
53367 - .bank_num = 0,
53368 - .pin = 17,
53369 - .func = 3,
53370 - .route_offset = 0x314,
53371 - .route_val = BIT(16 + 15) | BIT(15),
53372 - },
53379 + RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */
53380 + RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */
53381 + RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */
53382 + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */
53383 + RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */
53384 + RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */
53385 + RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */
53386 + RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */
53402 - {
53403 - /* uart2dbg_rxm0 */
53404 - .bank_num = 1,
53405 - .pin = 1,
53406 - .func = 2,
53407 - .route_offset = 0x50,
53408 - .route_val = BIT(16) | BIT(16 + 1),
53409 - }, {
53410 - /* uart2dbg_rxm1 */
53411 - .bank_num = 2,
53412 - .pin = 1,
53413 - .func = 1,
53414 - .route_offset = 0x50,
53415 - .route_val = BIT(16) | BIT(16 + 1) | BIT(0),
53416 - }, {
53417 - /* gmac-m1_rxd0 */
53418 - .bank_num = 1,
53419 - .pin = 11,
53420 - .func = 2,
53421 - .route_offset = 0x50,
53422 - .route_val = BIT(16 + 2) | BIT(2),
53423 - }, {
53424 - /* gmac-m1-optimized_rxd3 */
53425 - .bank_num = 1,
53426 - .pin = 14,
53427 - .func = 2,
53428 - .route_offset = 0x50,
53429 - .route_val = BIT(16 + 10) | BIT(10),
53430 - }, {
53431 - /* pdm_sdi0m0 */
53432 - .bank_num = 2,
53433 - .pin = 19,
53434 - .func = 2,
53435 - .route_offset = 0x50,
53436 - .route_val = BIT(16 + 3),
53437 - }, {
53438 - /* pdm_sdi0m1 */
53439 - .bank_num = 1,
53440 - .pin = 23,
53441 - .func = 3,
53442 - .route_offset = 0x50,
53443 - .route_val = BIT(16 + 3) | BIT(3),
53444 - }, {
53445 - /* spi_rxdm2 */
53446 - .bank_num = 3,
53447 - .pin = 2,
53448 - .func = 4,
53449 - .route_offset = 0x50,
53450 - .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5),
53451 - }, {
53452 - /* i2s2_sdim0 */
53453 - .bank_num = 1,
53454 - .pin = 24,
53455 - .func = 1,
53456 - .route_offset = 0x50,
53457 - .route_val = BIT(16 + 6),
53458 - }, {
53459 - /* i2s2_sdim1 */
53460 - .bank_num = 3,
53461 - .pin = 2,
53462 - .func = 6,
53463 - .route_offset = 0x50,
53464 - .route_val = BIT(16 + 6) | BIT(6),
53465 - }, {
53466 - /* card_iom1 */
53467 - .bank_num = 2,
53468 - .pin = 22,
53469 - .func = 3,
53470 - .route_offset = 0x50,
53471 - .route_val = BIT(16 + 7) | BIT(7),
53472 - }, {
53473 - /* tsp_d5m1 */
53474 - .bank_num = 2,
53475 - .pin = 16,
53476 - .func = 3,
53477 - .route_offset = 0x50,
53478 - .route_val = BIT(16 + 8) | BIT(8),
53479 - }, {
53480 - /* cif_data5m1 */
53481 - .bank_num = 2,
53482 - .pin = 16,
53483 - .func = 4,
53484 - .route_offset = 0x50,
53485 - .route_val = BIT(16 + 9) | BIT(9),
53486 - },
53489 + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */
53490 + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */
53502 - {
53503 - /* uart2dbga_rx */
53504 - .bank_num = 4,
53505 - .pin = 8,
53506 - .func = 2,
53507 - .route_offset = 0xe21c,
53508 - .route_val = BIT(16 + 10) | BIT(16 + 11),
53509 - }, {
53510 - /* uart2dbgb_rx */
53511 - .bank_num = 4,
53512 - .pin = 16,
53513 - .func = 2,
53514 - .route_offset = 0xe21c,
53515 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
53516 - }, {
53517 - /* uart2dbgc_rx */
53518 - .bank_num = 4,
53519 - .pin = 19,
53520 - .func = 1,
53521 - .route_offset = 0xe21c,
53522 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
53523 - }, {
53524 - /* pcie_clkreqn */
53525 - .bank_num = 2,
53526 - .pin = 26,
53527 - .func = 2,
53528 - .route_offset = 0xe21c,
53529 - .route_val = BIT(16 + 14),
53530 - }, {
53531 - /* pcie_clkreqnb */
53532 - .bank_num = 4,
53533 - .pin = 24,
53534 - .func = 1,
53535 - .route_offset = 0xe21c,
53536 - .route_val = BIT(16 + 14) | BIT(14),
53537 - },
53598 + RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
53599 + RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
53642 @@ -1439,8 +1033,12 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
53643 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
53646 - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53647 - ? info->regmap_pmu : info->regmap_base;
53648 + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53649 + regmap = info->regmap_pmu;
53650 + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
53651 + regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base;
53653 + regmap = info->regmap_base;
53656 mux_type = bank->iomux[iomux_num].type;
53657 @@ -1527,8 +1125,12 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
53658 dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
53659 bank->bank_num, pin, mux);
53661 - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53662 - ? info->regmap_pmu : info->regmap_base;
53663 + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53664 + regmap = info->regmap_pmu;
53665 + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
53666 + regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base;
53668 + regmap = info->regmap_base;
53671 mux_type = bank->iomux[iomux_num].type;
53672 @@ -1551,6 +1153,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
53673 if (bank->recalced_mask & BIT(pin))
53677 + return -EINVAL;
53679 if (bank->route_mask & BIT(pin)) {
53682 @@ -1572,10 +1177,20 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mu…
53686 - data = (mask << (bit + 16));
53687 - rmask = data | (data >> 16);
53688 - data |= (mux & mask) << bit;
53689 - ret = regmap_update_bits(regmap, reg, rmask, data);
53707 @@ -1760,6 +1375,115 @@ static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
53722 + struct rockchip_pinctrl *info = bank->drvdata;
53725 + if (bank->bank_num == 0) {
53727 + *regmap = info->regmap_base;
53729 + *reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4);
53734 + *regmap = info->regmap_pmu;
53738 + *regmap = info->regmap_base;
53739 + *reg += (bank->bank_num - 1) * RV1126_PULL_BANK_STRIDE;
53757 + struct rockchip_pinctrl *info = bank->drvdata;
53760 + if (bank->bank_num == 0) {
53762 + *regmap = info->regmap_base;
53764 + *reg -= (((31 - pin_num) / RV1126_DRV_PINS_PER_REG + 1) * 4);
53765 + *reg -= 0x4;
53770 + *regmap = info->regmap_pmu;
53773 + *regmap = info->regmap_base;
53775 + *reg += (bank->bank_num - 1) * RV1126_DRV_BANK_STRIDE;
53794 + struct rockchip_pinctrl *info = bank->drvdata;
53797 + if (bank->bank_num == 0) {
53799 + *regmap = info->regmap_base;
53801 + *reg -= (((31 - pin_num) / RV1126_SCHMITT_PINS_PER_GRF_REG + 1) * 4);
53805 + *regmap = info->regmap_pmu;
53809 + *regmap = info->regmap_base;
53812 + *reg += (bank->bank_num - 1) * RV1126_SCHMITT_BANK_STRIDE;
53823 @@ -1780,6 +1504,111 @@ static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
53837 + struct rockchip_pinctrl *info = bank->drvdata;
53839 + if (bank->bank_num == 0) {
53840 + *regmap = info->regmap_pmu;
53844 + *regmap = info->regmap_base;
53845 + *reg += (bank->bank_num - 1) * RK1808_PULL_BANK_STRIDE;
53864 + struct rockchip_pinctrl *info = bank->drvdata;
53866 + if (bank->bank_num == 0) {
53867 + *regmap = info->regmap_pmu;
53870 + *regmap = info->regmap_base;
53872 + *reg += (bank->bank_num - 1) * RK1808_DRV_BANK_STRIDE;
53890 + struct rockchip_pinctrl *info = bank->drvdata;
53892 + if (bank->bank_num == 0) {
53893 + *regmap = info->regmap_pmu;
53896 + *regmap = info->regmap_base;
53898 + *reg += (bank->bank_num - 1) * RK1808_SR_BANK_STRIDE;
53916 + struct rockchip_pinctrl *info = bank->drvdata;
53918 + if (bank->bank_num == 0) {
53919 + *regmap = info->regmap_pmu;
53922 + *regmap = info->regmap_base;
53924 + *reg += (bank->bank_num - 1) * RK1808_SCHMITT_BANK_STRIDE;
53935 @@ -2102,6 +1931,100 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
53949 + struct rockchip_pinctrl *info = bank->drvdata;
53951 + if (bank->bank_num == 0) {
53952 + *regmap = info->regmap_pmu;
53955 + *regmap = info->regmap_base;
53957 + *reg += (bank->bank_num - 1) * RK3568_SR_BANK_STRIDE;
53975 + struct rockchip_pinctrl *info = bank->drvdata;
53977 + if (bank->bank_num == 0) {
53978 + *regmap = info->regmap_pmu;
53980 + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
53986 + *regmap = info->regmap_base;
53988 + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
54006 + struct rockchip_pinctrl *info = bank->drvdata;
54009 + if (bank->bank_num == 0) {
54010 + *regmap = info->regmap_pmu;
54017 + *regmap = info->regmap_base;
54019 + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
54027 + if ((bank->bank_num == 1 && (pin_num == 15 || pin_num == 23 || pin_num == 31)) ||
54028 + ((bank->bank_num == 2 || bank->bank_num == 3 || bank->bank_num == 4) &&
54030 + *bit -= RK3568_DRV_BITS_PER_PIN;
54034 { 2, 4, 8, 12, -1, -1, -1, -1 },
54035 { 3, 6, 9, 12, -1, -1, -1, -1 },
54036 @@ -2202,6 +2125,15 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
54037 bank->bank_num, pin_num, strength);
54039 ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
54040 + if (ctrl->type == RV1126) {
54044 + } else if (ctrl->type == RK3568) {
54046 + ret = (1 << (strength + 1)) - 1;
54050 ret = -EINVAL;
54052 @@ -2271,14 +2203,42 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
54053 return -EINVAL;
54058 data = ((1 << rmask_bits) - 1) << (bit + 16);
54066 - return ret;
54067 + if (ctrl->type == RK3568 && rockchip_get_cpu_version() == 0) {
54068 + if (bank->bank_num == 1 && pin_num == 21)
54070 + else if (bank->bank_num == 2 && pin_num == 2)
54072 + else if (bank->bank_num == 2 && pin_num == 8)
54074 + else if (bank->bank_num == 3 && pin_num == 0)
54076 + else if (bank->bank_num == 3 && pin_num == 6)
54078 + else if (bank->bank_num == 4 && pin_num == 0)
54083 + data = ((1 << rmask_bits) - 1) << 16;
54085 + data |= (1 << (strength + 1)) - 1;
54096 @@ -2323,11 +2283,14 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
54108 pull_type = bank->pull_type[pin_num / 8];
54110 data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
54111 @@ -2368,11 +2331,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
54123 pull_type = bank->pull_type[pin_num / 8];
54124 ret = -EINVAL;
54126 @@ -2382,6 +2348,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
54131 + * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6,
54134 + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
54140 dev_err(info->dev, "unsupported pull setting %d\n",
54141 @@ -2426,6 +2400,35 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
54156 + struct rockchip_pinctrl *info = bank->drvdata;
54158 + if (bank->bank_num == 0) {
54159 + *regmap = info->regmap_pmu;
54162 + *regmap = info->regmap_base;
54164 + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
54176 struct rockchip_pinctrl *info = bank->drvdata;
54177 @@ -2444,10 +2447,17 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
54181 - return data & 0x1;
54182 -}
54183 -
54184 -static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
54185 + switch (ctrl->type) {
54187 + return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1);
54198 struct rockchip_pinctrl *info = bank->drvdata;
54199 @@ -2465,7 +2475,91 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
54203 - data = BIT(bit + 16) | (enable << bit);
54204 + switch (ctrl->type) {
54206 + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
54230 + struct rockchip_pinctrl *info = bank->drvdata;
54233 + if (bank->bank_num == 0) {
54234 + *regmap = info->regmap_pmu;
54238 + *regmap = info->regmap_base;
54241 + *reg += (bank->bank_num - 1) * PX30_SLEW_RATE_BANK_STRIDE;
54251 + struct rockchip_pinctrl *info = bank->drvdata;
54252 + struct rockchip_pin_ctrl *ctrl = info->ctrl;
54258 + ret = ctrl->slew_rate_calc_reg(bank, pin_num, ®map, ®, &bit);
54273 + struct rockchip_pinctrl *info = bank->drvdata;
54274 + struct rockchip_pin_ctrl *ctrl = info->ctrl;
54280 + dev_dbg(info->dev, "setting slew rate of GPIO%d-%d to %d\n",
54281 + bank->bank_num, pin_num, speed);
54283 + ret = ctrl->slew_rate_calc_reg(bank, pin_num, ®map, ®, &bit);
54292 @@ -2526,9 +2620,9 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
54296 - if (ret) {
54299 - for (cnt--; cnt >= 0; cnt--)
54300 + for (cnt--; cnt >= 0 && !data[cnt].func; cnt--)
54301 rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
54304 @@ -2537,86 +2631,11 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
54308 -static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
54309 -{
54310 - struct rockchip_pin_bank *bank = gpiochip_get_data(chip);
54311 - u32 data;
54312 - int ret;
54313 -
54314 - ret = clk_enable(bank->clk);
54315 - if (ret < 0) {
54316 - dev_err(bank->drvdata->dev,
54317 - "failed to enable clock for bank %s\n", bank->name);
54318 - return ret;
54319 - }
54320 - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
54321 - clk_disable(bank->clk);
54322 -
54323 - if (data & BIT(offset))
54324 - return GPIO_LINE_DIRECTION_OUT;
54325 -
54326 - return GPIO_LINE_DIRECTION_IN;
54327 -}
54328 -
54329 -/*
54330 - * The calls to gpio_direction_output() and gpio_direction_input()
54331 - * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
54332 - * function called from the gpiolib interface).
54333 - */
54334 -static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
54335 - int pin, bool input)
54336 -{
54337 - struct rockchip_pin_bank *bank;
54338 - int ret;
54339 - unsigned long flags;
54340 - u32 data;
54341 -
54342 - bank = gpiochip_get_data(chip);
54343 -
54344 - ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
54345 - if (ret < 0)
54346 - return ret;
54347 -
54348 - clk_enable(bank->clk);
54349 - raw_spin_lock_irqsave(&bank->slock, flags);
54350 -
54351 - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
54352 - /* set bit to 1 for output, 0 for input */
54353 - if (!input)
54354 - data |= BIT(pin);
54355 - else
54356 - data &= ~BIT(pin);
54357 - writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
54358 -
54359 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54360 - clk_disable(bank->clk);
54361 -
54362 - return 0;
54363 -}
54364 -
54365 -static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
54366 - struct pinctrl_gpio_range *range,
54367 - unsigned offset, bool input)
54368 -{
54369 - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
54370 - struct gpio_chip *chip;
54371 - int pin;
54372 -
54373 - chip = range->gc;
54374 - pin = offset - chip->base;
54375 - dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
54376 - offset, range->name, pin, input ? "input" : "output");
54377 -
54378 - return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base,
54379 - input);
54380 -}
54381 -
54387 - .gpio_set_direction = rockchip_pmx_gpio_set_direction,
54391 @@ -2635,26 +2654,27 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
54409 -static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
54410 -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset);
54411 -
54418 + struct gpio_chip *gpio = &bank->gpio_chip;
54422 @@ -2687,10 +2707,13 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int p…
54426 - rockchip_gpio_set(&bank->gpio_chip,
54427 - pin - bank->pin_base, arg);
54428 - rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip,
54429 - pin - bank->pin_base, false);
54430 + rc = rockchip_get_mux(bank, pin - bank->pin_base);
54432 + dev_err(info->dev, "pin-%d has been mux to func%d\n", pin, rc);
54433 + return -EINVAL;
54436 + rc = gpio->direction_output(gpio, pin - bank->pin_base, arg);
54440 @@ -2713,9 +2736,17 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pi…
54445 + if (!info->ctrl->slew_rate_calc_reg)
54446 + return -ENOTSUPP;
54449 + pin - bank->pin_base, arg);
54454 return -ENOTSUPP;
54455 - break;
54459 @@ -2728,6 +2759,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
54463 + struct gpio_chip *gpio = &bank->gpio_chip;
54467 @@ -2753,10 +2785,12 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int p…
54470 rc = rockchip_get_mux(bank, pin - bank->pin_base);
54471 - if (rc != RK_FUNC_GPIO)
54473 + dev_err(info->dev, "pin-%d has been mux to func%d\n", pin, rc);
54474 return -EINVAL;
54477 - rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base);
54478 + rc = gpio->get(gpio, pin - bank->pin_base);
54482 @@ -2781,11 +2815,20 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int p…
54489 + if (!info->ctrl->slew_rate_calc_reg)
54490 + return -ENOTSUPP;
54492 + rc = rockchip_get_slew_rate(bank, pin - bank->pin_base);
54499 return -ENOTSUPP;
54500 - break;
54504 @@ -2848,716 +2891,173 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
54505 return -EINVAL;
54508 - grp->npins = size / 4;
54509 -
54510 - grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int),
54511 - GFP_KERNEL);
54512 - grp->data = devm_kcalloc(info->dev,
54513 - grp->npins,
54514 - sizeof(struct rockchip_pin_config),
54515 - GFP_KERNEL);
54516 - if (!grp->pins || !grp->data)
54517 - return -ENOMEM;
54518 -
54519 - for (i = 0, j = 0; i < size; i += 4, j++) {
54520 - const __be32 *phandle;
54521 - struct device_node *np_config;
54522 -
54523 - num = be32_to_cpu(*list++);
54524 - bank = bank_num_to_bank(info, num);
54525 - if (IS_ERR(bank))
54526 - return PTR_ERR(bank);
54527 -
54528 - grp->pins[j] = bank->pin_base + be32_to_cpu(*list++);
54529 - grp->data[j].func = be32_to_cpu(*list++);
54530 -
54531 - phandle = list++;
54532 - if (!phandle)
54533 - return -EINVAL;
54534 -
54535 - np_config = of_find_node_by_phandle(be32_to_cpup(phandle));
54536 - ret = pinconf_generic_parse_dt_config(np_config, NULL,
54537 - &grp->data[j].configs, &grp->data[j].nconfigs);
54538 - if (ret)
54539 - return ret;
54540 - }
54541 -
54542 - return 0;
54543 -}
54544 -
54545 -static int rockchip_pinctrl_parse_functions(struct device_node *np,
54546 - struct rockchip_pinctrl *info,
54547 - u32 index)
54548 -{
54549 - struct device_node *child;
54550 - struct rockchip_pmx_func *func;
54551 - struct rockchip_pin_group *grp;
54552 - int ret;
54553 - static u32 grp_index;
54554 - u32 i = 0;
54555 -
54556 - dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
54557 -
54558 - func = &info->functions[index];
54559 -
54560 - /* Initialise function */
54561 - func->name = np->name;
54562 - func->ngroups = of_get_child_count(np);
54563 - if (func->ngroups <= 0)
54564 - return 0;
54565 -
54566 - func->groups = devm_kcalloc(info->dev,
54567 - func->ngroups, sizeof(char *), GFP_KERNEL);
54568 - if (!func->groups)
54569 - return -ENOMEM;
54570 -
54571 - for_each_child_of_node(np, child) {
54572 - func->groups[i] = child->name;
54573 - grp = &info->groups[grp_index++];
54574 - ret = rockchip_pinctrl_parse_groups(child, grp, info, i++);
54575 - if (ret) {
54576 - of_node_put(child);
54577 - return ret;
54578 - }
54579 - }
54580 -
54581 - return 0;
54582 -}
54583 -
54584 -static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
54585 - struct rockchip_pinctrl *info)
54586 -{
54587 - struct device *dev = &pdev->dev;
54588 - struct device_node *np = dev->of_node;
54589 - struct device_node *child;
54590 - int ret;
54591 - int i;
54592 -
54593 - rockchip_pinctrl_child_count(info, np);
54594 -
54595 - dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
54596 - dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
54597 -
54598 - info->functions = devm_kcalloc(dev,
54599 - info->nfunctions,
54600 - sizeof(struct rockchip_pmx_func),
54601 - GFP_KERNEL);
54602 - if (!info->functions)
54603 - return -ENOMEM;
54604 -
54605 - info->groups = devm_kcalloc(dev,
54606 - info->ngroups,
54607 - sizeof(struct rockchip_pin_group),
54608 - GFP_KERNEL);
54609 - if (!info->groups)
54610 - return -ENOMEM;
54611 -
54612 - i = 0;
54613 -
54614 - for_each_child_of_node(np, child) {
54615 - if (of_match_node(rockchip_bank_match, child))
54616 - continue;
54617 -
54618 - ret = rockchip_pinctrl_parse_functions(child, info, i++);
54619 - if (ret) {
54620 - dev_err(&pdev->dev, "failed to parse function\n");
54621 - of_node_put(child);
54622 - return ret;
54623 - }
54624 - }
54625 -
54626 - return 0;
54627 -}
54628 -
54629 -static int rockchip_pinctrl_register(struct platform_device *pdev,
54630 - struct rockchip_pinctrl *info)
54631 -{
54632 - struct pinctrl_desc *ctrldesc = &info->pctl;
54633 - struct pinctrl_pin_desc *pindesc, *pdesc;
54634 - struct rockchip_pin_bank *pin_bank;
54635 - int pin, bank, ret;
54636 - int k;
54637 -
54638 - ctrldesc->name = "rockchip-pinctrl";
54639 - ctrldesc->owner = THIS_MODULE;
54640 - ctrldesc->pctlops = &rockchip_pctrl_ops;
54641 - ctrldesc->pmxops = &rockchip_pmx_ops;
54642 - ctrldesc->confops = &rockchip_pinconf_ops;
54643 -
54644 - pindesc = devm_kcalloc(&pdev->dev,
54645 - info->ctrl->nr_pins, sizeof(*pindesc),
54646 - GFP_KERNEL);
54647 - if (!pindesc)
54648 - return -ENOMEM;
54649 -
54650 - ctrldesc->pins = pindesc;
54651 - ctrldesc->npins = info->ctrl->nr_pins;
54652 -
54653 - pdesc = pindesc;
54654 - for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) {
54655 - pin_bank = &info->ctrl->pin_banks[bank];
54656 - for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) {
54657 - pdesc->number = k;
54658 - pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
54659 - pin_bank->name, pin);
54660 - pdesc++;
54661 - }
54662 - }
54663 -
54664 - ret = rockchip_pinctrl_parse_dt(pdev, info);
54665 - if (ret)
54666 - return ret;
54667 -
54668 - info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
54669 - if (IS_ERR(info->pctl_dev)) {
54670 - dev_err(&pdev->dev, "could not register pinctrl driver\n");
54671 - return PTR_ERR(info->pctl_dev);
54672 - }
54673 -
54674 - for (bank = 0; bank < info->ctrl->nr_banks; ++bank) {
54675 - pin_bank = &info->ctrl->pin_banks[bank];
54676 - pin_bank->grange.name = pin_bank->name;
54677 - pin_bank->grange.id = bank;
54678 - pin_bank->grange.pin_base = pin_bank->pin_base;
54679 - pin_bank->grange.base = pin_bank->gpio_chip.base;
54680 - pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
54681 - pin_bank->grange.gc = &pin_bank->gpio_chip;
54682 - pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange);
54683 - }
54684 -
54685 - return 0;
54686 -}
54687 -
54688 -/*
54689 - * GPIO handling
54690 - */
54691 -
54692 -static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
54693 -{
54694 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54695 - void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR;
54696 - unsigned long flags;
54697 - u32 data;
54698 -
54699 - clk_enable(bank->clk);
54700 - raw_spin_lock_irqsave(&bank->slock, flags);
54701 -
54702 - data = readl(reg);
54703 - data &= ~BIT(offset);
54704 - if (value)
54705 - data |= BIT(offset);
54706 - writel(data, reg);
54707 -
54708 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54709 - clk_disable(bank->clk);
54710 -}
54711 -
54712 -/*
54713 - * Returns the level of the pin for input direction and setting of the DR
54714 - * register for output gpios.
54715 - */
54716 -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset)
54717 -{
54718 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54719 - u32 data;
54720 -
54721 - clk_enable(bank->clk);
54722 - data = readl(bank->reg_base + GPIO_EXT_PORT);
54723 - clk_disable(bank->clk);
54724 - data >>= offset;
54725 - data &= 1;
54726 - return data;
54727 -}
54728 -
54729 -/*
54730 - * gpiolib gpio_direction_input callback function. The setting of the pin
54731 - * mux function as 'gpio input' will be handled by the pinctrl subsystem
54732 - * interface.
54733 - */
54734 -static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
54735 -{
54736 - return pinctrl_gpio_direction_input(gc->base + offset);
54737 -}
54738 -
54739 -/*
54740 - * gpiolib gpio_direction_output callback function. The setting of the pin
54741 - * mux function as 'gpio output' will be handled by the pinctrl subsystem
54742 - * interface.
54743 - */
54744 -static int rockchip_gpio_direction_output(struct gpio_chip *gc,
54745 - unsigned offset, int value)
54746 -{
54747 - rockchip_gpio_set(gc, offset, value);
54748 - return pinctrl_gpio_direction_output(gc->base + offset);
54749 -}
54750 -
54751 -static void rockchip_gpio_set_debounce(struct gpio_chip *gc,
54752 - unsigned int offset, bool enable)
54753 -{
54754 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54755 - void __iomem *reg = bank->reg_base + GPIO_DEBOUNCE;
54756 - unsigned long flags;
54757 - u32 data;
54758 -
54759 - clk_enable(bank->clk);
54760 - raw_spin_lock_irqsave(&bank->slock, flags);
54761 -
54762 - data = readl(reg);
54763 - if (enable)
54764 - data |= BIT(offset);
54765 - else
54766 - data &= ~BIT(offset);
54767 - writel(data, reg);
54768 -
54769 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54770 - clk_disable(bank->clk);
54771 -}
54772 -
54773 -/*
54774 - * gpiolib set_config callback function. The setting of the pin
54775 - * mux function as 'gpio output' will be handled by the pinctrl subsystem
54776 - * interface.
54777 - */
54778 -static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
54779 - unsigned long config)
54780 -{
54781 - enum pin_config_param param = pinconf_to_config_param(config);
54782 -
54783 - switch (param) {
54784 - case PIN_CONFIG_INPUT_DEBOUNCE:
54785 - rockchip_gpio_set_debounce(gc, offset, true);
54786 - /*
54787 - * Rockchip's gpio could only support up to one period
54788 - * of the debounce clock(pclk), which is far away from
54789 - * satisftying the requirement, as pclk is usually near
54790 - * 100MHz shared by all peripherals. So the fact is it
54791 - * has crippled debounce capability could only be useful
54792 - * to prevent any spurious glitches from waking up the system
54793 - * if the gpio is conguired as wakeup interrupt source. Let's
54794 - * still return -ENOTSUPP as before, to make sure the caller
54795 - * of gpiod_set_debounce won't change its behaviour.
54796 - */
54797 - return -ENOTSUPP;
54798 - default:
54799 - return -ENOTSUPP;
54800 - }
54801 -}
54802 -
54803 -/*
54804 - * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
54805 - * and a virtual IRQ, if not already present.
54806 - */
54807 -static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
54808 -{
54809 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54810 - unsigned int virq;
54811 -
54812 - if (!bank->domain)
54813 - return -ENXIO;
54814 -
54815 - clk_enable(bank->clk);
54816 - virq = irq_create_mapping(bank->domain, offset);
54817 - clk_disable(bank->clk);
54818 -
54819 - return (virq) ? : -ENXIO;
54820 -}
54821 -
54822 -static const struct gpio_chip rockchip_gpiolib_chip = {
54823 - .request = gpiochip_generic_request,
54824 - .free = gpiochip_generic_free,
54825 - .set = rockchip_gpio_set,
54826 - .get = rockchip_gpio_get,
54827 - .get_direction = rockchip_gpio_get_direction,
54828 - .direction_input = rockchip_gpio_direction_input,
54829 - .direction_output = rockchip_gpio_direction_output,
54830 - .set_config = rockchip_gpio_set_config,
54831 - .to_irq = rockchip_gpio_to_irq,
54832 - .owner = THIS_MODULE,
54833 -};
54834 -
54835 -/*
54836 - * Interrupt handling
54837 - */
54838 -
54839 -static void rockchip_irq_demux(struct irq_desc *desc)
54840 -{
54841 - struct irq_chip *chip = irq_desc_get_chip(desc);
54842 - struct rockchip_pin_bank *bank = irq_desc_get_handler_data(desc);
54843 - u32 pend;
54844 -
54845 - dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);
54846 -
54847 - chained_irq_enter(chip, desc);
54848 -
54849 - pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS);
54850 -
54851 - while (pend) {
54852 - unsigned int irq, virq;
54853 -
54854 - irq = __ffs(pend);
54855 - pend &= ~BIT(irq);
54856 - virq = irq_find_mapping(bank->domain, irq);
54857 -
54858 - if (!virq) {
54859 - dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq);
54860 - continue;
54861 - }
54862 -
54863 - dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq);
54864 -
54865 - /*
54866 - * Triggering IRQ on both rising and falling edge
54867 - * needs manual intervention.
54868 - */
54869 - if (bank->toggle_edge_mode & BIT(irq)) {
54870 - u32 data, data_old, polarity;
54871 - unsigned long flags;
54872 -
54873 - data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
54874 - do {
54875 - raw_spin_lock_irqsave(&bank->slock, flags);
54876 -
54877 - polarity = readl_relaxed(bank->reg_base +
54878 - GPIO_INT_POLARITY);
54879 - if (data & BIT(irq))
54880 - polarity &= ~BIT(irq);
54881 - else
54882 - polarity |= BIT(irq);
54883 - writel(polarity,
54884 - bank->reg_base + GPIO_INT_POLARITY);
54885 -
54886 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54887 -
54888 - data_old = data;
54889 - data = readl_relaxed(bank->reg_base +
54890 - GPIO_EXT_PORT);
54891 - } while ((data & BIT(irq)) != (data_old & BIT(irq)));
54892 - }
54893 -
54894 - generic_handle_irq(virq);
54895 - }
54896 -
54897 - chained_irq_exit(chip, desc);
54898 -}
54899 -
54900 -static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
54901 -{
54902 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
54903 - struct rockchip_pin_bank *bank = gc->private;
54904 - u32 mask = BIT(d->hwirq);
54905 - u32 polarity;
54906 - u32 level;
54907 - u32 data;
54908 - unsigned long flags;
54909 - int ret;
54910 -
54911 - /* make sure the pin is configured as gpio input */
54912 - ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
54913 - if (ret < 0)
54914 - return ret;
54915 -
54916 - clk_enable(bank->clk);
54917 - raw_spin_lock_irqsave(&bank->slock, flags);
54918 -
54919 - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
54920 - data &= ~mask;
54921 - writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
54922 -
54923 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54924 -
54925 - if (type & IRQ_TYPE_EDGE_BOTH)
54926 - irq_set_handler_locked(d, handle_edge_irq);
54927 - else
54928 - irq_set_handler_locked(d, handle_level_irq);
54929 -
54930 - raw_spin_lock_irqsave(&bank->slock, flags);
54931 - irq_gc_lock(gc);
54932 -
54933 - level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
54934 - polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY);
54935 -
54936 - switch (type) {
54937 - case IRQ_TYPE_EDGE_BOTH:
54938 - bank->toggle_edge_mode |= mask;
54939 - level |= mask;
54940 -
54941 - /*
54942 - * Determine gpio state. If 1 next interrupt should be falling
54943 - * otherwise rising.
54944 - */
54945 - data = readl(bank->reg_base + GPIO_EXT_PORT);
54946 - if (data & mask)
54947 - polarity &= ~mask;
54948 - else
54949 - polarity |= mask;
54950 - break;
54951 - case IRQ_TYPE_EDGE_RISING:
54952 - bank->toggle_edge_mode &= ~mask;
54953 - level |= mask;
54954 - polarity |= mask;
54955 - break;
54956 - case IRQ_TYPE_EDGE_FALLING:
54957 - bank->toggle_edge_mode &= ~mask;
54958 - level |= mask;
54959 - polarity &= ~mask;
54960 - break;
54961 - case IRQ_TYPE_LEVEL_HIGH:
54962 - bank->toggle_edge_mode &= ~mask;
54963 - level &= ~mask;
54964 - polarity |= mask;
54965 - break;
54966 - case IRQ_TYPE_LEVEL_LOW:
54967 - bank->toggle_edge_mode &= ~mask;
54968 - level &= ~mask;
54969 - polarity &= ~mask;
54970 - break;
54971 - default:
54972 - irq_gc_unlock(gc);
54973 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54974 - clk_disable(bank->clk);
54975 - return -EINVAL;
54976 - }
54977 -
54978 - writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL);
54979 - writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
54980 -
54981 - irq_gc_unlock(gc);
54982 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54983 - clk_disable(bank->clk);
54984 -
54985 - return 0;
54986 -}
54987 -
54988 -static void rockchip_irq_suspend(struct irq_data *d)
54989 -{
54990 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
54991 - struct rockchip_pin_bank *bank = gc->private;
54992 + grp->npins = size / 4;
54994 - clk_enable(bank->clk);
54995 - bank->saved_masks = irq_reg_readl(gc, GPIO_INTMASK);
54996 - irq_reg_writel(gc, ~gc->wake_active, GPIO_INTMASK);
54997 - clk_disable(bank->clk);
54998 -}
54999 + grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int),
55001 + grp->data = devm_kcalloc(info->dev,
55002 + grp->npins,
55005 + if (!grp->pins || !grp->data)
55006 + return -ENOMEM;
55008 -static void rockchip_irq_resume(struct irq_data *d)
55009 -{
55010 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
55011 - struct rockchip_pin_bank *bank = gc->private;
55016 - clk_enable(bank->clk);
55017 - irq_reg_writel(gc, bank->saved_masks, GPIO_INTMASK);
55018 - clk_disable(bank->clk);
55019 -}
55025 -static void rockchip_irq_enable(struct irq_data *d)
55026 -{
55027 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
55028 - struct rockchip_pin_bank *bank = gc->private;
55029 + grp->pins[j] = bank->pin_base + be32_to_cpu(*list++);
55030 + grp->data[j].func = be32_to_cpu(*list++);
55032 - clk_enable(bank->clk);
55033 - irq_gc_mask_clr_bit(d);
55034 -}
55037 + return -EINVAL;
55039 -static void rockchip_irq_disable(struct irq_data *d)
55040 -{
55041 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
55042 - struct rockchip_pin_bank *bank = gc->private;
55045 + &grp->data[j].configs, &grp->data[j].nconfigs);
55050 - irq_gc_mask_set_bit(d);
55051 - clk_disable(bank->clk);
55055 -static int rockchip_interrupts_register(struct platform_device *pdev,
55056 - struct rockchip_pinctrl *info)
55061 - struct rockchip_pin_ctrl *ctrl = info->ctrl;
55062 - struct rockchip_pin_bank *bank = ctrl->pin_banks;
55063 - unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
55064 - struct irq_chip_generic *gc;
55069 - int i;
55073 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
55074 - if (!bank->valid) {
55075 - dev_warn(&pdev->dev, "bank %s is not valid\n",
55076 - bank->name);
55077 - continue;
55078 - }
55079 + dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
55081 - ret = clk_enable(bank->clk);
55082 - if (ret) {
55083 - dev_err(&pdev->dev, "failed to enable clock for bank %s\n",
55084 - bank->name);
55085 - continue;
55086 - }
55087 + func = &info->functions[index];
55089 - bank->domain = irq_domain_add_linear(bank->of_node, 32,
55090 - &irq_generic_chip_ops, NULL);
55091 - if (!bank->domain) {
55092 - dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n",
55093 - bank->name);
55094 - clk_disable(bank->clk);
55095 - continue;
55096 - }
55098 + func->name = np->name;
55099 + func->ngroups = of_get_child_count(np);
55100 + if (func->ngroups <= 0)
55103 + func->groups = devm_kcalloc(info->dev,
55104 + func->ngroups, sizeof(char *), GFP_KERNEL);
55105 + if (!func->groups)
55106 + return -ENOMEM;
55108 - ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1,
55109 - "rockchip_gpio_irq", handle_level_irq,
55110 - clr, 0, 0);
55112 + func->groups[i] = child->name;
55113 + grp = &info->groups[grp_index++];
55116 - dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n",
55117 - bank->name);
55118 - irq_domain_remove(bank->domain);
55119 - clk_disable(bank->clk);
55120 - continue;
55124 -
55125 - gc = irq_get_domain_generic_chip(bank->domain, 0);
55126 - gc->reg_base = bank->reg_base;
55127 - gc->private = bank;
55128 - gc->chip_types[0].regs.mask = GPIO_INTMASK;
55129 - gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;
55130 - gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
55131 - gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
55132 - gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
55133 - gc->chip_types[0].chip.irq_enable = rockchip_irq_enable;
55134 - gc->chip_types[0].chip.irq_disable = rockchip_irq_disable;
55135 - gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
55136 - gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
55137 - gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
55138 - gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
55139 - gc->wake_enabled = IRQ_MSK(bank->nr_pins);
55140 -
55141 - /*
55142 - * Linux assumes that all interrupts start out disabled/masked.
55143 - * Our driver only uses the concept of masked and always keeps
55144 - * things enabled, so for us that's all masked and all enabled.
55145 - */
55146 - writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTMASK);
55147 - writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTEN);
55148 - gc->mask_cache = 0xffffffff;
55149 -
55150 - irq_set_chained_handler_and_data(bank->irq,
55151 - rockchip_irq_demux, bank);
55152 - clk_disable(bank->clk);
55158 -static int rockchip_gpiolib_register(struct platform_device *pdev,
55159 - struct rockchip_pinctrl *info)
55163 - struct rockchip_pin_ctrl *ctrl = info->ctrl;
55164 - struct rockchip_pin_bank *bank = ctrl->pin_banks;
55165 - struct gpio_chip *gc;
55166 + struct device *dev = &pdev->dev;
55167 + struct device_node *np = dev->of_node;
55172 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
55173 - if (!bank->valid) {
55174 - dev_warn(&pdev->dev, "bank %s is not valid\n",
55175 - bank->name);
55176 - continue;
55177 - }
55178 -
55179 - bank->gpio_chip = rockchip_gpiolib_chip;
55182 - gc = &bank->gpio_chip;
55183 - gc->base = bank->pin_base;
55184 - gc->ngpio = bank->nr_pins;
55185 - gc->parent = &pdev->dev;
55186 - gc->of_node = bank->of_node;
55187 - gc->label = bank->name;
55188 + dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
55189 + dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
55191 - ret = gpiochip_add_data(gc, bank);
55192 - if (ret) {
55193 - dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
55194 - gc->label, ret);
55195 - goto fail;
55196 - }
55197 - }
55198 + info->functions = devm_kcalloc(dev,
55199 + info->nfunctions,
55202 + if (!info->functions)
55203 + return -ENOMEM;
55205 - rockchip_interrupts_register(pdev, info);
55206 + info->groups = devm_kcalloc(dev,
55207 + info->ngroups,
55210 + if (!info->groups)
55211 + return -ENOMEM;
55213 - return 0;
55216 -fail:
55217 - for (--i, --bank; i >= 0; --i, --bank) {
55218 - if (!bank->valid)
55222 - gpiochip_remove(&bank->gpio_chip);
55223 - }
55224 - return ret;
55225 -}
55227 -static int rockchip_gpiolib_unregister(struct platform_device *pdev,
55228 - struct rockchip_pinctrl *info)
55229 -{
55230 - struct rockchip_pin_ctrl *ctrl = info->ctrl;
55231 - struct rockchip_pin_bank *bank = ctrl->pin_banks;
55232 - int i;
55233 -
55234 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
55235 - if (!bank->valid)
55236 - continue;
55237 - gpiochip_remove(&bank->gpio_chip);
55240 + dev_err(&pdev->dev, "failed to parse function\n");
55249 -static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
55250 - struct rockchip_pinctrl *info)
55254 - struct resource res;
55255 - void __iomem *base;
55256 + struct pinctrl_desc *ctrldesc = &info->pctl;
55262 - if (of_address_to_resource(bank->of_node, 0, &res)) {
55263 - dev_err(info->dev, "cannot find IO resource for bank\n");
55264 - return -ENOENT;
55265 - }
55266 + ctrldesc->name = "rockchip-pinctrl";
55267 + ctrldesc->owner = THIS_MODULE;
55268 + ctrldesc->pctlops = &rockchip_pctrl_ops;
55269 + ctrldesc->pmxops = &rockchip_pmx_ops;
55270 + ctrldesc->confops = &rockchip_pinconf_ops;
55272 - bank->reg_base = devm_ioremap_resource(info->dev, &res);
55273 - if (IS_ERR(bank->reg_base))
55274 - return PTR_ERR(bank->reg_base);
55275 + pindesc = devm_kcalloc(&pdev->dev,
55276 + info->ctrl->nr_pins, sizeof(*pindesc),
55279 + return -ENOMEM;
55281 - /*
55282 - * special case, where parts of the pull setting-registers are
55283 - * part of the PMU register space
55284 - */
55285 - if (of_device_is_compatible(bank->of_node,
55286 - "rockchip,rk3188-gpio-bank0")) {
55287 - struct device_node *node;
55288 -
55289 - node = of_parse_phandle(bank->of_node->parent,
55290 - "rockchip,pmu", 0);
55291 - if (!node) {
55292 - if (of_address_to_resource(bank->of_node, 1, &res)) {
55293 - dev_err(info->dev, "cannot find IO resource for bank\n");
55294 - return -ENOENT;
55295 - }
55296 + ctrldesc->pins = pindesc;
55297 + ctrldesc->npins = info->ctrl->nr_pins;
55299 - base = devm_ioremap_resource(info->dev, &res);
55300 - if (IS_ERR(base))
55301 - return PTR_ERR(base);
55302 - rockchip_regmap_config.max_register =
55303 - resource_size(&res) - 4;
55304 - rockchip_regmap_config.name =
55305 - "rockchip,rk3188-gpio-bank0-pull";
55306 - bank->regmap_pull = devm_regmap_init_mmio(info->dev,
55307 - base,
55308 - &rockchip_regmap_config);
55310 + for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) {
55311 + pin_bank = &info->ctrl->pin_banks[bank];
55312 + for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) {
55313 + pdesc->number = k;
55314 + pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
55315 + pin_bank->name, pin);
55318 - of_node_put(node);
55321 - bank->irq = irq_of_parse_and_map(bank->of_node, 0);
55326 - bank->clk = of_clk_get(bank->of_node, 0);
55327 - if (IS_ERR(bank->clk))
55328 - return PTR_ERR(bank->clk);
55329 + info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
55330 + if (IS_ERR(info->pctl_dev)) {
55331 + dev_err(&pdev->dev, "could not register pinctrl driver\n");
55332 + return PTR_ERR(info->pctl_dev);
55335 - return clk_prepare(bank->clk);
55340 @@ -3569,7 +3069,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55343 struct device_node *node = pdev->dev.of_node;
55344 - struct device_node *np;
55348 @@ -3577,23 +3076,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55350 ctrl = (struct rockchip_pin_ctrl *)match->data;
55352 - for_each_child_of_node(node, np) {
55353 - if (!of_find_property(np, "gpio-controller", NULL))
55354 - continue;
55355 -
55356 - bank = ctrl->pin_banks;
55357 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
55358 - if (!strcmp(bank->name, np->name)) {
55359 - bank->of_node = np;
55360 -
55361 - if (!rockchip_get_bank_data(bank, d))
55362 - bank->valid = true;
55363 -
55364 - break;
55365 - }
55366 - }
55367 - }
55368 -
55369 grf_offs = ctrl->grf_mux_offset;
55370 pmu_offs = ctrl->pmu_mux_offset;
55371 drv_pmu_offs = ctrl->pmu_drv_offset;
55372 @@ -3618,12 +3100,13 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55375 if (iom->offset >= 0) {
55376 - if (iom->type & IOMUX_SOURCE_PMU)
55377 + if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
55378 pmu_offs = iom->offset;
55380 grf_offs = iom->offset;
55382 - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
55383 + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
55384 + (iom->type & IOMUX_L_SOURCE_PMU)) ?
55388 @@ -3648,7 +3131,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55389 inc = (iom->type & (IOMUX_WIDTH_4BIT |
55392 - if (iom->type & IOMUX_SOURCE_PMU)
55393 + if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
55397 @@ -3743,6 +3226,46 @@ static int __maybe_unused rockchip_pinctrl_resume(struct device *dev)
55425 + ret = regmap_write(info->regmap_base, RK3308_GRF_SOC_CON13,
55432 + ret = regmap_write(info->regmap_base, RK3308_GRF_SOC_CON15,
55444 @@ -3814,17 +3337,25 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
55445 return PTR_ERR(info->regmap_pmu);
55448 - ret = rockchip_gpiolib_register(pdev, info);
55450 + if (ctrl->soc_data_init) {
55451 + ret = ctrl->soc_data_init(info);
55460 - ret = rockchip_pinctrl_register(pdev, info);
55465 - rockchip_gpiolib_unregister(pdev, info);
55466 + dev_err(&pdev->dev, "failed to register gpio device\n");
55469 -
55470 - platform_set_drvdata(pdev, info);
55475 @@ -3864,6 +3395,7 @@ static struct rockchip_pin_ctrl px30_pin_ctrl = {
55483 @@ -3890,6 +3422,86 @@ static struct rockchip_pin_ctrl rv1108_pin_ctrl = {
55516 + .label = "RV1126-GPIO",
55555 + .label = "RK1808-GPIO",
55570 @@ -4012,9 +3624,9 @@ static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
55574 - PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
55575 - IOMUX_SOURCE_PMU,
55576 - IOMUX_SOURCE_PMU,
55583 @@ -4089,6 +3701,7 @@ static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
55591 @@ -4213,11 +3826,55 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
55621 + .label = "RK3568-GPIO",
55636 { .compatible = "rockchip,px30-pinctrl",
55638 { .compatible = "rockchip,rv1108-pinctrl",
55640 + { .compatible = "rockchip,rv1126-pinctrl",
55642 + { .compatible = "rockchip,rk1808-pinctrl",
55644 { .compatible = "rockchip,rk2928-pinctrl",
55646 { .compatible = "rockchip,rk3036-pinctrl",
55647 @@ -4242,6 +3899,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
55649 { .compatible = "rockchip,rk3399-pinctrl",
55651 + { .compatible = "rockchip,rk3568-pinctrl",
55656 @@ -4259,3 +3918,14 @@ static int __init rockchip_pinctrl_drv_register(void)
55669 +MODULE_ALIAS("platform:pinctrl-rockchip");
55671 diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
55673 --- a/drivers/power/reset/gpio-poweroff.c
55674 +++ b/drivers/power/reset/gpio-poweroff.c
55675 @@ -90,7 +90,6 @@ static const struct of_device_id of_gpio_poweroff_match[] = {
55676 { .compatible = "gpio-poweroff", },
55679 -MODULE_DEVICE_TABLE(of, of_gpio_poweroff_match);
55683 diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
55685 --- a/drivers/power/supply/Kconfig
55687 @@ -692,8 +692,7 @@ config BATTERY_GOLDFISH
55691 - depends on I2C
55692 - select REGMAP_I2C
55697 @@ -776,4 +775,18 @@ config RN5T618_POWER
55716 diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
55718 --- a/drivers/power/supply/Makefile
55720 @@ -98,3 +98,4 @@ obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o
55721 obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o
55722 obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o
55723 obj-$(CONFIG_RN5T618_POWER) += rn5t618_power.o
55724 +obj-y += ../../$(VENDOR_DRIVER_DIR)/power/supply/
55725 diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
55727 --- a/drivers/pwm/Kconfig
55729 @@ -408,6 +408,12 @@ config PWM_ROCKCHIP
55742 diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
55744 --- a/drivers/pwm/pwm-rockchip.c
55745 +++ b/drivers/pwm/pwm-rockchip.c
55746 @@ -11,6 +11,7 @@
55754 @@ -26,15 +27,25 @@
55780 @@ -49,7 +60,9 @@ struct rockchip_pwm_data {
55790 @@ -63,7 +76,6 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
55793 u32 enable_conf = pc->data->enable_conf;
55794 - unsigned long clk_rate;
55798 @@ -72,15 +84,13 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
55802 - clk_rate = clk_get_rate(pc->clk);
55803 -
55804 tmp = readl_relaxed(pc->base + pc->data->regs.period);
55805 tmp *= pc->data->prescaler * NSEC_PER_SEC;
55806 - state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
55807 + state->period = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
55809 tmp = readl_relaxed(pc->base + pc->data->regs.duty);
55810 tmp *= pc->data->prescaler * NSEC_PER_SEC;
55811 - state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
55812 + state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
55814 val = readl_relaxed(pc->base + pc->data->regs.ctrl);
55815 state->enabled = (val & enable_conf) == enable_conf;
55816 @@ -98,28 +108,48 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
55820 - u64 clk_rate, div;
55825 - clk_rate = clk_get_rate(pc->clk);
55826 -
55832 - div = clk_rate * state->period;
55833 + div = (u64)pc->clk_rate * state->period;
55835 pc->data->prescaler * NSEC_PER_SEC);
55837 - div = clk_rate * state->duty_cycle;
55838 + div = (u64)pc->clk_rate * state->duty_cycle;
55839 duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
55846 ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
55847 + if (pc->data->vop_pwm) {
55848 + if (pc->vop_pwm_en)
55855 + if (state->oneshot_count > PWM_ONESHOT_COUNT_MAX) {
55856 + pc->oneshot = false;
55857 + dev_err(chip->dev, "Oneshot_count value overflow.\n");
55858 + } else if (state->oneshot_count > 0) {
55859 + pc->oneshot = true;
55860 + ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
55862 + pc->oneshot = false;
55867 if (pc->data->supports_lock) {
55869 writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl);
55870 @@ -145,6 +175,7 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
55873 writel(ctrl, pc->base + pc->data->regs.ctrl);
55878 @@ -163,13 +194,24 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
55881 val = readl_relaxed(pc->base + pc->data->regs.ctrl);
55882 + val &= ~pc->data->enable_conf_mask;
55884 - if (enable)
55885 + if (PWM_OUTPUT_CENTER & pc->data->enable_conf_mask) {
55886 + if (pc->center_aligned)
55892 - else
55893 + if (pc->oneshot)
55899 writel_relaxed(val, pc->base + pc->data->regs.ctrl);
55900 + if (pc->data->vop_pwm)
55901 + pc->vop_pwm_en = enable;
55904 clk_disable(pc->clk);
55905 @@ -207,6 +249,8 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
55909 + if (state->enabled)
55910 + ret = pinctrl_select_state(pc->pinctrl, pc->active_state);
55912 clk_disable(pc->pclk);
55914 @@ -229,7 +273,9 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
55924 @@ -242,8 +288,10 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
55935 @@ -256,8 +304,10 @@ static const struct rockchip_pwm_data pwm_data_vop = {
55946 @@ -270,8 +320,10 @@ static const struct rockchip_pwm_data pwm_data_v3 = {
55957 @@ -301,7 +353,8 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55958 return -ENOMEM;
55961 - pc->base = devm_ioremap_resource(&pdev->dev, r);
55962 + pc->base = devm_ioremap(&pdev->dev, r->start,
55964 if (IS_ERR(pc->base))
55965 return PTR_ERR(pc->base);
55967 @@ -339,6 +392,18 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55971 + pc->pinctrl = devm_pinctrl_get(&pdev->dev);
55972 + if (IS_ERR(pc->pinctrl)) {
55973 + dev_err(&pdev->dev, "Get pinctrl failed!\n");
55974 + return PTR_ERR(pc->pinctrl);
55977 + pc->active_state = pinctrl_lookup_state(pc->pinctrl, "active");
55978 + if (IS_ERR(pc->active_state)) {
55979 + dev_err(&pdev->dev, "No active pinctrl state\n");
55980 + return PTR_ERR(pc->active_state);
55985 pc->data = id->data;
55986 @@ -346,6 +411,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55987 pc->chip.ops = &rockchip_pwm_ops;
55988 pc->chip.base = -1;
55989 pc->chip.npwm = 1;
55990 + pc->clk_rate = clk_get_rate(pc->clk);
55992 if (pc->data->supports_polarity) {
55993 pc->chip.of_xlate = of_pwm_xlate_with_flags;
55994 @@ -356,6 +422,9 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55995 ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
55998 + pc->center_aligned =
55999 + device_property_read_bool(&pdev->dev, "center-aligned");
56001 ret = pwmchip_add(&pc->chip);
56003 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
56004 @@ -396,7 +465,21 @@ static struct platform_driver rockchip_pwm_driver = {
56026 diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
56028 --- a/drivers/pwm/sysfs.c
56030 @@ -103,6 +103,43 @@ static ssize_t duty_cycle_store(struct device *child,
56052 + struct pwm_device *pwm = export->pwm;
56061 + mutex_lock(&export->lock);
56065 + mutex_unlock(&export->lock);
56074 @@ -217,6 +254,9 @@ static ssize_t capture_show(struct device *child,
56084 @@ -224,6 +264,9 @@ static DEVICE_ATTR_RO(capture);
56094 diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
56096 --- a/drivers/regulator/Kconfig
56098 @@ -904,11 +904,11 @@ config REGULATOR_RC5T583
56102 - tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
56107 - PMIC RK805,RK809&RK817,RK808 and RK818.
56112 @@ -1279,5 +1279,11 @@ config REGULATOR_QCOM_LABIBB
56124 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
56126 --- a/drivers/regulator/Makefile
56128 @@ -157,5 +157,6 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
56129 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
56130 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
56131 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
56132 +obj-$(CONFIG_REGULATOR_XZ3216) += ../$(VENDOR_DRIVER_DIR)/regulator/
56134 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
56135 diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
56137 --- a/drivers/regulator/core.c
56139 @@ -51,6 +51,7 @@ static LIST_HEAD(regulator_map_list);
56147 @@ -92,6 +93,11 @@ struct regulator_supply_alias {
56159 @@ -4931,11 +4937,265 @@ static void regulator_dev_release(struct device *dev)
56178 + rdev_err(regulator->rdev, "enable failed, ret=%d\n",
56183 + rdev_err(regulator->rdev, "disable failed, ret=%d\n",
56198 + rdev_err(regulator->rdev, "force_disable failed, ret=%d\n",
56211 + struct regulator *regulator = file->private_data;
56212 + struct regulator_dev *rdev = regulator->rdev;
56217 + int min_uV, max_uV = -1;
56221 + return -EFAULT;
56228 + rdev_err(regulator->rdev, "incorrect values specified: \"%s\"; should be: \"target_uV\"\n",
56230 + return -EINVAL;
56233 + max_uV = rdev->constraints->max_uV;
56235 + list_for_each_entry(reg, &rdev->consumer_list, list) {
56236 + if ((!reg->voltage->min_uV && !reg->voltage->max_uV) ||
56239 + reg->voltage->min_uV = min_uV;
56240 + reg->voltage->max_uV = max_uV;
56245 + rdev_err(regulator->rdev, "set voltage(%d, %d) failed, ret=%d\n",
56250 + rdev_err(regulator->rdev, "voltage request string exceeds maximum buffer size\n");
56251 + return -EINVAL;
56265 + rdev_err(regulator->rdev, "set mode=%u failed, ret=%d\n",
56279 + rdev_err(regulator->rdev, "set load=%d failed, ret=%d\n",
56311 + struct regulator *regulator = file->private_data;
56317 + ret = snprintf(buf, MAX_DEBUG_BUF_LEN - 1, "%d\n", voltage);
56324 + file->private_data = inode->i_private;
56342 + rdev_err(regulator->rdev, "get mode failed, ret=%d\n", mode);
56358 + struct regulator_dev *rdev = m->private;
56365 + if (rdev->open_count)
56366 + seq_printf(m, "%-32s Min_uV Max_uV load_uA\n",
56367 + "Device-Supply");
56369 + list_for_each_entry(reg, &rdev->consumer_list, list) {
56370 + if (reg->supply_name)
56371 + supply_name = reg->supply_name;
56373 + supply_name = "(null)-(null)";
56375 + seq_printf(m, "%-32s %8d %8d %8d\n", supply_name,
56376 + reg->voltage->min_uV, reg->voltage->max_uV, reg->uA_load);
56386 + return single_open(file, reg_debug_consumers_show, inode->i_private);
56401 + debugfs_remove_recursive(rdev->debugfs);
56404 + if (reg_debug->reg->rdev == rdev) {
56405 + reg_debug->reg->debugfs = NULL;
56406 + list_del(®_debug->list);
56407 + regulator_put(reg_debug->reg);
56415 struct device *parent = rdev->dev.parent;
56424 if (parent && rname == rdev->desc->name) {
56425 @@ -4956,8 +5216,88 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
56426 &rdev->open_count);
56427 debugfs_create_u32("bypass_count", 0444, rdev->debugfs,
56428 &rdev->bypass_count);
56429 + debugfs_create_file("consumers", 0444, rdev->debugfs, rdev,
56444 + reg_debug->reg = regulator;
56445 + list_add(®_debug->list, ®ulator_debug_list);
56447 + ops = rdev->desc->ops;
56453 + debugfs_create_file("enable", mode, rdev->debugfs, regulator,
56457 + if (ops->is_enabled)
56460 + if (ops->disable)
56464 + debugfs_create_file("force_disable", mode, rdev->debugfs,
56468 + if (ops->get_voltage || ops->get_voltage_sel)
56471 + if (ops->set_voltage || ops->set_voltage_sel)
56475 + debugfs_create_file("voltage", mode, rdev->debugfs, regulator,
56479 + if (ops->get_mode)
56482 + if (ops->set_mode)
56486 + debugfs_create_file("mode", mode, rdev->debugfs, regulator,
56490 + if (ops->get_mode)
56493 + if (ops->set_load || (ops->get_optimum_mode && ops->set_mode))
56497 + debugfs_create_file("load", mode, rdev->debugfs, regulator,
56514 @@ -5432,7 +5772,7 @@ void regulator_unregister(struct regulator_dev *rdev)
56518 - debugfs_remove_recursive(rdev->debugfs);
56520 WARN_ON(rdev->open_count);
56523 @@ -5863,7 +6203,11 @@ static int __init regulator_init(void)
56535 diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
56537 --- a/drivers/regulator/fan53555.c
56539 @@ -20,10 +20,23 @@
56563 @@ -36,6 +49,7 @@
56571 @@ -47,13 +61,25 @@
56575 -#define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
56576 -#define FAN53526_NVOLTAGES 128
56599 @@ -88,8 +114,10 @@ enum {
56610 @@ -97,17 +125,52 @@ struct fan53555_device_info {
56625 - unsigned int vsel_count;
56626 - /* Mode */
56627 - unsigned int mode_reg;
56628 - unsigned int mode_mask;
56650 + if (di->vendor == FAN53555_VENDOR_RK) {
56651 + ret = regmap_read(di->regmap, RK860X_MAX_SET, &val);
56667 @@ -118,8 +181,8 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
56671 - ret = regmap_update_bits(rdev->regmap, di->sleep_reg,
56672 - di->desc.vsel_mask, ret);
56673 + ret = regmap_update_bits(di->regmap, di->sleep_reg,
56674 + di->vol_mask, ret);
56678 @@ -133,7 +196,7 @@ static int fan53555_set_suspend_enable(struct regulator_dev *rdev)
56682 - return regmap_update_bits(rdev->regmap, di->sleep_reg,
56683 + return regmap_update_bits(di->regmap, di->sleep_en_reg,
56687 @@ -141,21 +204,69 @@ static int fan53555_set_suspend_disable(struct regulator_dev *rdev)
56691 - return regmap_update_bits(rdev->regmap, di->sleep_reg,
56692 + return regmap_update_bits(di->regmap, di->sleep_en_reg,
56700 + if (di->vsel_gpio) {
56701 + gpiod_set_raw_value(di->vsel_gpio, !di->sleep_vsel_id);
56705 + return regmap_update_bits(di->regmap, di->en_reg,
56713 + if (di->vsel_gpio) {
56714 + gpiod_set_raw_value(di->vsel_gpio, di->sleep_vsel_id);
56718 + return regmap_update_bits(di->regmap, di->en_reg,
56728 + if (di->vsel_gpio) {
56729 + if (di->sleep_vsel_id)
56730 + return !gpiod_get_raw_value(di->vsel_gpio);
56732 + return gpiod_get_raw_value(di->vsel_gpio);
56735 + ret = regmap_read(di->regmap, di->en_reg, &val);
56750 - regmap_update_bits(rdev->regmap, di->mode_reg,
56751 + regmap_update_bits(di->regmap, di->mode_reg,
56752 di->mode_mask, di->mode_mask);
56755 - regmap_update_bits(rdev->regmap, di->vol_reg, di->mode_mask, 0);
56756 + regmap_update_bits(di->regmap, di->mode_reg, di->mode_mask, 0);
56759 return -EINVAL;
56760 @@ -169,7 +280,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
56764 - ret = regmap_read(rdev->regmap, di->mode_reg, &val);
56765 + ret = regmap_read(di->regmap, di->mode_reg, &val);
56768 if (val & di->mode_mask)
56769 @@ -189,13 +300,37 @@ static const int slew_rates[] = {
56783 int regval = -1, i;
56787 - for (i = 0; i < ARRAY_SIZE(slew_rates); i++) {
56788 - if (ramp <= slew_rates[i])
56789 + switch (di->vendor) {
56801 + return -EINVAL;
56809 @@ -206,20 +341,20 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
56810 return -EINVAL;
56813 - return regmap_update_bits(rdev->regmap, FAN53555_CONTROL,
56814 - CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT);
56815 + return regmap_update_bits(di->regmap, di->slew_reg,
56816 + di->slew_mask, regval << di->slew_shift);
56821 - .get_voltage_sel = regulator_get_voltage_sel_regmap,
56827 - .enable = regulator_enable_regmap,
56828 - .disable = regulator_disable_regmap,
56829 - .is_enabled = regulator_is_enabled_regmap,
56836 @@ -250,7 +385,7 @@ static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di)
56837 return -EINVAL;
56840 - di->vsel_count = FAN53526_NVOLTAGES;
56841 + di->n_voltages = FAN53555_NVOLTAGES_64;
56845 @@ -292,8 +427,58 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
56846 "Chip ID %d not supported!\n", di->chip_id);
56847 return -EINVAL;
56849 + di->vol_mask = VSEL_NSEL_MASK;
56850 + di->mode_reg = di->vol_reg;
56851 + di->mode_mask = VSEL_MODE;
56852 + di->slew_reg = FAN53555_CONTROL;
56853 + di->slew_mask = CTL_SLEW_MASK;
56854 + di->slew_shift = CTL_SLEW_SHIFT;
56855 + di->n_voltages = FAN53555_NVOLTAGES_64;
56857 - di->vsel_count = FAN53555_NVOLTAGES;
56866 + if (di->sleep_vsel_id) {
56867 + di->sleep_reg = RK860X_VSEL1;
56868 + di->vol_reg = RK860X_VSEL0;
56869 + di->mode_reg = FAN53555_VSEL0;
56870 + di->en_reg = FAN53555_VSEL0;
56871 + di->sleep_en_reg = FAN53555_VSEL1;
56873 + di->sleep_reg = RK860X_VSEL0;
56874 + di->vol_reg = RK860X_VSEL1;
56875 + di->mode_reg = FAN53555_VSEL1;
56876 + di->en_reg = FAN53555_VSEL1;
56877 + di->sleep_en_reg = FAN53555_VSEL0;
56880 + di->mode_mask = VSEL_MODE;
56881 + di->vol_mask = RK_VSEL_NSEL_MASK;
56882 + di->slew_reg = FAN53555_CONTROL;
56883 + di->slew_mask = CTL_SLEW_MASK;
56884 + di->slew_shift = CTL_SLEW_SHIFT;
56887 + di->vsel_min = 500000;
56888 + di->vsel_step = 6250;
56889 + di->n_voltages = FAN53555_NVOLTAGES_160;
56891 + if (pdata->limit_volt) {
56892 + if (pdata->limit_volt < di->vsel_min ||
56893 + pdata->limit_volt > 1500000)
56894 + pdata->limit_volt = 1500000;
56895 + val = (pdata->limit_volt - di->vsel_min) / di->vsel_step;
56896 + ret = regmap_write(di->regmap, RK860X_MAX_SET, val);
56898 + dev_err(di->dev, "Failed to set limit voltage!\n");
56905 @@ -312,8 +497,43 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
56906 "Chip ID %d not supported!\n", di->chip_id);
56907 return -EINVAL;
56909 + di->vol_mask = VSEL_NSEL_MASK;
56910 + di->mode_reg = di->vol_reg;
56911 + di->mode_mask = VSEL_MODE;
56912 + di->slew_reg = FAN53555_CONTROL;
56913 + di->slew_reg = FAN53555_CONTROL;
56914 + di->slew_mask = CTL_SLEW_MASK;
56915 + di->slew_shift = CTL_SLEW_SHIFT;
56916 + di->n_voltages = FAN53555_NVOLTAGES_64;
56918 - di->vsel_count = FAN53555_NVOLTAGES;
56924 + if (di->sleep_vsel_id) {
56925 + di->sleep_reg = TCS452X_VSEL1;
56926 + di->vol_reg = TCS452X_VSEL0;
56927 + di->mode_mask = TCS_VSEL0_MODE;
56929 + di->sleep_reg = TCS452X_VSEL0;
56930 + di->vol_reg = TCS452X_VSEL1;
56931 + di->mode_mask = TCS_VSEL1_MODE;
56934 + di->mode_reg = TCS452X_COMMAND;
56935 + di->vol_mask = TCS_VSEL_NSEL_MASK;
56936 + di->slew_reg = TCS452X_TIME;
56937 + di->slew_mask = TCS_SLEW_MASK;
56938 + di->slew_shift = TCS_SLEW_MASK;
56941 + di->vsel_min = 600000;
56942 + di->vsel_step = 6250;
56943 + di->n_voltages = FAN53555_NVOLTAGES_127;
56945 + di->en_reg = di->vol_reg;
56946 + di->sleep_en_reg = di->sleep_reg;
56950 @@ -343,7 +563,10 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
56951 return -EINVAL;
56954 - /* Setup mode control register */
56955 + di->en_reg = di->vol_reg;
56956 + di->sleep_en_reg = di->sleep_reg;
56959 switch (di->vendor) {
56961 di->mode_reg = FAN53555_CONTROL;
56962 @@ -356,28 +579,20 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
56963 di->mode_mask = CTL_MODE_VSEL0_MODE;
56966 - break;
56967 - case FAN53555_VENDOR_FAIRCHILD:
56968 - case FAN53555_VENDOR_SILERGY:
56969 - di->mode_reg = di->vol_reg;
56970 - di->mode_mask = VSEL_MODE;
56971 - break;
56972 - default:
56973 - dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
56974 - return -EINVAL;
56975 - }
56976 -
56977 - /* Setup voltage range */
56978 - switch (di->vendor) {
56979 - case FAN53526_VENDOR_FAIRCHILD:
56995 dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
56996 return -EINVAL;
56997 @@ -390,23 +605,23 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
57000 struct regulator_desc *rdesc = &di->desc;
57001 - struct regulator_dev *rdev;
57003 rdesc->name = "fan53555-reg";
57004 rdesc->supply_name = "vin";
57005 rdesc->ops = &fan53555_regulator_ops;
57006 rdesc->type = REGULATOR_VOLTAGE;
57007 - rdesc->n_voltages = di->vsel_count;
57008 - rdesc->enable_reg = di->vol_reg;
57009 + rdesc->n_voltages = di->n_voltages;
57010 + rdesc->enable_reg = di->en_reg;
57011 rdesc->enable_mask = VSEL_BUCK_EN;
57012 rdesc->min_uV = di->vsel_min;
57013 rdesc->uV_step = di->vsel_step;
57014 rdesc->vsel_reg = di->vol_reg;
57015 - rdesc->vsel_mask = di->vsel_count - 1;
57016 + rdesc->vsel_mask = di->vol_mask;
57017 rdesc->owner = THIS_MODULE;
57018 + rdesc->enable_time = 400;
57020 - rdev = devm_regulator_register(di->dev, &di->desc, config);
57021 - return PTR_ERR_OR_ZERO(rdev);
57022 + di->rdev = devm_regulator_register(di->dev, &di->desc, config);
57023 + return PTR_ERR_OR_ZERO(di->rdev);
57027 @@ -419,7 +634,7 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
57031 - int ret;
57036 @@ -427,12 +642,30 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
57039 pdata->regulator = of_get_regulator_init_data(dev, np, desc);
57040 + pdata->regulator->constraints.initial_state = PM_SUSPEND_MEM;
57042 + if (!(of_property_read_u32(np, "limit-microvolt", &limit_volt)))
57043 + pdata->limit_volt = limit_volt;
57045 ret = of_property_read_u32(np, "fcs,suspend-voltage-selector",
57048 pdata->sleep_vsel_id = tmp;
57050 + if (pdata->sleep_vsel_id)
57055 + pdata->vsel_gpio =
57058 + if (IS_ERR(pdata->vsel_gpio)) {
57059 + ret = PTR_ERR(pdata->vsel_gpio);
57061 + pdata->vsel_gpio = NULL;
57067 @@ -443,12 +676,21 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
57089 @@ -461,7 +703,6 @@ static int fan53555_regulator_probe(struct i2c_client *client,
57093 - struct regmap *regmap;
57097 @@ -470,6 +711,8 @@ static int fan53555_regulator_probe(struct i2c_client *client,
57099 return -ENOMEM;
57101 + di->desc.of_map_mode = fan53555_map_mode;
57103 pdata = dev_get_platdata(&client->dev);
57105 pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
57106 @@ -479,6 +722,9 @@ static int fan53555_regulator_probe(struct i2c_client *client,
57107 return -ENODEV;
57110 + di->vsel_gpio = pdata->vsel_gpio;
57111 + di->sleep_vsel_id = pdata->sleep_vsel_id;
57113 di->regulator = pdata->regulator;
57114 if (client->dev.of_node) {
57115 di->vendor =
57116 @@ -498,22 +744,22 @@ static int fan53555_regulator_probe(struct i2c_client *client,
57117 di->vendor = id->driver_data;
57120 - regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
57121 - if (IS_ERR(regmap)) {
57122 + di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
57123 + if (IS_ERR(di->regmap)) {
57124 dev_err(&client->dev, "Failed to allocate regmap!\n");
57125 - return PTR_ERR(regmap);
57126 + return PTR_ERR(di->regmap);
57128 di->dev = &client->dev;
57131 - ret = regmap_read(regmap, FAN53555_ID1, &val);
57132 + ret = regmap_read(di->regmap, FAN53555_ID1, &val);
57134 dev_err(&client->dev, "Failed to get chip ID!\n");
57137 di->chip_id = val & DIE_ID;
57139 - ret = regmap_read(regmap, FAN53555_ID2, &val);
57140 + ret = regmap_read(di->regmap, FAN53555_ID2, &val);
57142 dev_err(&client->dev, "Failed to get chip Rev!\n");
57144 @@ -530,15 +776,52 @@ static int fan53555_regulator_probe(struct i2c_client *client,
57146 config.dev = di->dev;
57147 config.init_data = di->regulator;
57148 - config.regmap = regmap;
57149 + config.regmap = di->regmap;
57155 dev_err(&client->dev, "Failed to register regulator!\n");
57167 + dev_info(di->dev, "fan53555..... reset\n");
57169 + switch (di->vendor) {
57173 + ret = regmap_update_bits(di->regmap, di->slew_reg,
57177 + ret = regmap_update_bits(di->regmap, TCS452X_LIMCONF,
57181 + * it will return -ENXIO, ignore this error.
57183 + if (ret == -ENXIO)
57187 + ret = -EINVAL;
57192 + dev_err(di->dev, "reset: force fan53555_reset error! ret=%d\n", ret);
57194 + dev_info(di->dev, "reset: force fan53555_reset ok!\n");
57198 @@ -548,12 +831,21 @@ static const struct i2c_device_id fan53555_id[] = {
57220 @@ -565,6 +857,7 @@ static struct i2c_driver fan53555_regulator_driver = {
57228 diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
57230 --- a/drivers/regulator/of_regulator.c
57232 @@ -413,8 +413,12 @@ device_node *regulator_of_get_init_node(struct device *dev,
57235 name = of_get_property(child, "regulator-compatible", NULL);
57236 - if (!name)
57237 - name = child->name;
57239 + if (!desc->of_match_full_name)
57240 + name = child->name;
57242 + name = child->full_name;
57245 if (!strcmp(desc->of_match, name)) {
57247 diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
57249 --- a/drivers/regulator/rk808-regulator.c
57250 +++ b/drivers/regulator/rk808-regulator.c
57251 @@ -34,6 +34,11 @@
57263 @@ -60,8 +65,8 @@
57267 -/* max steps for increase voltage of Buck1/2, equal 100mv*/
57268 -#define MAX_STEPS_ONE_TIME 8
57274 @@ -113,10 +118,15 @@
57284 - _vmask, _ereg, _emask, _etime) \
57287 - _vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops)
57292 @@ -124,9 +134,9 @@
57296 - _vmask, _ereg, _emask, _disval, _etime) \
57299 - _vmask, _ereg, _emask, _emask, _disval, _etime, &rk817_reg_ops)
57304 @@ -145,10 +155,10 @@
57308 -#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \
57312 - _emask, _disval, &rk817_switch_ops)
57317 @@ -165,11 +175,33 @@ static const int rk808_buck_config_regs[] = {
57322 + REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), /* 0.7125v - 1.45v */
57323 + REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),/* 1.8v - 2.2v */
57324 + REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0), /* 2.3v - 2.3v */
57328 + REGULATOR_LINEAR_RANGE(800000, 0, 26, 100000), /* 0.8v - 3.4v */
57338 + REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), /* 0.7125v - 1.45v */
57339 + REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),/* 1.8v - 2.2v */
57340 + REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0), /* 2.3v - 2.3v */
57344 + REGULATOR_LINEAR_RANGE(800000, 0, 26, 100000), /* 0.8v - 3.4 */
57351 @@ -287,6 +319,58 @@ static int rk808_buck1_2_i2c_set_voltage_sel(struct regulator_dev *rdev,
57368 + regmap_read(rdev->regmap, RK816_CHIP_VER_REG, &rk816_type);
57370 + sel <<= ffs(rdev->desc->vsel_mask) - 1;
57380 + ret = regmap_update_bits(rdev->regmap,
57381 + rdev->desc->vsel_reg,
57382 + rdev->desc->vsel_mask, sel);
57387 + ret = regmap_update_bits(rdev->regmap,
57395 + regmap_read(rdev->regmap,
57396 + rdev->desc->vsel_reg, &real_sel);
57397 + real_sel &= rdev->desc->vsel_mask;
57398 + delay--;
57410 @@ -340,6 +424,33 @@ static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev,
57434 + rdev->desc->name, ramp_delay);
57437 + return regmap_update_bits(rdev->regmap, reg,
57444 @@ -366,6 +477,16 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
57450 + struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
57452 + if (rk808->variant == RK805_ID)
57461 @@ -428,9 +549,14 @@ static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
57465 - unsigned int reg;
57468 - reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57469 + if (rdev->desc->id >= RK805_ID_LDO1)
57474 + reg = rdev->desc->enable_reg + offset;
57476 return regmap_update_bits(rdev->regmap, reg,
57477 rdev->desc->enable_mask,
57478 @@ -439,18 +565,77 @@ static int rk805_set_suspend_enable(struct regulator_dev *rdev)
57482 - unsigned int reg;
57485 - reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57486 + if (rdev->desc->id >= RK805_ID_LDO1)
57491 + reg = rdev->desc->enable_reg + offset;
57493 return regmap_update_bits(rdev->regmap, reg,
57494 rdev->desc->enable_mask,
57502 + if (rdev->desc->id <= RK816_ID_DCDC4) {
57503 + reg = rdev->desc->enable_reg +
57505 + val = 1 << rdev->desc->id;
57506 + } else if ((rdev->desc->id > RK816_ID_DCDC4) &&
57507 + (rdev->desc->id <= RK816_ID_LDO4)) {
57508 + reg = rdev->desc->enable_reg -
57510 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57512 + reg = rdev->desc->enable_reg -
57514 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57517 + return regmap_update_bits(rdev->regmap, reg,
57526 + if (rdev->desc->id <= RK816_ID_DCDC4) {
57527 + reg = rdev->desc->enable_reg +
57529 + val = 1 << rdev->desc->id;
57530 + } else if ((rdev->desc->id > RK816_ID_DCDC4) &&
57531 + (rdev->desc->id <= RK816_ID_LDO4)) {
57532 + reg = rdev->desc->enable_reg -
57534 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57536 + reg = rdev->desc->enable_reg -
57538 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57541 + return regmap_update_bits(rdev->regmap, reg,
57549 + struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
57551 + if (rk808->variant == RK816_ID)
57553 + else if (rk808->variant == RK805_ID)
57556 reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57558 @@ -462,6 +647,12 @@ static int rk808_set_suspend_enable(struct regulator_dev *rdev)
57562 + struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
57564 + if (rk808->variant == RK816_ID)
57566 + else if (rk808->variant == RK805_ID)
57569 reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57571 @@ -560,6 +751,22 @@ static unsigned int rk8xx_get_mode(struct regulator_dev *rdev)
57577 + return regmap_update_bits(rdev->regmap,
57578 + rdev->desc->enable_reg,
57579 + rdev->desc->enable_mask,
57580 + rdev->desc->enable_mask);
57585 + return regmap_update_bits(rdev->regmap,
57586 + rdev->desc->enable_reg,
57587 + rdev->desc->enable_mask,
57588 + rdev->desc->disable_val);
57594 @@ -569,17 +776,7 @@ static int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
57598 - /* add write mask bit */
57599 - val |= (rdev->desc->enable_mask & 0xf0);
57600 - val &= rdev->desc->enable_mask;
57601 -
57602 - if (rdev->desc->enable_is_inverted) {
57603 - if (rdev->desc->enable_val)
57604 - return val != rdev->desc->enable_val;
57605 - return (val == 0);
57606 - }
57607 - if (rdev->desc->enable_val)
57608 - return val == rdev->desc->enable_val;
57609 + val &= rdev->desc->enable_val;
57613 @@ -595,27 +792,6 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
57617 -static const struct regulator_ops rk805_reg_ops = {
57618 - .list_voltage = regulator_list_voltage_linear,
57619 - .map_voltage = regulator_map_voltage_linear,
57620 - .get_voltage_sel = regulator_get_voltage_sel_regmap,
57621 - .set_voltage_sel = regulator_set_voltage_sel_regmap,
57622 - .enable = regulator_enable_regmap,
57623 - .disable = regulator_disable_regmap,
57624 - .is_enabled = regulator_is_enabled_regmap,
57625 - .set_suspend_voltage = rk808_set_suspend_voltage,
57626 - .set_suspend_enable = rk805_set_suspend_enable,
57627 - .set_suspend_disable = rk805_set_suspend_disable,
57628 -};
57629 -
57630 -static const struct regulator_ops rk805_switch_ops = {
57631 - .enable = regulator_enable_regmap,
57632 - .disable = regulator_disable_regmap,
57633 - .is_enabled = regulator_is_enabled_regmap,
57634 - .set_suspend_enable = rk805_set_suspend_enable,
57635 - .set_suspend_disable = rk805_set_suspend_disable,
57636 -};
57637 -
57641 @@ -625,12 +801,33 @@ static const struct regulator_ops rk808_buck1_2_ops = {
57645 - .set_ramp_delay = rk808_set_ramp_delay,
57676 @@ -652,6 +849,10 @@ static const struct regulator_ops rk808_reg_ops_ranges = {
57687 @@ -661,24 +862,20 @@ static const struct regulator_ops rk808_switch_ops = {
57697 -static const struct linear_range rk805_buck_1_2_voltage_ranges[] = {
57698 - REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500),
57699 - REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),
57700 - REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0),
57701 -};
57702 -
57709 - .enable = regulator_enable_regmap,
57710 - .disable = regulator_disable_regmap,
57716 @@ -690,8 +887,8 @@ static const struct regulator_ops rk817_reg_ops = {
57720 - .enable = regulator_enable_regmap,
57721 - .disable = regulator_disable_regmap,
57727 @@ -703,8 +900,8 @@ static const struct regulator_ops rk817_boost_ops = {
57731 - .enable = regulator_enable_regmap,
57732 - .disable = regulator_disable_regmap,
57738 @@ -716,8 +913,8 @@ static const struct regulator_ops rk817_buck_ops_range = {
57742 - .enable = regulator_enable_regmap,
57743 - .disable = regulator_disable_regmap,
57749 @@ -729,8 +926,8 @@ static const struct regulator_ops rk817_buck_ops_range = {
57753 - .enable = regulator_enable_regmap,
57754 - .disable = regulator_disable_regmap,
57760 @@ -751,7 +948,10 @@ static const struct regulator_desc rk805_reg[] = {
57764 - .enable_mask = BIT(0),
57772 @@ -767,7 +967,10 @@ static const struct regulator_desc rk805_reg[] = {
57776 - .enable_mask = BIT(1),
57784 @@ -775,27 +978,45 @@ static const struct regulator_desc rk805_reg[] = {
57788 - .ops = &rk805_switch_ops,
57793 - .enable_mask = BIT(2),
57820 - RK805_DESC(RK805_ID_DCDC4, "DCDC_REG4", "vcc4", 800, 3400, 100,
57821 - RK805_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
57822 - RK805_DCDC_EN_REG, BIT(3), 0),
57823 -
57826 - BIT(0), 400),
57830 - BIT(1), 400),
57834 - BIT(2), 400),
57839 @@ -892,6 +1113,101 @@ static const struct regulator_desc rk808_reg[] = {
57941 @@ -908,7 +1224,7 @@ static const struct regulator_desc rk809_reg[] = {
57945 - .enable_val = ENABLE_MASK(RK817_ID_DCDC1),
57950 @@ -927,7 +1243,7 @@ static const struct regulator_desc rk809_reg[] = {
57954 - .enable_val = ENABLE_MASK(RK817_ID_DCDC2),
57959 @@ -946,7 +1262,7 @@ static const struct regulator_desc rk809_reg[] = {
57963 - .enable_val = ENABLE_MASK(RK817_ID_DCDC3),
57968 @@ -965,7 +1281,7 @@ static const struct regulator_desc rk809_reg[] = {
57972 - .enable_val = ENABLE_MASK(RK817_ID_DCDC4),
57977 @@ -985,52 +1301,52 @@ static const struct regulator_desc rk809_reg[] = {
57981 - .enable_val = ENABLE_MASK(1),
57989 - RK817_POWER_EN_REG(1), ENABLE_MASK(0),
57994 - RK817_POWER_EN_REG(1), ENABLE_MASK(1),
57999 - RK817_POWER_EN_REG(1), ENABLE_MASK(2),
58004 - RK817_POWER_EN_REG(1), ENABLE_MASK(3),
58009 - RK817_POWER_EN_REG(2), ENABLE_MASK(0),
58014 - RK817_POWER_EN_REG(2), ENABLE_MASK(1),
58019 - RK817_POWER_EN_REG(2), ENABLE_MASK(2),
58024 - RK817_POWER_EN_REG(2), ENABLE_MASK(3),
58029 - RK817_POWER_EN_REG(3), ENABLE_MASK(0),
58033 - RK817_POWER_EN_REG(3), ENABLE_MASK(2),
58037 - RK817_POWER_EN_REG(3), ENABLE_MASK(3),
58042 @@ -1114,46 +1430,46 @@ static const struct regulator_desc rk817_reg[] = {
58046 - RK817_POWER_EN_REG(1), ENABLE_MASK(0),
58051 - RK817_POWER_EN_REG(1), ENABLE_MASK(1),
58056 - RK817_POWER_EN_REG(1), ENABLE_MASK(2),
58061 - RK817_POWER_EN_REG(1), ENABLE_MASK(3),
58066 - RK817_POWER_EN_REG(2), ENABLE_MASK(0),
58071 - RK817_POWER_EN_REG(2), ENABLE_MASK(1),
58076 - RK817_POWER_EN_REG(2), ENABLE_MASK(2),
58081 - RK817_POWER_EN_REG(2), ENABLE_MASK(3),
58086 - RK817_POWER_EN_REG(3), ENABLE_MASK(0),
58091 - RK817_POWER_EN_REG(3), ENABLE_MASK(1), ENABLE_MASK(1),
58093 DISABLE_VAL(1), 400, 3500 - 5400),
58095 - RK817_POWER_EN_REG(3), ENABLE_MASK(2),
58100 @@ -1331,6 +1647,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
58111 @@ -1370,9 +1690,23 @@ static struct platform_driver rk808_regulator_driver = {
58131 -MODULE_DESCRIPTION("regulator driver for the RK805/RK808/RK818 series PMICs");
58133 MODULE_AUTHOR("Tony xie <tony.xie@rock-chips.com>");
58134 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
58135 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
58136 diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
58138 --- a/drivers/rtc/rtc-hym8563.c
58139 +++ b/drivers/rtc/rtc-hym8563.c
58140 @@ -96,13 +96,13 @@ static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
58144 -
58147 dev_warn(&client->dev,
58149 return -EINVAL;
58151 -
58153 tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK);
58154 tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK);
58155 tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK);
58156 @@ -232,12 +232,39 @@ static int hym8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
58157 if (alm_tm->tm_hour >= 24) {
58158 alm_tm->tm_hour = 0;
58159 alm_tm->tm_mday++;
58160 - if (alm_tm->tm_mday > 31)
58161 - alm_tm->tm_mday = 0;
58162 + alm_tm->tm_wday++;
58163 + if (alm_tm->tm_wday > 6)
58164 + alm_tm->tm_wday = 0;
58165 + switch (alm_tm->tm_mon + 1) {
58173 + if (alm_tm->tm_mday > 31)
58174 + alm_tm->tm_mday = 1;
58180 + if (alm_tm->tm_mday > 30)
58181 + alm_tm->tm_mday = 1;
58184 + if (alm_tm->tm_year / 4 == 0) {
58185 + if (alm_tm->tm_mday > 29)
58186 + alm_tm->tm_mday = 1;
58187 + } else if (alm_tm->tm_mday > 28) {
58188 + alm_tm->tm_mday = 1;
58195 -
58199 @@ -519,6 +546,19 @@ static int hym8563_probe(struct i2c_client *client,
58217 hym8563 = devm_kzalloc(&client->dev, sizeof(*hym8563), GFP_KERNEL);
58219 @@ -527,7 +567,7 @@ static int hym8563_probe(struct i2c_client *client,
58220 hym8563->client = client;
58223 - device_set_wakeup_capable(&client->dev, true);
58224 + // device_set_wakeup_capable(&client->dev, true);
58228 @@ -547,14 +587,24 @@ static int hym8563_probe(struct i2c_client *client,
58232 + if (client->irq > 0 ||
58233 + device_property_read_bool(&client->dev, "wakeup-source")) {
58234 + device_init_wakeup(&client->dev, true);
58242 - dev_dbg(&client->dev, "rtc information is %s\n",
58243 + dev_info(&client->dev, "rtc information is %s\n",
58246 + hym8563_rtc_read_time(&client->dev, &tm_read);
58248 + (tm_read.tm_mon == -1) || (rtc_valid_tm(&tm_read) != 0))
58249 + hym8563_rtc_set_time(&client->dev, &tm);
58251 hym8563->rtc = devm_rtc_device_register(&client->dev, client->name,
58253 if (IS_ERR(hym8563->rtc))
58254 diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
58256 --- a/drivers/soc/rockchip/Kconfig
58258 @@ -1,19 +1,49 @@
58259 # SPDX-License-Identifier: GPL-2.0-only
58292 - bool "Rockchip General Register Files support" if COMPILE_TEST
58293 - default y if ARCH_ROCKCHIP
58297 special additional settings registers for a lot of soc-components.
58304 + This driver support Decompress IP built-in Rockchip SoC, support
58310 @@ -22,8 +52,24 @@ config ROCKCHIP_IODOMAIN
58331 - bool "Rockchip generic power domain"
58336 @@ -34,4 +80,71 @@ config ROCKCHIP_PM_DOMAINS
58344 + The Process-Voltage-Temperature Monitor (PVTM) is used to monitor
58408 diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
58410 --- a/drivers/soc/rockchip/Makefile
58412 @@ -2,6 +2,21 @@
58416 +obj-$(CONFIG_ROCKCHIP_CPUINFO) += rockchip-cpuinfo.o
58417 obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
58418 +obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS) += rockchip_decompress.o
58419 obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o
58420 obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
58421 +obj-$(CONFIG_ROCKCHIP_FIQ_DEBUGGER) += rk_fiq_debugger.o
58422 +obj-$(CONFIG_ROCKCHIP_VENDOR_STORAGE) += rk_vendor_storage.o
58423 +obj-$(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE) += sdmmc_vendor_storage.o
58424 +obj-$(CONFIG_ROCKCHIP_FLASH_VENDOR_STORAGE) += flash_vendor_storage.o
58425 +obj-$(CONFIG_ROCKCHIP_MTD_VENDOR_STORAGE) += mtd_vendor_storage.o
58426 +obj-$(CONFIG_ROCKCHIP_IPA) += rockchip_ipa.o
58427 +obj-$(CONFIG_ROCKCHIP_OPP) += rockchip_opp_select.o
58428 +obj-$(CONFIG_ROCKCHIP_PVTM) += rockchip_pvtm.o
58429 +obj-$(CONFIG_ROCKCHIP_SUSPEND_MODE) += rockchip_pm_config.o
58430 +obj-$(CONFIG_ROCKCHIP_SYSTEM_MONITOR) += rockchip_system_monitor.o
58431 +obj-$(CONFIG_ROCKCHIP_DEBUG) += rockchip_debug.o
58433 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/mmc/host/
58435 diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c
58437 --- a/drivers/soc/rockchip/grf.c
58439 @@ -7,6 +7,7 @@
58447 @@ -25,6 +26,21 @@ struct rockchip_grf_info {
58469 @@ -86,6 +102,17 @@ static const struct rockchip_grf_info rk3328_grf __initconst = {
58487 @@ -108,8 +135,37 @@ static const struct rockchip_grf_info rk3399_grf __initconst = {
58519 + .compatible = "rockchip,px30-grf",
58522 .compatible = "rockchip,rk3036-grf",
58525 @@ -121,6 +177,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
58527 .compatible = "rockchip,rk3288-grf",
58530 + .compatible = "rockchip,rk3308-grf",
58533 .compatible = "rockchip,rk3328-grf",
58535 @@ -130,6 +189,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
58537 .compatible = "rockchip,rk3399-grf",
58540 + .compatible = "rockchip,rv1126-grf",
58545 @@ -173,3 +235,6 @@ static int __init rockchip_grf_init(void)
58552 diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
58554 --- a/drivers/soc/rockchip/io-domain.c
58555 +++ b/drivers/soc/rockchip/io-domain.c
58556 @@ -51,6 +51,10 @@
58567 @@ -74,8 +78,51 @@ struct rockchip_iodomain {
58577 + struct rockchip_iodomain *iod = supply->iod;
58582 + switch (supply->idx) {
58586 + b = supply->idx;
58588 + b = supply->idx + 4;
58591 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
58592 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
58602 + b = supply->idx - 1;
58606 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
58607 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
58610 + return -EINVAL;
58619 @@ -139,7 +186,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
58623 - ret = rockchip_iodomain_write(supply, uV);
58624 + ret = supply->iod->write(supply, uV);
58628 @@ -401,6 +448,21 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
58650 @@ -431,6 +493,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
58672 .compatible = "rockchip,px30-io-voltage-domain",
58673 @@ -472,6 +550,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
58674 .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
58678 + .compatible = "rockchip,rk3568-pmu-io-voltage-domain",
58682 .compatible = "rockchip,rv1108-io-voltage-domain",
58684 @@ -480,6 +562,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
58685 .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
58689 + .compatible = "rockchip,rv1126-pmu-io-voltage-domain",
58695 @@ -505,6 +591,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
58697 iod->soc_data = match->data;
58699 + if (match->data == &soc_data_rk3568_pmu)
58700 + iod->write = rk3568_pmu_iodomain_write;
58702 + iod->write = rockchip_iodomain_write;
58704 parent = pdev->dev.parent;
58705 if (parent && parent->of_node) {
58706 iod->grf = syscon_node_to_regmap(parent->of_node);
58707 @@ -565,7 +656,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
58708 supply->reg = reg;
58709 supply->nb.notifier_call = rockchip_iodomain_notify;
58711 - ret = rockchip_iodomain_write(supply, uV);
58712 + ret = iod->write(supply, uV);
58714 supply->reg = NULL;
58716 diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
58718 --- a/drivers/soc/rockchip/pm_domains.c
58720 @@ -5,6 +5,7 @@
58728 @@ -15,7 +16,12 @@
58738 #include <dt-bindings/power/px30-power.h>
58739 #include <dt-bindings/power/rk3036-power.h>
58740 #include <dt-bindings/power/rk3066-power.h>
58741 @@ -29,6 +35,7 @@
58742 #include <dt-bindings/power/rk3399-power.h>
58749 @@ -37,6 +44,10 @@ struct rockchip_domain_info {
58760 @@ -45,6 +56,7 @@ struct rockchip_pmu_info {
58768 @@ -72,6 +84,9 @@ struct rockchip_pm_domain {
58778 @@ -83,32 +98,89 @@ struct rockchip_pmu {
58791 + mutex_lock(&pd->pmu->mutex);
58798 + mutex_unlock(&pd->pmu->mutex);
58803 -#define DOMAIN(pwr, status, req, idle, ack, wakeup) \
58846 -#define DOMAIN_M(pwr, status, req, idle, ack, wakeup) \
58864 -#define DOMAIN_RK3036(req, ack, idle, wakeup) \
58871 @@ -116,20 +188,53 @@ struct rockchip_pmu {
58875 -#define DOMAIN_PX30(pwr, status, req, wakeup) \
58876 - DOMAIN_M(pwr, status, req, (req) << 16, req, wakeup)
58904 -#define DOMAIN_RK3288(pwr, status, req, wakeup) \
58905 - DOMAIN(pwr, status, req, req, (req) << 16, wakeup)
58909 -#define DOMAIN_RK3328(pwr, status, req, wakeup) \
58910 - DOMAIN_M(pwr, pwr, req, (req) << 10, req, wakeup)
58914 -#define DOMAIN_RK3368(pwr, status, req, wakeup) \
58915 - DOMAIN(pwr, status, req, (req) << 16, req, wakeup)
58919 -#define DOMAIN_RK3399(pwr, status, req, wakeup) \
58920 - DOMAIN(pwr, status, req, req, req, wakeup)
58935 @@ -155,20 +260,25 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
58936 const struct rockchip_domain_info *pd_info = pd->info;
58937 struct generic_pm_domain *genpd = &pd->genpd;
58938 struct rockchip_pmu *pmu = pd->pmu;
58943 - int ret;
58946 + if (pd_info->req_offset)
58947 + pd_req_offset = pd_info->req_offset;
58949 if (pd_info->req_mask == 0)
58951 else if (pd_info->req_w_mask)
58952 - regmap_write(pmu->regmap, pmu->info->req_offset,
58953 + regmap_write(pmu->regmap, pmu->info->req_offset + pd_req_offset,
58954 idle ? (pd_info->req_mask | pd_info->req_w_mask) :
58955 pd_info->req_w_mask);
58957 - regmap_update_bits(pmu->regmap, pmu->info->req_offset,
58958 - pd_info->req_mask, idle ? -1U : 0);
58959 + regmap_update_bits(pmu->regmap, pmu->info->req_offset +
58960 + pd_req_offset, pd_info->req_mask,
58961 + idle ? -1U : 0);
58965 @@ -179,22 +289,48 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
58968 dev_err(pmu->dev,
58969 - "failed to get ack on domain '%s', val=0x%x\n",
58970 - genpd->name, val);
58971 - return ret;
58973 + genpd->name, idle, target_ack, val);
58980 dev_err(pmu->dev,
58981 - "failed to set idle on domain '%s', val=%d\n",
58982 - genpd->name, is_idle);
58983 - return ret;
58985 + genpd->name, idle, is_idle);
58989 - return 0;
59003 + return -EINVAL;
59005 + if (IS_ERR_OR_NULL(dev->pm_domain))
59006 + return -EINVAL;
59008 + genpd = pd_to_genpd(dev->pm_domain);
59021 @@ -245,11 +381,63 @@ static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
59032 + return -EINVAL;
59034 + if (IS_ERR_OR_NULL(dev->pm_domain))
59035 + return -EINVAL;
59037 + genpd = pd_to_genpd(dev->pm_domain);
59055 + return -EINVAL;
59057 + if (IS_ERR_OR_NULL(dev->pm_domain))
59058 + return -EINVAL;
59060 + genpd = pd_to_genpd(dev->pm_domain);
59073 struct rockchip_pmu *pmu = pd->pmu;
59076 + if (pd->info->repair_status_mask) {
59077 + regmap_read(pmu->regmap, pmu->info->repair_status_offset, &val);
59079 + return val & pd->info->repair_status_mask;
59082 /* check idle status for idle-only domains */
59083 if (pd->info->status_mask == 0)
59085 @@ -260,76 +448,131 @@ static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
59086 return !(val & pd->info->status_mask);
59089 -static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
59090 - bool on)
59094 struct rockchip_pmu *pmu = pd->pmu;
59095 struct generic_pm_domain *genpd = &pd->genpd;
59100 + if (pd->info->pwr_offset)
59101 + pd_pwr_offset = pd->info->pwr_offset;
59103 if (pd->info->pwr_mask == 0)
59104 - return;
59106 else if (pd->info->pwr_w_mask)
59107 - regmap_write(pmu->regmap, pmu->info->pwr_offset,
59108 + regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset,
59109 on ? pd->info->pwr_w_mask :
59110 (pd->info->pwr_mask | pd->info->pwr_w_mask));
59112 - regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
59113 - pd->info->pwr_mask, on ? 0 : -1U);
59114 + regmap_update_bits(pmu->regmap, pmu->info->pwr_offset +
59115 + pd_pwr_offset, pd->info->pwr_mask,
59116 + on ? 0 : -1U);
59120 - if (readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
59121 - is_on == on, 0, 10000)) {
59125 dev_err(pmu->dev,
59126 - "failed to set domain '%s', val=%d\n",
59127 - genpd->name, is_on);
59128 - return;
59130 + genpd->name, on, is_on);
59142 struct rockchip_pmu *pmu = pd->pmu;
59143 - int ret;
59145 + struct generic_pm_domain *genpd = &pd->genpd;
59147 - mutex_lock(&pmu->mutex);
59154 + if (IS_ERR_OR_NULL(pd->supply) &&
59155 + PTR_ERR(pd->supply) != -ENODEV)
59156 + pd->supply = devm_regulator_get_optional(pd->pmu->dev,
59157 + genpd->name);
59159 + if (power_on && !IS_ERR(pd->supply)) {
59160 + ret = regulator_enable(pd->supply);
59162 + dev_err(pd->pmu->dev, "failed to set vdd supply enable '%s',\n",
59163 + genpd->name);
59169 ret = clk_bulk_enable(pd->num_clks, pd->clks);
59171 dev_err(pmu->dev, "failed to enable clocks\n");
59172 - mutex_unlock(&pmu->mutex);
59179 + pd->is_qos_saved = true;
59182 - rockchip_pmu_set_idle_request(pd, true);
59185 + dev_err(pd->pmu->dev, "failed to set idle request '%s',\n",
59186 + genpd->name);
59191 - rockchip_do_pmu_set_power_domain(pd, power_on);
59194 + dev_err(pd->pmu->dev, "failed to set power '%s' = %d,\n",
59195 + genpd->name, power_on);
59201 - rockchip_pmu_set_idle_request(pd, false);
59204 + dev_err(pd->pmu->dev, "failed to set deidle request '%s',\n",
59205 + genpd->name);
59209 - rockchip_pmu_restore_qos(pd);
59210 + if (pd->is_qos_saved)
59215 clk_bulk_disable(pd->num_clks, pd->clks);
59217 + if (!power_on && !IS_ERR(pd->supply))
59218 + ret = regulator_disable(pd->supply);
59221 - mutex_unlock(&pmu->mutex);
59222 - return 0;
59231 + if (pd->is_ignore_pwr)
59237 @@ -337,9 +580,71 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain)
59241 + if (pd->is_ignore_pwr)
59253 + return -EINVAL;
59255 + if (IS_ERR_OR_NULL(dev->pm_domain))
59256 + return -EINVAL;
59258 + genpd = pd_to_genpd(dev->pm_domain);
59271 + return -EINVAL;
59273 + if (IS_ERR_OR_NULL(dev->pm_domain))
59274 + return -EINVAL;
59276 + genpd = pd_to_genpd(dev->pm_domain);
59292 + if (IS_ERR_OR_NULL(dev->pm_domain))
59295 + genpd = pd_to_genpd(dev->pm_domain);
59309 @@ -378,15 +683,58 @@ static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
59322 + for (i = 0; i < pd->num_qos; i++) {
59324 + regmap_write(pd->qos_regmap[i],
59326 + pd->qos_save_regs[0][i]);
59329 + regmap_write(pd->qos_regmap[i],
59331 + pd->qos_save_regs[1][i]);
59334 + regmap_write(pd->qos_regmap[i],
59336 + pd->qos_save_regs[2][i]);
59339 + regmap_write(pd->qos_regmap[i],
59341 + pd->qos_save_regs[3][i]);
59344 + regmap_write(pd->qos_regmap[i],
59346 + pd->qos_save_regs[4][i]);
59361 - u32 id;
59369 @@ -401,6 +749,8 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59371 return -EINVAL;
59373 + if (pmu->genpd_data.domains[id])
59376 pd_info = &pmu->info->domain_info[id];
59378 @@ -415,6 +765,8 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59380 pd->info = pd_info;
59381 pd->pmu = pmu;
59382 + if (!pd_info->pwr_mask)
59383 + pd->is_ignore_pwr = true;
59385 pd->num_clks = of_clk_get_parent_count(node);
59386 if (pd->num_clks > 0) {
59387 @@ -443,8 +795,14 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59391 - pd->num_qos = of_count_phandle_with_args(node, "pm_qos",
59392 - NULL);
59398 + pd->num_qos++;
59402 if (pd->num_qos > 0) {
59403 pd->qos_regmap = devm_kcalloc(pmu->dev, pd->num_qos,
59404 @@ -455,55 +813,127 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59408 - for (j = 0; j < MAX_QOS_REGS_NUM; j++) {
59409 - pd->qos_save_regs[j] = devm_kcalloc(pmu->dev,
59410 - pd->num_qos,
59411 - sizeof(u32),
59412 - GFP_KERNEL);
59413 - if (!pd->qos_save_regs[j]) {
59414 - error = -ENOMEM;
59415 - goto err_unprepare_clocks;
59416 - }
59417 + pd->qos_save_regs[0] = (u32 *)devm_kmalloc(pmu->dev,
59420 + pd->num_qos,
59422 + if (!pd->qos_save_regs[0]) {
59423 + error = -ENOMEM;
59428 + pd->num_qos,
59431 + error = -ENOMEM;
59435 + pd->qos_save_regs[i] = pd->qos_save_regs[i - 1] +
59437 + qos_is_need_init[i] = qos_is_need_init[i - 1] + num_qos;
59440 - for (j = 0; j < pd->num_qos; j++) {
59444 error = -ENODEV;
59447 - pd->qos_regmap[j] = syscon_node_to_regmap(qos_node);
59448 - if (IS_ERR(pd->qos_regmap[j])) {
59449 - error = -ENODEV;
59450 - of_node_put(qos_node);
59451 - goto err_unprepare_clocks;
59453 + pd->qos_regmap[num_qos_reg] =
59455 + if (IS_ERR(pd->qos_regmap[num_qos_reg])) {
59456 + error = -ENODEV;
59461 + "priority-init",
59463 + pd->qos_save_regs[0][j] = val;
59469 + "mode-init",
59471 + pd->qos_save_regs[1][j] = val;
59477 + "bandwidth-init",
59479 + pd->qos_save_regs[2][j] = val;
59485 + "saturation-init",
59487 + pd->qos_save_regs[3][j] = val;
59493 + "extcontrol-init",
59495 + pd->qos_save_regs[4][j] = val;
59503 + if (num_qos_reg > pd->num_qos)
59508 - error = rockchip_pd_power(pd, true);
59509 - if (error) {
59510 - dev_err(pmu->dev,
59511 - "failed to power on domain '%pOFn': %d\n",
59512 - node, error);
59513 - goto err_unprepare_clocks;
59514 - }
59515 -
59516 - pd->genpd.name = node->name;
59517 + if (pd->info->name)
59518 + pd->genpd.name = pd->info->name;
59520 + pd->genpd.name = kbasename(node->full_name);
59521 pd->genpd.power_off = rockchip_pd_power_off;
59522 pd->genpd.power_on = rockchip_pd_power_on;
59523 pd->genpd.attach_dev = rockchip_pd_attach_dev;
59524 pd->genpd.detach_dev = rockchip_pd_detach_dev;
59525 - pd->genpd.flags = GENPD_FLAG_PM_CLK;
59526 if (pd_info->active_wakeup)
59527 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
59528 - pm_genpd_init(&pd->genpd, NULL, false);
59530 + if (pd_info->keepon_startup) {
59531 + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
59535 + dev_err(pmu->dev,
59537 + node->name, error);
59548 + pm_genpd_init(&pd->genpd, NULL, !rockchip_pmu_domain_is_on(pd));
59550 pmu->genpd_data.domains[id] = &pd->genpd;
59555 clk_bulk_unprepare(pd->num_clks, pd->clks);
59557 clk_bulk_put(pd->num_clks, pd->clks);
59558 @@ -527,9 +957,9 @@ static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
59559 clk_bulk_put(pd->num_clks, pd->clks);
59561 /* protect the zeroing of pm->num_clks */
59562 - mutex_lock(&pd->pmu->mutex);
59564 pd->num_clks = 0;
59565 - mutex_unlock(&pd->pmu->mutex);
59570 @@ -566,6 +996,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
59578 @@ -606,6 +1037,17 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
59579 parent_domain->name, child_domain->name);
59590 + if (!parent_pd->is_ignore_pwr)
59591 + child_pd->is_ignore_pwr = false;
59596 @@ -616,6 +1058,75 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
59607 + pd->genpd.flags &= (~GENPD_FLAG_ALWAYS_ON);
59608 + list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
59609 + if (!atomic_read(&pm_data->dev->power.usage_count)) {
59611 + if (!pm_runtime_enabled(pm_data->dev)) {
59612 + pm_runtime_enable(pm_data->dev);
59615 + pm_runtime_get_sync(pm_data->dev);
59616 + pm_runtime_put_sync(pm_data->dev);
59618 + pm_runtime_disable(pm_data->dev);
59632 + for (i = 0; i < g_pmu->genpd_data.num_domains; i++) {
59633 + genpd = g_pmu->genpd_data.domains[i];
59636 + if (pd->info->keepon_startup)
59671 struct device *dev = &pdev->dev;
59672 @@ -626,6 +1137,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59680 @@ -666,6 +1178,14 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59681 return PTR_ERR(pmu->regmap);
59684 + reg_base = of_iomap(parent->of_node, 0);
59687 + return -ENOMEM;
59695 @@ -708,6 +1228,10 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59706 @@ -716,129 +1240,129 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59710 - [PX30_PD_USB] = DOMAIN_PX30(BIT(5), BIT(5), BIT(10), false),
59711 - [PX30_PD_SDCARD] = DOMAIN_PX30(BIT(8), BIT(8), BIT(9), false),
59712 - [PX30_PD_GMAC] = DOMAIN_PX30(BIT(10), BIT(10), BIT(6), false),
59713 - [PX30_PD_MMC_NAND] = DOMAIN_PX30(BIT(11), BIT(11), BIT(5), false),
59714 - [PX30_PD_VPU] = DOMAIN_PX30(BIT(12), BIT(12), BIT(14), false),
59715 - [PX30_PD_VO] = DOMAIN_PX30(BIT(13), BIT(13), BIT(7), false),
59716 - [PX30_PD_VI] = DOMAIN_PX30(BIT(14), BIT(14), BIT(8), false),
59717 - [PX30_PD_GPU] = DOMAIN_PX30(BIT(15), BIT(15), BIT(2), false),
59729 - [RK3036_PD_MSCH] = DOMAIN_RK3036(BIT(14), BIT(23), BIT(30), true),
59730 - [RK3036_PD_CORE] = DOMAIN_RK3036(BIT(13), BIT(17), BIT(24), false),
59731 - [RK3036_PD_PERI] = DOMAIN_RK3036(BIT(12), BIT(18), BIT(25), false),
59732 - [RK3036_PD_VIO] = DOMAIN_RK3036(BIT(11), BIT(19), BIT(26), false),
59733 - [RK3036_PD_VPU] = DOMAIN_RK3036(BIT(10), BIT(20), BIT(27), false),
59734 - [RK3036_PD_GPU] = DOMAIN_RK3036(BIT(9), BIT(21), BIT(28), false),
59735 - [RK3036_PD_SYS] = DOMAIN_RK3036(BIT(8), BIT(22), BIT(29), false),
59746 - [RK3066_PD_GPU] = DOMAIN(BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
59747 - [RK3066_PD_VIDEO] = DOMAIN(BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
59748 - [RK3066_PD_VIO] = DOMAIN(BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
59749 - [RK3066_PD_PERI] = DOMAIN(BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
59750 - [RK3066_PD_CPU] = DOMAIN(0, BIT(5), BIT(1), BIT(26), BIT(31), false),
59759 - [RK3128_PD_CORE] = DOMAIN_RK3288(BIT(0), BIT(0), BIT(4), false),
59760 - [RK3128_PD_MSCH] = DOMAIN_RK3288(0, 0, BIT(6), true),
59761 - [RK3128_PD_VIO] = DOMAIN_RK3288(BIT(3), BIT(3), BIT(2), false),
59762 - [RK3128_PD_VIDEO] = DOMAIN_RK3288(BIT(2), BIT(2), BIT(1), false),
59763 - [RK3128_PD_GPU] = DOMAIN_RK3288(BIT(1), BIT(1), BIT(3), false),
59772 - [RK3188_PD_GPU] = DOMAIN(BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
59773 - [RK3188_PD_VIDEO] = DOMAIN(BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
59774 - [RK3188_PD_VIO] = DOMAIN(BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
59775 - [RK3188_PD_PERI] = DOMAIN(BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
59776 - [RK3188_PD_CPU] = DOMAIN(BIT(5), BIT(5), BIT(1), BIT(26), BIT(31), false),
59785 - [RK3228_PD_CORE] = DOMAIN_RK3036(BIT(0), BIT(0), BIT(16), true),
59786 - [RK3228_PD_MSCH] = DOMAIN_RK3036(BIT(1), BIT(1), BIT(17), true),
59787 - [RK3228_PD_BUS] = DOMAIN_RK3036(BIT(2), BIT(2), BIT(18), true),
59788 - [RK3228_PD_SYS] = DOMAIN_RK3036(BIT(3), BIT(3), BIT(19), true),
59789 - [RK3228_PD_VIO] = DOMAIN_RK3036(BIT(4), BIT(4), BIT(20), false),
59790 - [RK3228_PD_VOP] = DOMAIN_RK3036(BIT(5), BIT(5), BIT(21), false),
59791 - [RK3228_PD_VPU] = DOMAIN_RK3036(BIT(6), BIT(6), BIT(22), false),
59792 - [RK3228_PD_RKVDEC] = DOMAIN_RK3036(BIT(7), BIT(7), BIT(23), false),
59793 - [RK3228_PD_GPU] = DOMAIN_RK3036(BIT(8), BIT(8), BIT(24), false),
59794 - [RK3228_PD_PERI] = DOMAIN_RK3036(BIT(9), BIT(9), BIT(25), true),
59795 - [RK3228_PD_GMAC] = DOMAIN_RK3036(BIT(10), BIT(10), BIT(26), false),
59810 - [RK3288_PD_VIO] = DOMAIN_RK3288(BIT(7), BIT(7), BIT(4), false),
59811 - [RK3288_PD_HEVC] = DOMAIN_RK3288(BIT(14), BIT(10), BIT(9), false),
59812 - [RK3288_PD_VIDEO] = DOMAIN_RK3288(BIT(8), BIT(8), BIT(3), false),
59813 - [RK3288_PD_GPU] = DOMAIN_RK3288(BIT(9), BIT(9), BIT(2), false),
59821 - [RK3328_PD_CORE] = DOMAIN_RK3328(0, BIT(0), BIT(0), false),
59822 - [RK3328_PD_GPU] = DOMAIN_RK3328(0, BIT(1), BIT(1), false),
59823 - [RK3328_PD_BUS] = DOMAIN_RK3328(0, BIT(2), BIT(2), true),
59824 - [RK3328_PD_MSCH] = DOMAIN_RK3328(0, BIT(3), BIT(3), true),
59825 - [RK3328_PD_PERI] = DOMAIN_RK3328(0, BIT(4), BIT(4), true),
59826 - [RK3328_PD_VIDEO] = DOMAIN_RK3328(0, BIT(5), BIT(5), false),
59827 - [RK3328_PD_HEVC] = DOMAIN_RK3328(0, BIT(6), BIT(6), false),
59828 - [RK3328_PD_VIO] = DOMAIN_RK3328(0, BIT(8), BIT(8), false),
59829 - [RK3328_PD_VPU] = DOMAIN_RK3328(0, BIT(9), BIT(9), false),
59842 - [RK3366_PD_PERI] = DOMAIN_RK3368(BIT(10), BIT(10), BIT(6), true),
59843 - [RK3366_PD_VIO] = DOMAIN_RK3368(BIT(14), BIT(14), BIT(8), false),
59844 - [RK3366_PD_VIDEO] = DOMAIN_RK3368(BIT(13), BIT(13), BIT(7), false),
59845 - [RK3366_PD_RKVDEC] = DOMAIN_RK3368(BIT(11), BIT(11), BIT(7), false),
59846 - [RK3366_PD_WIFIBT] = DOMAIN_RK3368(BIT(8), BIT(8), BIT(9), false),
59847 - [RK3366_PD_VPU] = DOMAIN_RK3368(BIT(12), BIT(12), BIT(7), false),
59848 - [RK3366_PD_GPU] = DOMAIN_RK3368(BIT(15), BIT(15), BIT(2), false),
59859 - [RK3368_PD_PERI] = DOMAIN_RK3368(BIT(13), BIT(12), BIT(6), true),
59860 - [RK3368_PD_VIO] = DOMAIN_RK3368(BIT(15), BIT(14), BIT(8), false),
59861 - [RK3368_PD_VIDEO] = DOMAIN_RK3368(BIT(14), BIT(13), BIT(7), false),
59862 - [RK3368_PD_GPU_0] = DOMAIN_RK3368(BIT(16), BIT(15), BIT(2), false),
59863 - [RK3368_PD_GPU_1] = DOMAIN_RK3368(BIT(17), BIT(16), BIT(2), false),
59872 - [RK3399_PD_TCPD0] = DOMAIN_RK3399(BIT(8), BIT(8), 0, false),
59873 - [RK3399_PD_TCPD1] = DOMAIN_RK3399(BIT(9), BIT(9), 0, false),
59874 - [RK3399_PD_CCI] = DOMAIN_RK3399(BIT(10), BIT(10), 0, true),
59875 - [RK3399_PD_CCI0] = DOMAIN_RK3399(0, 0, BIT(15), true),
59876 - [RK3399_PD_CCI1] = DOMAIN_RK3399(0, 0, BIT(16), true),
59877 - [RK3399_PD_PERILP] = DOMAIN_RK3399(BIT(11), BIT(11), BIT(1), true),
59878 - [RK3399_PD_PERIHP] = DOMAIN_RK3399(BIT(12), BIT(12), BIT(2), true),
59879 - [RK3399_PD_CENTER] = DOMAIN_RK3399(BIT(13), BIT(13), BIT(14), true),
59880 - [RK3399_PD_VIO] = DOMAIN_RK3399(BIT(14), BIT(14), BIT(17), false),
59881 - [RK3399_PD_GPU] = DOMAIN_RK3399(BIT(15), BIT(15), BIT(0), false),
59882 - [RK3399_PD_VCODEC] = DOMAIN_RK3399(BIT(16), BIT(16), BIT(3), false),
59883 - [RK3399_PD_VDU] = DOMAIN_RK3399(BIT(17), BIT(17), BIT(4), false),
59884 - [RK3399_PD_RGA] = DOMAIN_RK3399(BIT(18), BIT(18), BIT(5), false),
59885 - [RK3399_PD_IEP] = DOMAIN_RK3399(BIT(19), BIT(19), BIT(6), false),
59886 - [RK3399_PD_VO] = DOMAIN_RK3399(BIT(20), BIT(20), 0, false),
59887 - [RK3399_PD_VOPB] = DOMAIN_RK3399(0, 0, BIT(7), false),
59888 - [RK3399_PD_VOPL] = DOMAIN_RK3399(0, 0, BIT(8), false),
59889 - [RK3399_PD_ISP0] = DOMAIN_RK3399(BIT(22), BIT(22), BIT(9), false),
59890 - [RK3399_PD_ISP1] = DOMAIN_RK3399(BIT(23), BIT(23), BIT(10), false),
59891 - [RK3399_PD_HDCP] = DOMAIN_RK3399(BIT(24), BIT(24), BIT(11), false),
59892 - [RK3399_PD_GMAC] = DOMAIN_RK3399(BIT(25), BIT(25), BIT(23), true),
59893 - [RK3399_PD_EMMC] = DOMAIN_RK3399(BIT(26), BIT(26), BIT(24), true),
59894 - [RK3399_PD_USB3] = DOMAIN_RK3399(BIT(27), BIT(27), BIT(12), true),
59895 - [RK3399_PD_EDP] = DOMAIN_RK3399(BIT(28), BIT(28), BIT(22), false),
59896 - [RK3399_PD_GIC] = DOMAIN_RK3399(BIT(29), BIT(29), BIT(27), true),
59897 - [RK3399_PD_SD] = DOMAIN_RK3399(BIT(30), BIT(30), BIT(28), true),
59898 - [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(BIT(31), BIT(31), BIT(29), true),
59929 @@ -1023,6 +1547,7 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
59937 @@ -1043,3 +1568,12 @@ static int __init rockchip_pm_domain_drv_register(void)
59950 diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
59952 --- a/drivers/spi/spi-rockchip.c
59953 +++ b/drivers/spi/spi-rockchip.c
59954 @@ -10,6 +10,7 @@
59962 @@ -107,6 +108,8 @@
59971 @@ -116,13 +119,14 @@
59975 -/* Bit fields in SR, 5bit */
59976 -#define SR_MASK 0x1f
59988 @@ -130,7 +134,8 @@
59992 -#define INT_RF_FULL (1 << 4)
59998 @@ -149,6 +154,8 @@
60006 * SPI_CTRLR1 is 16-bits, so we should support lengths of 0xffff + 1. However,
60007 @@ -156,7 +163,8 @@
60011 -#define ROCKCHIP_SPI_MAX_CS_NUM 2
60012 +/* 2 for native cs, 2 for cs-gpio */
60017 @@ -187,7 +195,10 @@ struct rockchip_spi {
60028 @@ -195,13 +206,19 @@ static inline void spi_enable_chip(struct rockchip_spi *rs, bool enable)
60029 writel_relaxed((enable ? 1U : 0U), rs->regs + ROCKCHIP_SPI_SSIENR);
60032 -static inline void wait_for_idle(struct rockchip_spi *rs)
60038 - if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
60039 - return;
60041 + if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_SLAVE_TX_BUSY) &&
60042 + !((readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)))
60045 + if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
60050 dev_warn(rs->dev, "spi controller is in busy state!\n");
60051 @@ -226,7 +243,7 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
60053 struct spi_controller *ctlr = spi->controller;
60055 - bool cs_asserted = !enable;
60056 + bool cs_asserted = spi->mode & SPI_CS_HIGH ? enable : !enable;
60058 /* Return immediately for no-op */
60059 if (cs_asserted == rs->cs_asserted[spi->chip_select])
60060 @@ -236,11 +253,15 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
60062 pm_runtime_get_sync(rs->dev);
60064 - ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER,
60065 - BIT(spi->chip_select));
60066 + if (spi->cs_gpiod)
60067 + ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
60069 + ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
60071 - ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER,
60072 - BIT(spi->chip_select));
60073 + if (spi->cs_gpiod)
60074 + ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
60076 + ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
60079 pm_runtime_put(rs->dev);
60080 @@ -327,6 +348,15 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
60085 + if (rs->cs_inactive && readl_relaxed(rs->regs + ROCKCHIP_SPI_IMR) & INT_CS_INACTIVE) {
60086 + ctlr->slave_abort(ctlr);
60087 + writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
60088 + writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
60093 if (rs->tx_left)
60096 @@ -334,6 +364,7 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
60097 if (!rs->rx_left) {
60099 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
60100 + writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
60104 @@ -341,14 +372,18 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
60108 - struct spi_transfer *xfer)
60112 rs->tx = xfer->tx_buf;
60113 rs->rx = xfer->rx_buf;
60114 rs->tx_left = rs->tx ? xfer->len / rs->n_bytes : 0;
60115 rs->rx_left = xfer->len / rs->n_bytes;
60117 - writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
60118 + if (rs->cs_inactive)
60119 + writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
60121 + writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
60124 if (rs->tx_left)
60125 @@ -367,6 +402,9 @@ static void rockchip_spi_dma_rxcb(void *data)
60126 if (state & TXDMA && !rs->slave_abort)
60129 + if (rs->cs_inactive)
60130 + writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
60135 @@ -381,7 +419,7 @@ static void rockchip_spi_dma_txcb(void *data)
60139 - wait_for_idle(rs);
60140 + wait_for_tx_idle(rs, ctlr->slave);
60144 @@ -407,14 +445,16 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs,
60146 atomic_set(&rs->state, 0);
60148 + rs->tx = xfer->tx_buf;
60149 + rs->rx = xfer->rx_buf;
60152 if (xfer->rx_buf) {
60155 .src_addr = rs->dma_addr_rx,
60156 .src_addr_width = rs->n_bytes,
60157 - .src_maxburst = rockchip_spi_calc_burst_size(xfer->len /
60158 - rs->n_bytes),
60159 + .src_maxburst = rockchip_spi_calc_burst_size(xfer->len / rs->n_bytes),
60162 dmaengine_slave_config(ctlr->dma_rx, &rxconf);
60163 @@ -458,10 +498,13 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs,
60164 /* rx must be started before tx due to spi instinct */
60166 atomic_or(RXDMA, &rs->state);
60167 - dmaengine_submit(rxdesc);
60168 + ctlr->dma_rx->cookie = dmaengine_submit(rxdesc);
60169 dma_async_issue_pending(ctlr->dma_rx);
60172 + if (rs->cs_inactive)
60173 + writel_relaxed(INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
60178 @@ -493,6 +536,8 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
60179 cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET;
60180 if (spi->mode & SPI_LSB_FIRST)
60182 + if (spi->mode & SPI_CS_HIGH)
60183 + cr0 |= BIT(spi->chip_select) << CR0_SOI_OFFSET;
60185 if (xfer->rx_buf && xfer->tx_buf)
60187 @@ -531,6 +576,19 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
60195 + if (rs->high_speed_state) {
60196 + if (rs->freq > IO_DRIVER_4MA_MAX_SCLK_OUT)
60197 + pinctrl_select_state(rs->dev->pins->p,
60198 + rs->high_speed_state);
60200 + pinctrl_select_state(rs->dev->pins->p,
60201 + rs->dev->pins->default_state);
60204 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
60205 writel_relaxed(cr1, rs->regs + ROCKCHIP_SPI_CTRLR1);
60207 @@ -538,12 +596,12 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
60211 - if (xfer->len < rs->fifo_len)
60212 - writel_relaxed(xfer->len - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
60213 + if ((xfer->len / rs->n_bytes) < rs->fifo_len)
60214 + writel_relaxed(xfer->len / rs->n_bytes - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
60216 writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
60218 - writel_relaxed(rs->fifo_len / 2, rs->regs + ROCKCHIP_SPI_DMATDLR);
60219 + writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_DMATDLR);
60220 writel_relaxed(rockchip_spi_calc_burst_size(xfer->len / rs->n_bytes) - 1,
60221 rs->regs + ROCKCHIP_SPI_DMARDLR);
60222 writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR);
60223 @@ -566,7 +624,46 @@ static size_t rockchip_spi_max_transfer_size(struct spi_device *spi)
60232 + if (atomic_read(&rs->state) & RXDMA) {
60233 + dmaengine_pause(ctlr->dma_rx);
60234 + status = dmaengine_tx_status(ctlr->dma_rx, ctlr->dma_rx->cookie, &state);
60235 + dmaengine_terminate_sync(ctlr->dma_rx);
60236 + atomic_set(&rs->state, 0);
60238 + rs->rx = rs->xfer->rx_buf;
60239 + rs->xfer->len = 0;
60240 + rx_fifo_left = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
60241 + for (; rx_fifo_left; rx_fifo_left--)
60242 + readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
60245 + rs->rx += rs->xfer->len - rs->n_bytes * state.residue;
60249 + /* Get the valid data left in rx fifo and set rs->xfer->len real rx size */
60250 + if (rs->rx) {
60251 + rx_fifo_left = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
60252 + for (; rx_fifo_left; rx_fifo_left--) {
60253 + u32 rxw = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
60255 + if (rs->n_bytes == 1)
60256 + *(u8 *)rs->rx = (u8)rxw;
60258 + *(u16 *)rs->rx = (u16)rxw;
60259 + rs->rx += rs->n_bytes;
60262 + rs->xfer->len = (unsigned int)(rs->rx - rs->xfer->rx_buf);
60267 rs->slave_abort = true;
60268 complete(&ctlr->xfer_completion);
60270 @@ -582,12 +679,6 @@ static int rockchip_spi_transfer_one(
60274 - /* Zero length transfers won't trigger an interrupt on completion */
60275 - if (!xfer->len) {
60276 - spi_finalize_current_transfer(ctlr);
60277 - return 1;
60278 - }
60279 -
60280 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
60281 (readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY));
60283 @@ -602,7 +693,7 @@ static int rockchip_spi_transfer_one(
60286 rs->n_bytes = xfer->bits_per_word <= 8 ? 1 : 2;
60287 -
60288 + rs->xfer = xfer;
60289 use_dma = ctlr->can_dma ? ctlr->can_dma(ctlr, spi, xfer) : false;
60291 ret = rockchip_spi_config(rs, spi, xfer, use_dma, ctlr->slave);
60292 @@ -612,7 +703,7 @@ static int rockchip_spi_transfer_one(
60296 - return rockchip_spi_prepare_irq(rs, xfer);
60301 @@ -638,6 +729,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
60302 struct device_node *np = pdev->dev.of_node;
60307 slave_mode = of_property_read_bool(np, "spi-slave");
60309 @@ -785,6 +877,28 @@ static int rockchip_spi_probe(struct platform_device *pdev)
60310 ctlr->can_dma = rockchip_spi_can_dma;
60313 + switch (readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION)) {
60315 + ctlr->mode_bits |= SPI_CS_HIGH;
60316 + if (ctlr->can_dma && slave_mode)
60317 + rs->cs_inactive = true;
60319 + rs->cs_inactive = false;
60322 + rs->cs_inactive = false;
60326 + pinctrl = devm_pinctrl_get(&pdev->dev);
60328 + rs->high_speed_state = pinctrl_lookup_state(pinctrl, "high_speed");
60329 + if (IS_ERR_OR_NULL(rs->high_speed_state)) {
60330 + dev_warn(&pdev->dev, "no high_speed pinctrl state\n");
60331 + rs->high_speed_state = NULL;
60335 ret = devm_spi_register_controller(&pdev->dev, ctlr);
60337 dev_err(&pdev->dev, "Failed to register controller\n");
60338 diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
60340 --- a/drivers/spi/spidev.c
60342 @@ -682,6 +682,7 @@ static const struct of_device_id spidev_dt_ids[] = {
60344 { .compatible = "dh,dhcom-board" },
60350 diff --git a/drivers/staging/blackbox/Kconfig b/drivers/staging/blackbox/Kconfig
60352 --- a/drivers/staging/blackbox/Kconfig
60354 @@ -106,3 +106,14 @@ config DEF_BLACKBOX_STORAGE
60369 diff --git a/drivers/staging/blackbox/Makefile b/drivers/staging/blackbox/Makefile
60371 --- a/drivers/staging/blackbox/Makefile
60373 @@ -3,3 +3,5 @@
60374 obj-$(CONFIG_BLACKBOX) += blackbox_core.o \
60378 +obj-$(CONFIG_BLACKBOX_ROCKCHIP) += ../../$(VENDOR_DRIVER_DIR)/staging/blackbox/rockchip/
60379 diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
60381 --- a/drivers/thermal/rockchip_thermal.c
60383 @@ -18,6 +18,7 @@
60387 +#include <linux/nvmem-consumer.h>
60391 @@ -26,7 +27,7 @@
60395 - TSHUT_MODE_GPIO,
60400 @@ -71,12 +72,17 @@ enum adc_sort_mode {
60418 @@ -94,6 +100,8 @@ struct chip_tsadc_table {
60420 * @set_tshut_temp: set the hardware-controlled shutdown temperature
60421 * @set_tshut_mode: set the hardware-controlled shutdown mode
60424 * @table: the chip-specific conversion table
60427 @@ -119,7 +127,11 @@ struct rockchip_tsadc_chip {
60431 - void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m);
60438 /* Per-table methods */
60440 @@ -143,13 +155,18 @@ struct rockchip_thermal_sensor {
60444 - * @clk: the controller clock is divided by the exteral 24MHz
60445 - * @pclk: the advanced peripherals bus clock
60450 * @tshut_temp: the hardware-controlled shutdown temperature value
60452 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
60453 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
60461 @@ -158,15 +175,21 @@ struct rockchip_thermal_data {
60465 - struct clk *clk;
60466 - struct clk *pclk;
60485 @@ -210,8 +233,11 @@ struct rockchip_thermal_data {
60497 @@ -219,13 +245,33 @@ struct rockchip_thermal_data {
60523 +#define MIN_TEMP (-40000)
60524 +#define LOWEST_TEMP (-273000)
60529 * struct tsadc_table - code to temperature conversion table
60531 @@ -241,6 +287,7 @@ struct tsadc_table {
60537 {0, -40000},
60538 {374, -40000},
60539 @@ -280,6 +327,45 @@ static const struct tsadc_table rv1108_table[] = {
60544 + {0, -40000},
60545 + {3455, -40000},
60546 + {3463, -35000},
60547 + {3471, -30000},
60548 + {3479, -25000},
60549 + {3487, -20000},
60550 + {3495, -15000},
60551 + {3503, -10000},
60552 + {3511, -5000},
60583 {0, -40000},
60584 {588, -40000},
60585 @@ -474,6 +560,45 @@ static const struct tsadc_table rk3399_code_table[] = {
60590 + {0, -40000},
60591 + {1584, -40000},
60592 + {1620, -35000},
60593 + {1652, -30000},
60594 + {1688, -25000},
60595 + {1720, -20000},
60596 + {1756, -15000},
60597 + {1788, -10000},
60598 + {1824, -5000},
60631 @@ -482,6 +607,9 @@ static u32 rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table,
60633 u32 error = table->data_mask;
60635 + if (table->kNum)
60636 + return (((temp / 1000) * table->kNum) / 1000 + table->bNum);
60639 high = (table->length - 1) - 1; /* ignore the last check for table */
60641 @@ -535,6 +663,13 @@ static int rk_tsadcv2_code_to_temp(const struct chip_tsadc_table *table,
60645 + if (table->kNum) {
60646 + *temp = (((int)code - table->bNum) * 10000 / table->kNum) * 100;
60648 + return -EAGAIN;
60652 WARN_ON(table->length < 2);
60654 switch (table->mode) {
60655 @@ -701,6 +836,70 @@ static void rk_tsadcv4_initialize(struct regmap *grf, void __iomem *regs,
60726 @@ -815,23 +1014,69 @@ static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table,
60730 -static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
60756 - if (mode == TSHUT_MODE_GPIO) {
60778 + const struct chip_tsadc_table *table = &thermal->chip->table;
60782 + base_code = trim_base * table->kNum / 1000 + table->bNum;
60783 + trim_code = code - base_code - 10;
60792 + return thermal->trim * 500;
60798 @@ -860,7 +1105,7 @@ static const struct rockchip_tsadc_chip rv1108_tsadc_data = {
60802 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60807 @@ -880,11 +1125,61 @@ static const struct rockchip_tsadc_chip rv1108_tsadc_data = {
60865 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60870 @@ -909,7 +1204,7 @@ static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
60874 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60879 @@ -957,7 +1252,7 @@ static const struct rockchip_tsadc_chip rk3366_tsadc_data = {
60883 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60888 @@ -982,7 +1277,7 @@ static const struct rockchip_tsadc_chip rk3368_tsadc_data = {
60892 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60897 @@ -1007,7 +1302,7 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
60901 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60906 @@ -1027,6 +1322,31 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
60936 { .compatible = "rockchip,px30-tsadc",
60938 @@ -1035,6 +1355,14 @@ static const struct of_device_id of_rockchip_thermal_match[] = {
60939 .compatible = "rockchip,rv1108-tsadc",
60943 + .compatible = "rockchip,rv1126-tsadc",
60947 + .compatible = "rockchip,rk1808-tsadc",
60951 .compatible = "rockchip,rk3228-tsadc",
60953 @@ -1059,6 +1387,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = {
60954 .compatible = "rockchip,rk3399-tsadc",
60958 + .compatible = "rockchip,rk3568-tsadc",
60964 @@ -1099,6 +1431,9 @@ static int rockchip_thermal_set_trips(void *_sensor, int low, int high)
60965 dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n",
60966 __func__, sensor->id, low, high);
60968 + if (tsadc->trim_temp)
60969 + high += tsadc->trim_temp(thermal->pdev);
60971 return tsadc->set_alarm_temp(&tsadc->table,
60972 sensor->id, thermal->regs, high);
60974 @@ -1112,6 +1447,8 @@ static int rockchip_thermal_get_temp(void *_sensor, int *out_temp)
60976 retval = tsadc->get_temp(&tsadc->table,
60977 sensor->id, thermal->regs, out_temp);
60978 + if (tsadc->trim_temp)
60979 + *out_temp -= tsadc->trim_temp(thermal->pdev);
60980 dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n",
60981 sensor->id, *out_temp, retval);
60983 @@ -1123,11 +1460,52 @@ static const struct thermal_zone_of_device_ops rockchip_of_thermal_ops = {
60989 + if (!IS_ERR(thermal->pinctrl) && !IS_ERR_OR_NULL(thermal->otp_state))
60990 + pinctrl_select_state(thermal->pinctrl,
60991 + thermal->otp_state);
60996 + if (!IS_ERR(thermal->pinctrl) && !IS_ERR_OR_NULL(thermal->gpio_state))
60997 + pinctrl_select_state(thermal->pinctrl,
60998 + thermal->gpio_state);
61030 + const struct rockchip_tsadc_chip *tsadc = thermal->chip;
61034 if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) {
61036 @@ -1146,7 +1524,7 @@ static int rockchip_configure_from_dt(struct device *dev,
61037 if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) {
61040 - thermal->chip->tshut_mode == TSHUT_MODE_GPIO ?
61041 + thermal->chip->tshut_mode == TSHUT_MODE_OTP ?
61043 thermal->tshut_mode = thermal->chip->tshut_mode;
61045 @@ -1183,6 +1561,29 @@ static int rockchip_configure_from_dt(struct device *dev,
61046 if (IS_ERR(thermal->grf))
61049 + if (tsadc->trim_temp && tsadc->get_trim_code) {
61062 + thermal->trim = tsadc->get_trim_code(thermal->pdev,
61067 + thermal->trim);
61068 + thermal->tshut_temp += tsadc->trim_temp(thermal->pdev);
61075 @@ -1195,7 +1596,8 @@ rockchip_thermal_register_sensor(struct platform_device *pdev,
61076 const struct rockchip_tsadc_chip *tsadc = thermal->chip;
61079 - tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);
61080 + tsadc->set_tshut_mode(thermal->grf, id, thermal->regs,
61081 + thermal->tshut_mode);
61083 error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs,
61084 thermal->tshut_temp);
61085 @@ -1228,6 +1630,43 @@ static void rockchip_thermal_reset_controller(struct reset_control *reset)
61097 + pdev = thermal->pdev;
61099 + for (i = 0; i < thermal->chip->chn_num; i++) {
61100 + struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
61101 + struct thermal_zone_device *tz = sensor->tzd;
61103 + if (tz->temperature != THERMAL_TEMP_INVALID)
61104 + dev_warn(&pdev->dev, "channal %d: temperature(%d C)\n",
61105 + i, tz->temperature / 1000);
61108 + if (thermal->regs) {
61111 + 32, 4, thermal->regs, 0x88, false);
61128 struct device_node *np = pdev->dev.of_node;
61129 @@ -1262,40 +1701,26 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61130 if (IS_ERR(thermal->regs))
61131 return PTR_ERR(thermal->regs);
61133 - thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb");
61134 + thermal->reset = devm_reset_control_array_get(&pdev->dev, false, false);
61135 if (IS_ERR(thermal->reset)) {
61136 - error = PTR_ERR(thermal->reset);
61137 - dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error);
61138 - return error;
61139 - }
61140 -
61141 - thermal->clk = devm_clk_get(&pdev->dev, "tsadc");
61142 - if (IS_ERR(thermal->clk)) {
61143 - error = PTR_ERR(thermal->clk);
61144 - dev_err(&pdev->dev, "failed to get tsadc clock: %d\n", error);
61145 - return error;
61146 + if (PTR_ERR(thermal->reset) != -EPROBE_DEFER)
61147 + dev_err(&pdev->dev, "failed to get tsadc reset lines\n");
61148 + return PTR_ERR(thermal->reset);
61151 - thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
61152 - if (IS_ERR(thermal->pclk)) {
61153 - error = PTR_ERR(thermal->pclk);
61154 - dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n",
61155 - error);
61156 - return error;
61157 - }
61158 + thermal->num_clks = devm_clk_bulk_get_all(&pdev->dev, &thermal->clks);
61159 + if (thermal->num_clks < 1)
61160 + return -ENODEV;
61162 - error = clk_prepare_enable(thermal->clk);
61163 + error = clk_bulk_prepare_enable(thermal->num_clks, thermal->clks);
61165 - dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
61166 + dev_err(&pdev->dev, "failed to prepare enable tsadc bulk clks: %d\n",
61172 - error = clk_prepare_enable(thermal->pclk);
61173 - if (error) {
61174 - dev_err(&pdev->dev, "failed to enable pclk: %d\n", error);
61175 - goto err_disable_clk;
61176 - }
61177 + thermal->chip->control(thermal->regs, false);
61179 rockchip_thermal_reset_controller(thermal->reset);
61181 @@ -1303,12 +1728,30 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61183 dev_err(&pdev->dev, "failed to parse device tree data: %d\n",
61185 - goto err_disable_pclk;
61189 thermal->chip->initialize(thermal->grf, thermal->regs,
61190 thermal->tshut_polarity);
61192 + if (thermal->tshut_mode == TSHUT_MODE_OTP) {
61193 + thermal->pinctrl = devm_pinctrl_get(&pdev->dev);
61194 + if (IS_ERR(thermal->pinctrl))
61195 + dev_err(&pdev->dev, "failed to find thermal pinctrl\n");
61197 + thermal->gpio_state = pinctrl_lookup_state(thermal->pinctrl,
61199 + if (IS_ERR_OR_NULL(thermal->gpio_state))
61200 + dev_err(&pdev->dev, "failed to find thermal gpio state\n");
61202 + thermal->otp_state = pinctrl_lookup_state(thermal->pinctrl,
61204 + if (IS_ERR_OR_NULL(thermal->otp_state))
61205 + dev_err(&pdev->dev, "failed to find thermal otpout state\n");
61210 for (i = 0; i < thermal->chip->chn_num; i++) {
61212 &thermal->sensors[i],
61213 @@ -1317,7 +1760,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61214 dev_err(&pdev->dev,
61217 - goto err_disable_pclk;
61222 @@ -1328,7 +1771,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61224 dev_err(&pdev->dev,
61226 - goto err_disable_pclk;
61230 thermal->chip->control(thermal->regs, true);
61231 @@ -1343,14 +1786,16 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61235 - platform_set_drvdata(pdev, thermal);
61236 + thermal->panic_nb.notifier_call = rockchip_thermal_panic;
61238 + &thermal->panic_nb);
61240 + dev_info(&pdev->dev, "tsadc is probed successfully!\n");
61244 -err_disable_pclk:
61245 - clk_disable_unprepare(thermal->pclk);
61246 -err_disable_clk:
61247 - clk_disable_unprepare(thermal->clk);
61249 + clk_bulk_disable_unprepare(thermal->num_clks, thermal->clks);
61253 @@ -1369,12 +1814,28 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
61255 thermal->chip->control(thermal->regs, false);
61257 - clk_disable_unprepare(thermal->pclk);
61258 - clk_disable_unprepare(thermal->clk);
61259 + clk_bulk_disable_unprepare(thermal->num_clks, thermal->clks);
61269 + for (i = 0; i < thermal->chip->chn_num; i++) {
61270 + int id = thermal->sensors[i].id;
61272 + if (thermal->tshut_mode != TSHUT_MODE_CRU)
61273 + thermal->chip->set_tshut_mode(thermal->grf, id,
61274 + thermal->regs,
61277 + if (thermal->tshut_mode == TSHUT_MODE_OTP)
61284 @@ -1385,10 +1846,10 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
61286 thermal->chip->control(thermal->regs, false);
61288 - clk_disable(thermal->pclk);
61289 - clk_disable(thermal->clk);
61290 + clk_bulk_disable(thermal->num_clks, thermal->clks);
61292 - pinctrl_pm_select_sleep_state(dev);
61293 + if (thermal->tshut_mode == TSHUT_MODE_OTP)
61298 @@ -1399,13 +1860,10 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
61302 - error = clk_enable(thermal->clk);
61303 - if (error)
61304 - return error;
61305 -
61306 - error = clk_enable(thermal->pclk);
61307 + error = clk_bulk_enable(thermal->num_clks, thermal->clks);
61309 - clk_disable(thermal->clk);
61315 @@ -1417,7 +1875,7 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
61316 for (i = 0; i < thermal->chip->chn_num; i++) {
61317 int id = thermal->sensors[i].id;
61319 - thermal->chip->set_tshut_mode(id, thermal->regs,
61320 + thermal->chip->set_tshut_mode(thermal->grf, id, thermal->regs,
61321 thermal->tshut_mode);
61323 error = thermal->chip->set_tshut_temp(&thermal->chip->table,
61324 @@ -1433,7 +1891,8 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
61325 for (i = 0; i < thermal->chip->chn_num; i++)
61326 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
61328 - pinctrl_pm_select_default_state(dev);
61329 + if (thermal->tshut_mode == TSHUT_MODE_OTP)
61334 @@ -1449,6 +1908,7 @@ static struct platform_driver rockchip_thermal_driver = {
61342 diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
61344 --- a/drivers/thermal/thermal_core.c
61346 @@ -542,6 +542,7 @@ int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
61354 diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
61356 --- a/drivers/thermal/thermal_core.h
61358 @@ -179,6 +179,4 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz)
61362 -int thermal_zone_device_is_enabled(struct thermal_zone_device *tz);
61363 -
61365 diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
61367 --- a/drivers/tty/serial/8250/8250.h
61369 @@ -48,6 +48,9 @@ struct uart_8250_dma {
61379 @@ -136,6 +139,9 @@ static inline bool serial8250_set_THRI(struct uart_8250_port *up)
61380 if (up->ier & UART_IER_THRI)
61382 up->ier |= UART_IER_THRI;
61384 + up->ier |= UART_IER_PTIME;
61386 serial_out(up, UART_IER, up->ier);
61389 @@ -305,6 +311,9 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt)
61399 @@ -317,6 +326,12 @@ static inline int serial8250_rx_dma(struct uart_8250_port *p)
61401 return -1;
61406 + return -1;
61412 diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
61414 --- a/drivers/tty/serial/8250/8250_core.c
61416 @@ -558,6 +558,7 @@ static void __init serial8250_isa_init_ports(void)
61424 @@ -574,6 +575,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
61426 uart_add_one_port(drv, &up->port);
61432 @@ -1019,7 +1021,9 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
61433 uart->rs485_start_tx = up->rs485_start_tx;
61434 uart->rs485_stop_tx = up->rs485_stop_tx;
61435 uart->dma = up->dma;
61436 -
61438 + uart->port.line = up->port.line;
61441 if (uart->port.fifosize && !uart->tx_loadsz)
61442 uart->tx_loadsz = uart->port.fifosize;
61443 @@ -1243,7 +1247,11 @@ static void __exit serial8250_exit(void)
61455 diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
61457 --- a/drivers/tty/serial/8250/8250_dma.c
61459 @@ -11,6 +11,12 @@
61472 @@ -40,6 +46,39 @@ static void __dma_tx_complete(void *param)
61473 spin_unlock_irqrestore(&p->port.lock, flags);
61481 + struct uart_8250_dma *dma = p->dma;
61482 + struct tty_port *tty_port = &p->port.state->port;
61486 + dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
61487 + cur_index = dma->rx_size - state.residue;
61489 + if (cur_index == dma->rx_index)
61491 + else if (cur_index > dma->rx_index)
61492 + count = cur_index - dma->rx_index;
61494 + count = dma->rx_size - dma->rx_index;
61496 + tty_insert_flip_string(tty_port, dma->rx_buf + dma->rx_index, count);
61498 + if (cur_index < dma->rx_index) {
61499 + tty_insert_flip_string(tty_port, dma->rx_buf, cur_index);
61503 + p->port.icount.rx += count;
61504 + dma->rx_index = cur_index;
61512 @@ -59,6 +98,8 @@ static void __dma_rx_complete(void *param)
61520 struct uart_8250_dma *dma = p->dma;
61521 @@ -76,7 +117,12 @@ int serial8250_tx_dma(struct uart_8250_port *p)
61524 dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
61525 -
61527 + if (dma->tx_size < MAX_TX_BYTES) {
61528 + ret = -EBUSY;
61532 desc = dmaengine_prep_slave_single(dma->txchan,
61533 dma->tx_addr + xmit->tail,
61534 dma->tx_size, DMA_MEM_TO_DEV,
61535 @@ -106,6 +152,64 @@ int serial8250_tx_dma(struct uart_8250_port *p)
61545 + struct uart_port *port = &p->port;
61546 + struct tty_port *tty_port = &p->port.state->port;
61548 + struct uart_8250_dma *dma = p->dma;
61554 + dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
61555 + cur_index = dma->rx_size - state.residue;
61556 + } while (cur_index % dma->rxconf.src_maxburst);
61565 + p->port.icount.rx += i;
61569 + serial_port_out(port, UART_FCR, p->fcr);
61575 + struct uart_8250_dma *dma = p->dma;
61578 + desc = dmaengine_prep_dma_cyclic(dma->rxchan, dma->rx_addr,
61579 + dma->rx_size, dma->rx_size,
61583 + return -EBUSY;
61585 + dma->rx_running = 1;
61586 + desc->callback = NULL;
61587 + desc->callback_param = NULL;
61589 + dma->rx_cookie = dmaengine_submit(desc);
61590 + dma_async_issue_pending(dma->rxchan);
61591 + dma->rx_index = 0;
61599 struct uart_8250_dma *dma = p->dma;
61600 @@ -131,6 +235,8 @@ int serial8250_rx_dma(struct uart_8250_port *p)
61608 struct uart_8250_dma *dma = p->dma;
61609 @@ -158,11 +264,19 @@ int serial8250_request_dma(struct uart_8250_port *p)
61610 dma->rxconf.direction = DMA_DEV_TO_MEM;
61611 dma->rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
61612 dma->rxconf.src_addr = rx_dma_addr + UART_RX;
61614 + if ((p->port.fifosize / 4) < 16)
61615 + dma->rxconf.src_maxburst = p->port.fifosize / 4;
61617 + dma->rxconf.src_maxburst = 16;
61620 dma->txconf.direction = DMA_MEM_TO_DEV;
61621 dma->txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
61622 dma->txconf.dst_addr = tx_dma_addr + UART_TX;
61623 -
61625 + dma->txconf.dst_maxburst = 16;
61630 @@ -185,54 +299,52 @@ int serial8250_request_dma(struct uart_8250_port *p)
61632 dmaengine_slave_config(dma->rxchan, &dma->rxconf);
61634 - /* Get a channel for TX */
61635 - dma->txchan = dma_request_slave_channel_compat(mask,
61636 - dma->fn, dma->tx_param,
61637 - p->port.dev, "tx");
61638 - if (!dma->txchan) {
61639 - ret = -ENODEV;
61640 - goto release_rx;
61641 - }
61642 -
61643 - /* 8250 tx dma requires dmaengine driver to support terminate */
61644 - ret = dma_get_slave_caps(dma->txchan, &caps);
61645 - if (ret)
61646 - goto err;
61647 - if (!caps.cmd_terminate) {
61648 - ret = -EINVAL;
61649 - goto err;
61650 - }
61651 -
61652 - dmaengine_slave_config(dma->txchan, &dma->txconf);
61653 -
61656 + if (!dma->rx_size)
61657 + dma->rx_size = PAGE_SIZE * 2;
61659 if (!dma->rx_size)
61660 dma->rx_size = PAGE_SIZE;
61663 dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size,
61664 &dma->rx_addr, GFP_KERNEL);
61665 if (!dma->rx_buf) {
61666 ret = -ENOMEM;
61667 - goto err;
61671 - /* TX buffer */
61672 - dma->tx_addr = dma_map_single(dma->txchan->device->dev,
61673 - p->port.state->xmit.buf,
61674 - UART_XMIT_SIZE,
61675 - DMA_TO_DEVICE);
61676 - if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
61677 - dma_free_coherent(dma->rxchan->device->dev, dma->rx_size,
61678 - dma->rx_buf, dma->rx_addr);
61679 - ret = -ENOMEM;
61680 - goto err;
61681 + /* Get a channel for TX */
61682 + dma->txchan = dma_request_slave_channel_compat(mask,
61683 + dma->fn, dma->tx_param,
61684 + p->port.dev, "tx");
61685 + if (dma->txchan) {
61686 + dmaengine_slave_config(dma->txchan, &dma->txconf);
61688 + /* TX buffer */
61689 + dma->tx_addr = dma_map_single(dma->txchan->device->dev,
61690 + p->port.state->xmit.buf,
61693 + if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
61694 + dma_free_coherent(dma->rxchan->device->dev,
61695 + dma->rx_size, dma->rx_buf,
61696 + dma->rx_addr);
61697 + dma_release_channel(dma->txchan);
61698 + dma->txchan = NULL;
61701 + dev_info_ratelimited(p->port.dev, "got rx and tx dma channels\n");
61703 + dev_info_ratelimited(p->port.dev, "got rx dma channels only\n");
61706 - dev_dbg_ratelimited(p->port.dev, "got both dma channels\n");
61707 -
61713 -err:
61714 - dma_release_channel(dma->txchan);
61716 dma_release_channel(dma->rxchan);
61718 @@ -252,15 +364,18 @@ void serial8250_release_dma(struct uart_8250_port *p)
61719 dma->rx_addr);
61720 dma_release_channel(dma->rxchan);
61721 dma->rxchan = NULL;
61722 -
61724 + dma->rx_running = 0;
61726 /* Release TX resources */
61727 - dmaengine_terminate_sync(dma->txchan);
61728 - dma_unmap_single(dma->txchan->device->dev, dma->tx_addr,
61729 - UART_XMIT_SIZE, DMA_TO_DEVICE);
61730 - dma_release_channel(dma->txchan);
61731 - dma->txchan = NULL;
61732 - dma->tx_running = 0;
61733 -
61734 + if (dma->txchan) {
61735 + dmaengine_terminate_all(dma->txchan);
61736 + dma_unmap_single(dma->txchan->device->dev, dma->tx_addr,
61738 + dma_release_channel(dma->txchan);
61739 + dma->txchan = NULL;
61740 + dma->tx_running = 0;
61742 dev_dbg_ratelimited(p->port.dev, "dma channels released\n");
61745 diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
61747 --- a/drivers/tty/serial/8250/8250_dw.c
61749 @@ -33,6 +33,7 @@
61757 @@ -49,6 +50,11 @@ struct dw8250_data {
61769 @@ -235,10 +241,9 @@ static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset)
61773 - struct uart_8250_port *up = up_to_u8250p(p);
61774 struct dw8250_data *d = to_dw8250_data(p->private_data);
61775 unsigned int iir = p->serial_in(p, UART_IIR);
61776 - unsigned int status;
61781 @@ -247,15 +252,13 @@ static int dw8250_handle_irq(struct uart_port *p)
61785 - *
61786 - * This problem has only been observed so far when not in DMA mode
61787 - * so we limit the workaround only to non-DMA mode.
61789 - if (!up->dma && ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)) {
61791 spin_lock_irqsave(&p->lock, flags);
61792 + usr = p->serial_in(p, d->usr_reg);
61793 status = p->serial_in(p, UART_LSR);
61794 -
61795 - if (!(status & (UART_LSR_DR | UART_LSR_BI)))
61796 + rfl = p->serial_in(p, DW_UART_RFL);
61798 (void) p->serial_in(p, UART_RX);
61800 spin_unlock_irqrestore(&p->lock, flags);
61801 @@ -329,12 +332,49 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
61808 struct dw8250_data *d = to_dw8250_data(p->private_data);
61816 clk_disable_unprepare(d->clk);
61827 + ret = clk_set_rate(d->clk, rate);
61828 + rate_temp = clk_get_rate(d->clk);
61833 + * the baud rate error must be under -+2%
61835 + if ((rate_temp < rate) && ((rate - rate_temp) > diff)) {
61836 + ret = clk_set_rate(d->clk, rate + diff);
61837 + rate_temp = clk_get_rate(d->clk);
61838 + if ((rate_temp < rate) && ((rate - rate_temp) > diff))
61839 + dev_info(p->dev, "set rate:%ld, but get rate:%d\n",
61841 + else if ((rate < rate_temp) && ((rate_temp - rate) > diff))
61842 + dev_info(p->dev, "set rate:%ld, but get rate:%d\n",
61846 + p->uartclk = rate;
61848 rate = clk_round_rate(d->clk, newrate);
61851 @@ -348,6 +388,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
61853 swap(p->uartclk, rate);
61856 clk_prepare_enable(d->clk);
61858 p->status &= ~UPSTAT_AUTOCTS;
61859 @@ -480,6 +521,9 @@ static int dw8250_probe(struct platform_device *pdev)
61860 data->data.dma.fn = dw8250_fallback_dma_filter;
61861 data->usr_reg = DW_UART_USR;
61862 p->private_data = &data->data;
61864 + data->irq = irq;
61867 data->uart_16550_compatible = device_property_read_bool(dev,
61868 "snps,uart-16550-compatible");
61869 @@ -519,6 +563,13 @@ static int dw8250_probe(struct platform_device *pdev)
61870 data->msr_mask_off |= UART_MSR_TERI;
61874 + if (device_property_read_bool(p->dev, "wakeup-source"))
61875 + data->enable_wakeup = 1;
61877 + data->enable_wakeup = 0;
61881 device_property_read_u32(dev, "clock-frequency", &p->uartclk);
61883 @@ -599,7 +650,10 @@ static int dw8250_probe(struct platform_device *pdev)
61885 queue_work(system_unbound_wq, &data->clk_work);
61887 -
61889 + if (data->enable_wakeup)
61890 + device_init_wakeup(&pdev->dev, true);
61895 @@ -642,6 +696,10 @@ static int dw8250_remove(struct platform_device *pdev)
61900 + if (data->enable_wakeup)
61901 + device_init_wakeup(&pdev->dev, false);
61906 @@ -652,6 +710,13 @@ static int dw8250_suspend(struct device *dev)
61909 serial8250_suspend_port(data->data.line);
61912 + if (!enable_irq_wake(data->irq))
61913 + data->irq_wake = 1;
61920 @@ -661,6 +726,15 @@ static int dw8250_resume(struct device *dev)
61923 serial8250_resume_port(data->data.line);
61926 + if (data->irq_wake) {
61927 + disable_irq_wake(data->irq);
61928 + data->irq_wake = 0;
61936 diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
61938 --- a/drivers/tty/serial/8250/8250_dwlib.c
61940 @@ -106,6 +106,15 @@ void dw8250_setup_port(struct uart_port *p)
61956 @@ -114,6 +123,9 @@ void dw8250_setup_port(struct uart_port *p)
61957 p->type = PORT_16550A;
61958 p->flags |= UPF_FIXED_TYPE;
61959 p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
61961 + up->tx_loadsz = p->fifosize * 3 / 4;
61963 up->capabilities = UART_CAP_FIFO;
61966 diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
61968 --- a/drivers/tty/serial/8250/8250_port.c
61970 @@ -1567,8 +1567,13 @@ static inline void __start_tx(struct uart_port *port)
61975 + if (up->dma && up->dma->txchan && !up->dma->tx_dma(up))
61978 if (up->dma && !up->dma->tx_dma(up))
61983 if (up->bugs & UART_BUG_TXEN) {
61984 @@ -1888,6 +1893,12 @@ EXPORT_SYMBOL_GPL(serial8250_modem_status);
61992 + return up->dma->rx_dma(up);
61997 @@ -1896,6 +1907,7 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
62000 return up->dma->rx_dma(up);
62005 @@ -1906,7 +1918,9 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
62015 @@ -1915,6 +1929,17 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
62021 + int dma_err = -1;
62023 + if (up->dma && up->dma->rxchan)
62026 + if (!up->dma || dma_err)
62033 @@ -1932,11 +1957,34 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
62034 if (!up->dma || handle_rx_dma(up, iir))
62039 - if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE) &&
62040 - (up->ier & UART_IER_THRI))
62042 + if ((!up->dma || (up->dma && (!up->dma->txchan || up->dma->tx_err))) &&
62046 + if ((!up->dma || (up->dma && up->dma->tx_err)) &&
62055 + pr_err("%s: Overrun error!\n", port->name);
62057 + pr_err("%s: Parity error!\n", port->name);
62059 + pr_err("%s: Frame error!\n", port->name);
62061 + pr_err("%s: Break interrupt!\n", port->name);
62064 + port->name);
62070 @@ -2405,7 +2453,11 @@ int serial8250_do_startup(struct uart_port *port)
62080 dev_warn_ratelimited(port->dev, "%s\n", msg);
62081 up->dma = NULL;
62082 @@ -2599,6 +2651,10 @@ void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
62093 @@ -2618,6 +2674,17 @@ void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
62094 serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB);
62099 + dev_warn_ratelimited(port->dev, "ttyS%d set divisor fail, quot:%d != dll,dlh:%d\n",
62102 + if (port->type != PORT_16750)
62103 + serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */
62106 + serial_port_out(port, UART_MCR, up->mcr);
62111 @@ -2797,6 +2864,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
62112 if ((termios->c_cflag & CREAD) == 0)
62113 port->ignore_status_mask |= UART_LSR_DR;
62119 @@ -2810,6 +2878,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
62120 up->ier |= UART_IER_RTOIE;
62122 serial_port_out(port, UART_IER, up->ier);
62125 if (up->capabilities & UART_CAP_EFR) {
62127 @@ -2828,16 +2897,25 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
62139 + up->fcr = UART_FCR_ENABLE_FIFO | UART_FCR_T_TRIG_10 | UART_FCR_R_TRIG_10;
62142 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
62145 - if (port->type == PORT_16750)
62146 + if (port->type == PORT_16750) {
62147 serial_port_out(port, UART_FCR, up->fcr);
62148 + serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */
62151 - serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */
62152 if (port->type != PORT_16750) {
62154 if (up->fcr & UART_FCR_ENABLE_FIFO)
62155 @@ -2845,6 +2923,23 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
62156 serial_port_out(port, UART_FCR, up->fcr); /* set fcr */
62158 serial8250_set_mctrl(port, port->mctrl);
62164 + up->ier &= ~UART_IER_MSI;
62165 + if (!(up->bugs & UART_BUG_NOMSR) &&
62166 + UART_ENABLE_MS(&up->port, termios->c_cflag))
62167 + up->ier |= UART_IER_MSI;
62168 + if (up->capabilities & UART_CAP_UUE)
62169 + up->ier |= UART_IER_UUE;
62170 + if (up->capabilities & UART_CAP_RTOIE)
62171 + up->ier |= UART_IER_RTOIE;
62173 + serial_port_out(port, UART_IER, up->ier);
62176 spin_unlock_irqrestore(&port->lock, flags);
62179 diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
62181 --- a/drivers/tty/vt/keyboard.c
62183 @@ -488,6 +488,7 @@ static void fn_hold(struct vc_data *vc)
62185 struct tty_struct *tty = vc->port.tty;
62191 diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
62193 --- a/drivers/usb/core/hub.c
62195 @@ -1826,7 +1826,8 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *…
62198 if (hdev->parent) { /* normal device */
62199 - usb_enable_autosuspend(hdev);
62200 + if (!(hdev->parent->quirks & USB_QUIRK_AUTO_SUSPEND))
62203 const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
62205 diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
62207 --- a/drivers/usb/core/quirks.c
62209 @@ -322,6 +322,10 @@ static const struct usb_device_id usb_quirk_list[] = {
62220 @@ -411,6 +415,10 @@ static const struct usb_device_id usb_quirk_list[] = {
62231 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
62233 --- a/drivers/usb/gadget/Kconfig
62235 @@ -216,6 +216,12 @@ config USB_F_PRINTER
62245 # this first set of drivers all depend on bulk-capable hardware.
62248 @@ -230,6 +236,14 @@ config USB_CONFIGFS
62263 @@ -371,6 +385,23 @@ config USB_CONFIGFS_F_FS
62287 diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
62289 --- a/drivers/usb/gadget/composite.c
62291 @@ -13,6 +13,7 @@
62299 @@ -734,47 +735,77 @@ static int bos_desc(struct usb_composite_dev *cdev)
62301 if (gadget_is_superspeed_plus(cdev->gadget)) {
62307 - ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
62308 - bos->bNumDeviceCaps++;
62309 + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x2)
62313 - * Report typical values.
62314 + * Paired RX and TX sublink speed attributes share
62317 + ssic = (ssac + 1) / 2 - 1;
62319 + ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
62320 + bos->bNumDeviceCaps++;
62322 - le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(1));
62323 - ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1);
62324 + le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(ssac));
62325 + ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(ssac);
62326 ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
62327 ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE;
62328 ssp_cap->bReserved = 0;
62329 ssp_cap->wReserved = 0;
62331 - /* SSAC = 1 (2 attributes) */
62332 - ssp_cap->bmAttributes = cpu_to_le32(1);
62333 + ssp_cap->bmAttributes =
62337 - /* Min RX/TX Lane Count = 1 */
62338 ssp_cap->wFunctionalitySupport =
62339 - cpu_to_le16((1 << 8) | (1 << 12));
62345 - * bmSublinkSpeedAttr[0]:
62346 - * ST = Symmetric, RX
62347 - * LSE = 3 (Gbps)
62348 - * LP = 1 (SuperSpeedPlus)
62349 - * LSM = 10 (10 Gbps)
62350 - */
62351 - ssp_cap->bmSublinkSpeedAttr[0] =
62352 - cpu_to_le32((3 << 4) | (1 << 14) | (0xa << 16));
62353 - /*
62354 - * bmSublinkSpeedAttr[1] =
62355 - * ST = Symmetric, TX
62356 - * LSE = 3 (Gbps)
62357 - * LP = 1 (SuperSpeedPlus)
62358 - * LSM = 10 (10 Gbps)
62361 + * - SSID 0 for symmetric RX/TX sublink speed of 10 Gbps.
62364 + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps.
62367 + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps.
62368 + * - SSID 1 for symmetric RX/TX sublink speed of 10 Gbps.
62370 - ssp_cap->bmSublinkSpeedAttr[1] =
62371 - cpu_to_le32((3 << 4) | (1 << 14) |
62372 - (0xa << 16) | (1 << 7));
62380 + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x1 ||
62381 + cdev->gadget->max_ssp_rate == USB_SSP_GEN_UNKNOWN)
62391 + ssp_cap->bmSublinkSpeedAttr[i] =
62402 return le16_to_cpu(bos->wTotalLength);
62403 @@ -2061,7 +2092,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
62407 -void composite_disconnect(struct usb_gadget *gadget)
62412 @@ -2078,6 +2109,23 @@ void composite_disconnect(struct usb_gadget *gadget)
62413 spin_unlock_irqrestore(&cdev->lock, flags);
62433 /*-------------------------------------------------------------------------*/
62436 @@ -2398,7 +2446,7 @@ static const struct usb_gadget_driver composite_driver_template = {
62440 - .reset = composite_disconnect,
62445 diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
62447 --- a/drivers/usb/gadget/configfs.c
62449 @@ -10,6 +10,32 @@
62474 + return ERR_PTR(-EINVAL);
62482 @@ -51,6 +77,12 @@ struct gadget_info {
62495 @@ -272,7 +304,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
62497 mutex_lock(&gi->lock);
62499 - if (!strlen(name)) {
62504 @@ -1270,6 +1302,9 @@ static void purge_configs_funcs(struct gadget_info *gi)
62505 f->name, f);
62506 f->unbind(c, f);
62509 + if (f->bind_deactivated)
62512 c->next_interface_id = 0;
62513 memset(c->interface, 0, sizeof(c->interface));
62514 @@ -1422,6 +1457,57 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
62522 + struct usb_composite_dev *cdev = &gi->cdev;
62526 + /* 0-connected 1-configured 2-disconnected*/
62531 + spin_lock_irqsave(&cdev->lock, flags);
62532 + if (cdev->config)
62535 + if (gi->connected != gi->sw_connected) {
62536 + if (gi->connected)
62540 + gi->sw_connected = gi->connected;
62542 + spin_unlock_irqrestore(&cdev->lock, flags);
62545 + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected);
62551 + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured);
62557 + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected);
62564 + gi->connected, gi->sw_connected, cdev->config);
62572 @@ -1447,6 +1533,51 @@ static void configfs_composite_unbind(struct usb_gadget *gadget)
62573 spin_unlock_irqrestore(&gi->spinlock, flags);
62583 + int value = -EOPNOTSUPP;
62586 + spin_lock_irqsave(&cdev->lock, flags);
62587 + if (c->bRequest == USB_REQ_GET_DESCRIPTOR &&
62588 + (c->wValue >> 8) == USB_DT_CONFIG && !gi->connected) {
62589 + gi->connected = 1;
62590 + schedule_work(&gi->work);
62592 + spin_unlock_irqrestore(&cdev->lock, flags);
62593 + list_for_each_entry(fi, &gi->available_func, cfs_list) {
62594 + if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
62595 + value = fi->f->setup(fi->f, c);
62609 + spin_lock_irqsave(&cdev->lock, flags);
62610 + if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
62611 + cdev->config) {
62612 + schedule_work(&gi->work);
62614 + spin_unlock_irqrestore(&cdev->lock, flags);
62624 @@ -1472,6 +1603,8 @@ static int configfs_composite_setup(struct usb_gadget *gadget,
62633 @@ -1482,6 +1615,14 @@ static void configfs_composite_disconnect(struct usb_gadget *gadget)
62646 spin_lock_irqsave(&gi->spinlock, flags);
62648 @@ -1490,10 +1631,36 @@ static void configfs_composite_disconnect(struct usb_gadget *gadget)
62653 + gi->connected = 0;
62654 + schedule_work(&gi->work);
62657 spin_unlock_irqrestore(&gi->spinlock, flags);
62671 + spin_lock_irqsave(&gi->spinlock, flags);
62673 + if (!cdev || gi->unbind) {
62674 + spin_unlock_irqrestore(&gi->spinlock, flags);
62679 + spin_unlock_irqrestore(&gi->spinlock, flags);
62685 @@ -1542,10 +1709,13 @@ static const struct usb_gadget_driver configfs_driver_template = {
62693 - .reset = configfs_composite_disconnect,
62697 -
62701 @@ -1557,6 +1727,91 @@ static const struct usb_gadget_driver configfs_driver_template = {
62717 + cdev = &dev->cdev;
62722 + spin_lock_irqsave(&cdev->lock, flags);
62723 + if (cdev->config)
62725 + else if (dev->connected)
62727 + spin_unlock_irqrestore(&cdev->lock, flags);
62744 + INIT_WORK(&gi->work, android_work);
62745 + gi->dev = device_create(android_class, NULL,
62747 + if (IS_ERR(gi->dev))
62748 + return PTR_ERR(gi->dev);
62750 + dev_set_drvdata(gi->dev, gi);
62752 + android_device = gi->dev;
62758 + err = device_create_file(gi->dev, attr);
62760 + device_destroy(gi->dev->class,
62761 + gi->dev->devt);
62776 + device_remove_file(gi->dev, attr);
62777 + device_destroy(gi->dev->class, gi->dev->devt);
62793 @@ -1609,7 +1864,11 @@ static struct config_group *gadgets_make(
62794 if (!gi->composite.gadget_driver.function)
62800 return &gi->group;
62804 return ERR_PTR(-ENOMEM);
62805 @@ -1617,7 +1876,11 @@ static struct config_group *gadgets_make(
62817 @@ -1657,6 +1920,13 @@ static int __init gadget_cfs_init(void)
62831 @@ -1664,5 +1934,10 @@ module_init(gadget_cfs_init);
62842 diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
62844 --- a/drivers/usb/gadget/epautoconf.c
62846 @@ -67,6 +67,9 @@ struct usb_ep *usb_ep_autoconfig_ss(
62851 + u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
62854 if (gadget->ops->match_ep) {
62855 ep = gadget->ops->match_ep(gadget, desc, ep_comp);
62856 @@ -110,6 +113,27 @@ struct usb_ep *usb_ep_autoconfig_ss(
62857 ep->desc = NULL;
62858 ep->comp_desc = NULL;
62859 ep->claimed = true;
62861 + ep->transfer_type = type;
62866 + ep->mult = (ep_comp->bmAttributes & 0x3) + 1;
62870 + ep->maxburst = ep_comp->bMaxBurst + 1;
62878 + ep->mult = usb_endpoint_maxp_mult(desc);
62884 diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
62886 --- a/drivers/usb/gadget/function/f_fs.c
62888 @@ -71,7 +71,7 @@ struct ffs_function {
62892 - u8 eps_revmap[16];
62897 @@ -2799,7 +2799,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
62901 - int idx;
62906 @@ -2872,8 +2872,9 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
62908 ffs_ep->ep = ep;
62909 ffs_ep->req = req;
62910 - func->eps_revmap[ds->bEndpointAddress &
62911 - USB_ENDPOINT_NUMBER_MASK] = idx + 1;
62912 + ep_num = ((ds->bEndpointAddress & USB_ENDPOINT_DIR_MASK) >> 3) |
62913 + (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
62914 + func->eps_revmap[ep_num] = idx + 1;
62918 @@ -3408,7 +3409,10 @@ static void ffs_func_resume(struct usb_function *f)
62922 - num = func->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK];
62926 + num = func->eps_revmap[ep_num];
62927 return num ? num : -EDOM;
62930 diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
62932 --- a/drivers/usb/gadget/function/f_uvc.c
62934 @@ -124,6 +124,18 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt0 = {
62953 @@ -147,6 +159,16 @@ static struct usb_endpoint_descriptor uvc_fs_streaming_ep = {
62970 @@ -158,6 +180,16 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = {
62987 @@ -170,6 +202,17 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep = {
63005 @@ -178,18 +221,36 @@ static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = {
63042 @@ -197,6 +258,12 @@ static const struct usb_descriptor_header * const uvc_ss_streaming[] = {
63052 /* --------------------------------------------------------------------------
63055 @@ -208,6 +275,10 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req)
63061 + uvc->event_setup_out, req->actual);
63063 if (uvc->event_setup_out) {
63064 uvc->event_setup_out = 0;
63066 @@ -226,6 +297,11 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
63072 + ctrl->bRequestType, ctrl->bRequest, le16_to_cpu(ctrl->wValue),
63073 + le16_to_cpu(ctrl->wIndex), le16_to_cpu(ctrl->wLength));
63075 if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) {
63077 return -EINVAL;
63078 @@ -260,15 +336,27 @@ static int
63086 + opts = fi_to_f_uvc_opts(f->fi);
63088 if (interface == uvc->control_intf)
63090 else if (interface != uvc->streaming_intf)
63091 return -EINVAL;
63092 - else
63093 + else if (!opts->streaming_bulk)
63094 return uvc->video.ep->enabled ? 1 : 0;
63098 + * ISOC endpoints as there are different alt-settings for
63099 + * zero-bandwidth and full-bandwidth cases, but the same
63101 + * alt-setting.
63107 @@ -278,10 +366,13 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
63108 struct usb_composite_dev *cdev = f->config->cdev;
63116 + opts = fi_to_f_uvc_opts(f->fi);
63118 if (interface == uvc->control_intf) {
63120 return -EINVAL;
63121 @@ -295,6 +386,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
63123 usb_ep_enable(uvc->control_ep);
63125 + if (uvc->event_suspend) {
63128 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63129 + uvc->event_suspend = 0;
63133 if (uvc->state == UVC_STATE_DISCONNECTED) {
63136 @@ -310,49 +409,94 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
63137 if (interface != uvc->streaming_intf)
63138 return -EINVAL;
63140 - /* TODO
63141 - if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep))
63142 - return alt ? -EINVAL : 0;
63143 - */
63144 + if (!opts->streaming_bulk) {
63147 + if (uvc->state != UVC_STATE_STREAMING)
63150 + if (uvc->video.ep)
63151 + usb_ep_disable(uvc->video.ep);
63155 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63157 - switch (alt) {
63158 - case 0:
63159 - if (uvc->state != UVC_STATE_STREAMING)
63160 + uvc->state = UVC_STATE_CONNECTED;
63163 - if (uvc->video.ep)
63164 - usb_ep_disable(uvc->video.ep);
63166 + if (uvc->state != UVC_STATE_CONNECTED)
63169 - memset(&v4l2_event, 0, sizeof(v4l2_event));
63170 - v4l2_event.type = UVC_EVENT_STREAMOFF;
63171 - v4l2_event_queue(&uvc->vdev, &v4l2_event);
63172 + if (!uvc->video.ep)
63173 + return -EINVAL;
63175 - uvc->state = UVC_STATE_CONNECTED;
63176 - return 0;
63178 + usb_ep_disable(uvc->video.ep);
63180 - case 1:
63181 - if (uvc->state != UVC_STATE_CONNECTED)
63182 - return 0;
63183 + ret = config_ep_by_speed(f->config->cdev->gadget,
63184 + &uvc->func, uvc->video.ep);
63187 + usb_ep_enable(uvc->video.ep);
63191 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63194 - if (!uvc->video.ep)
63196 return -EINVAL;
63199 + switch (uvc->state) {
63201 + if (uvc->video.ep &&
63202 + !uvc->video.ep->enabled) {
63205 + * but don't change the 'uvc->state'.
63207 + ret = config_ep_by_speed(cdev->gadget,
63208 + &uvc->func,
63209 + uvc->video.ep);
63212 + ret = usb_ep_enable(uvc->video.ep);
63218 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63220 + uvc->state = UVC_STATE_STREAMING;
63224 - uvcg_info(f, "reset UVC\n");
63225 - usb_ep_disable(uvc->video.ep);
63232 - ret = config_ep_by_speed(f->config->cdev->gadget,
63233 - &(uvc->func), uvc->video.ep);
63234 - if (ret)
63235 - return ret;
63236 - usb_ep_enable(uvc->video.ep);
63237 + if (uvc->video.ep &&
63238 + uvc->video.ep->enabled) {
63239 + ret = usb_ep_disable(uvc->video.ep);
63244 - memset(&v4l2_event, 0, sizeof(v4l2_event));
63245 - v4l2_event.type = UVC_EVENT_STREAMON;
63246 - v4l2_event_queue(&uvc->vdev, &v4l2_event);
63247 - return USB_GADGET_DELAYED_STATUS;
63250 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63251 + uvc->state = UVC_STATE_CONNECTED;
63254 - default:
63255 - return -EINVAL;
63257 + return -EINVAL;
63262 @@ -374,6 +518,30 @@ uvc_function_disable(struct usb_function *f)
63263 usb_ep_disable(uvc->control_ep);
63273 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63274 + uvc->event_suspend = 1;
63285 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63286 + uvc->event_suspend = 0;
63290 /* --------------------------------------------------------------------------
63293 @@ -467,32 +635,45 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
63307 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63311 uvc_control_desc = uvc->desc.ss_control;
63312 uvc_streaming_cls = uvc->desc.ss_streaming;
63313 - uvc_streaming_std = uvc_ss_streaming;
63314 + if (!opts->streaming_bulk)
63321 uvc_control_desc = uvc->desc.fs_control;
63322 uvc_streaming_cls = uvc->desc.hs_streaming;
63323 - uvc_streaming_std = uvc_hs_streaming;
63324 + if (!opts->streaming_bulk)
63332 uvc_control_desc = uvc->desc.fs_control;
63333 uvc_streaming_cls = uvc->desc.fs_streaming;
63334 - uvc_streaming_std = uvc_fs_streaming;
63335 + if (!opts->streaming_bulk)
63342 @@ -512,12 +693,17 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
63346 + if (!opts->streaming_bulk)
63356 - + uvc_streaming_intf_alt0.bLength;
63357 + + streaming_intf_alt0->bLength;
63361 @@ -567,7 +753,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
63365 - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0);
63370 @@ -592,15 +778,24 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63373 int ret = -EINVAL;
63378 opts = fi_to_f_uvc_opts(f->fi);
63381 - opts->streaming_interval = clamp(opts->streaming_interval, 1U, 16U);
63382 - opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
63383 - opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
63384 + if (!opts->streaming_bulk) {
63385 + opts->streaming_interval = clamp(opts->streaming_interval,
63387 + opts->streaming_maxpacket = clamp(opts->streaming_maxpacket,
63389 + opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
63391 + opts->streaming_maxpacket = clamp(opts->streaming_maxpacket,
63393 + opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
63397 if (opts->streaming_maxburst &&
63398 @@ -627,26 +822,46 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63399 max_packet_size = opts->streaming_maxpacket / 3;
63402 - uvc_fs_streaming_ep.wMaxPacketSize =
63403 - cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
63404 - uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
63405 -
63406 - uvc_hs_streaming_ep.wMaxPacketSize =
63407 - cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11));
63408 -
63409 - /* A high-bandwidth endpoint must specify a bInterval value of 1 */
63410 - if (max_packet_mult > 1)
63411 - uvc_hs_streaming_ep.bInterval = 1;
63412 - else
63413 - uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
63414 -
63415 - uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size);
63416 - uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
63417 - uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
63418 - uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
63419 - uvc_ss_streaming_comp.wBytesPerInterval =
63420 - cpu_to_le16(max_packet_size * max_packet_mult *
63421 - (opts->streaming_maxburst + 1));
63422 + if (!opts->streaming_bulk) {
63424 + cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
63425 + uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
63429 + ((max_packet_mult - 1) << 11));
63431 + /* A high-bandwidth endpoint must specify a bInterval value of 1 */
63435 + uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
63439 + uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
63440 + uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
63441 + uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
63444 + (opts->streaming_maxburst + 1));
63447 + cpu_to_le16(min(opts->streaming_maxpacket, 64U));
63450 + cpu_to_le16(min(opts->streaming_maxpacket, 512U));
63454 + uvc_ss_bulk_streaming_comp.bMaxBurst = opts->streaming_maxburst;
63456 + * As per USB 3.1 spec "Table 9-26. SuperSpeed Endpoint
63464 ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
63465 @@ -656,23 +871,57 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63467 uvc->control_ep = ep;
63469 - if (gadget_is_superspeed(c->cdev->gadget))
63470 - ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep,
63471 - &uvc_ss_streaming_comp);
63472 - else if (gadget_is_dualspeed(cdev->gadget))
63473 - ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep);
63474 - else
63475 - ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep);
63476 + if (gadget_is_superspeed(c->cdev->gadget)) {
63477 + if (!opts->streaming_bulk)
63478 + ep = usb_ep_autoconfig_ss(cdev->gadget,
63482 + ep = usb_ep_autoconfig_ss(cdev->gadget,
63485 + } else if (gadget_is_dualspeed(cdev->gadget)) {
63486 + if (!opts->streaming_bulk) {
63487 + ep = usb_ep_autoconfig(cdev->gadget,
63490 + ep = usb_ep_autoconfig(cdev->gadget,
63499 + cpu_to_le16(min(opts->streaming_maxpacket,
63503 + if (!opts->streaming_bulk)
63504 + ep = usb_ep_autoconfig(cdev->gadget,
63507 + ep = usb_ep_autoconfig(cdev->gadget,
63515 uvc->video.ep = ep;
63516 + address = uvc->video.ep->address;
63518 - uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
63519 - uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
63520 - uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address;
63521 + if (!opts->streaming_bulk) {
63533 @@ -683,8 +932,12 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63537 - uvc_streaming_intf_alt0.iInterface = ret;
63538 - uvc_streaming_intf_alt1.iInterface = ret;
63539 + if (!opts->streaming_bulk) {
63548 @@ -696,8 +949,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63552 - uvc_streaming_intf_alt0.bInterfaceNumber = ret;
63553 - uvc_streaming_intf_alt1.bInterfaceNumber = ret;
63555 + if (!opts->streaming_bulk) {
63562 uvc->streaming_intf = ret;
63563 opts->streaming_interface = ret;
63565 @@ -747,6 +1006,8 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63569 + if (opts->streaming_bulk)
63570 + uvc->video.max_payload_size = uvc->video.imagesize;
63574 @@ -785,6 +1046,7 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63582 @@ -834,6 +1096,34 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63583 od->bSourceID = 2;
63584 od->iTerminal = 0;
63586 + ed = &opts->uvc_extension;
63587 + ed->bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 1);
63588 + ed->bDescriptorType = USB_DT_CS_INTERFACE;
63589 + ed->bDescriptorSubType = UVC_VC_EXTENSION_UNIT;
63590 + ed->bUnitID = 6;
63591 + ed->guidExtensionCode[0] = 0xa2;
63592 + ed->guidExtensionCode[1] = 0x9e;
63593 + ed->guidExtensionCode[2] = 0x76;
63594 + ed->guidExtensionCode[3] = 0x41;
63595 + ed->guidExtensionCode[4] = 0xde;
63596 + ed->guidExtensionCode[5] = 0x04;
63597 + ed->guidExtensionCode[6] = 0x47;
63598 + ed->guidExtensionCode[7] = 0xe3;
63599 + ed->guidExtensionCode[8] = 0x8b;
63600 + ed->guidExtensionCode[9] = 0x2b;
63601 + ed->guidExtensionCode[10] = 0xf4;
63602 + ed->guidExtensionCode[11] = 0x34;
63603 + ed->guidExtensionCode[12] = 0x1a;
63604 + ed->guidExtensionCode[13] = 0xff;
63605 + ed->guidExtensionCode[14] = 0x00;
63606 + ed->guidExtensionCode[15] = 0x3b;
63607 + ed->bNumControls = 3;
63608 + ed->bNrInPins = 1;
63609 + ed->baSourceID[0] = 2;
63610 + ed->bControlSize = 1;
63611 + ed->bmControls[0] = 7;
63612 + ed->iExtension = 0;
63614 md = &opts->uvc_color_matching;
63615 md->bLength = UVC_DT_COLOR_MATCHING_SIZE;
63616 md->bDescriptorType = USB_DT_CS_INTERFACE;
63617 @@ -848,7 +1138,8 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63621 - ctl_cls[4] = NULL; /* NULL-terminate */
63623 + ctl_cls[5] = NULL; /* NULL-terminate */
63624 opts->fs_control =
63627 @@ -858,12 +1149,15 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63631 - ctl_cls[4] = NULL; /* NULL-terminate */
63633 + ctl_cls[5] = NULL; /* NULL-terminate */
63634 opts->ss_control =
63637 opts->streaming_interval = 1;
63638 opts->streaming_maxpacket = 1024;
63639 + opts->uvc_num_request = UVC_NUM_REQUESTS;
63640 + opts->pm_qos_latency = 0;
63644 @@ -948,6 +1242,8 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
63645 uvc->func.disable = uvc_function_disable;
63646 uvc->func.setup = uvc_function_setup;
63647 uvc->func.free_func = uvc_free;
63648 + uvc->func.suspend = uvc_function_suspend;
63649 + uvc->func.resume = uvc_function_resume;
63650 uvc->func.bind_deactivated = true;
63652 return &uvc->func;
63653 diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h
63655 --- a/drivers/usb/gadget/function/u_uvc.h
63657 @@ -18,15 +18,18 @@
63675 * Control descriptors array pointers for full-/high-speed and
63676 @@ -51,6 +54,7 @@ struct f_uvc_opts {
63684 @@ -60,8 +64,8 @@ struct f_uvc_opts {
63688 - struct uvc_descriptor_header *uvc_fs_control_cls[5];
63689 - struct uvc_descriptor_header *uvc_ss_control_cls[5];
63694 * Streaming descriptors for full-speed, high-speed and super-speed.
63695 @@ -81,6 +85,7 @@ struct f_uvc_opts {
63703 diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
63705 --- a/drivers/usb/gadget/function/uvc.h
63707 @@ -14,6 +14,7 @@
63713 #include <media/v4l2-device.h>
63714 #include <media/v4l2-dev.h>
63715 @@ -68,6 +69,7 @@ extern unsigned int uvc_gadget_trace_param;
63721 /* ------------------------------------------------------------------------
63723 @@ -89,8 +91,8 @@ struct uvc_video {
63727 - struct usb_request *req[UVC_NUM_REQUESTS];
63728 - __u8 *req_buffer[UVC_NUM_REQUESTS];
63734 @@ -118,6 +120,8 @@ struct uvc_device {
63743 @@ -138,6 +142,7 @@ struct uvc_device {
63751 diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
63753 --- a/drivers/usb/gadget/function/uvc_queue.c
63755 @@ -124,6 +124,14 @@ int uvcg_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
63756 queue->queue.mem_ops = &vb2_vmalloc_memops;
63757 queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
63765 + queue->queue.allow_zero_bytesused = 1;
63767 ret = vb2_queue_init(&queue->queue);
63770 diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c
63772 --- a/drivers/usb/gadget/function/uvc_v4l2.c
63774 @@ -41,6 +41,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
63775 req->length = min_t(unsigned int, uvc->event_length, data->length);
63776 req->zero = data->length < uvc->event_length;
63778 + uvc_trace(UVC_TRACE_CONTROL, "%s: req len %d\n", __func__, req->length);
63779 memcpy(req->buf, data->data, req->length);
63781 return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL);
63782 @@ -58,6 +59,8 @@ struct uvc_format {
63791 @@ -201,11 +204,21 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
63795 - * Complete the alternate setting selection setup phase now that
63796 - * userspace is ready to provide video frames.
63798 + * for ISOC endpoints as there are different alt-
63799 + * settings for zero-bandwidth and full-bandwidth
63801 + * as they have a single alt-setting.
63803 - uvc_function_setup_continue(uvc);
63804 - uvc->state = UVC_STATE_STREAMING;
63805 + if (!usb_endpoint_xfer_bulk(video->ep->desc)) {
63812 + uvc->state = UVC_STATE_STREAMING;
63817 @@ -389,6 +402,9 @@ const struct v4l2_file_operations uvc_v4l2_fops = {
63827 diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
63829 --- a/drivers/usb/gadget/function/uvc_video.c
63831 @@ -12,12 +12,14 @@
63837 #include <media/v4l2-dev.h>
63844 /* --------------------------------------------------------------------------
63846 @@ -87,6 +89,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
63847 video->fid ^= UVC_STREAM_FID;
63849 video->payload_size = 0;
63850 + req->zero = 1;
63853 if (video->payload_size == video->max_payload_size ||
63854 @@ -135,7 +138,7 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
63858 - if (usb_endpoint_xfer_bulk(video->ep->desc))
63859 + if (video->ep->desc && usb_endpoint_xfer_bulk(video->ep->desc))
63860 usb_ep_set_halt(video->ep);
63863 @@ -176,8 +179,13 @@ static int
63870 - for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
63872 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63874 + for (i = 0; i < opts->uvc_num_request; ++i) {
63875 if (video->req[i]) {
63876 usb_ep_free_request(video->ep, video->req[i]);
63877 video->req[i] = NULL;
63878 @@ -200,14 +208,24 @@ uvc_video_alloc_requests(struct uvc_video *video)
63881 int ret = -ENOMEM;
63886 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63888 BUG_ON(video->req_size);
63890 - req_size = video->ep->maxpacket
63891 - * max_t(unsigned int, video->ep->maxburst, 1)
63892 - * (video->ep->mult);
63893 + if (!usb_endpoint_xfer_bulk(video->ep->desc)) {
63894 + req_size = video->ep->maxpacket
63895 + * max_t(unsigned int, video->ep->maxburst, 1)
63896 + * (video->ep->mult);
63898 + req_size = video->ep->maxpacket
63899 + * max_t(unsigned int, video->ep->maxburst, 1);
63902 - for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
63903 + for (i = 0; i < opts->uvc_num_request; ++i) {
63904 video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
63905 if (video->req_buffer[i] == NULL)
63907 @@ -301,6 +319,8 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
63914 if (video->ep == NULL) {
63915 uvcg_info(&video->uvc->func,
63916 @@ -308,19 +328,25 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
63917 return -ENODEV;
63921 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63924 cancel_work_sync(&video->pump);
63925 uvcg_queue_cancel(&video->queue, 0);
63927 - for (i = 0; i < UVC_NUM_REQUESTS; ++i)
63928 + for (i = 0; i < opts->uvc_num_request; ++i)
63929 if (video->req[i])
63930 usb_ep_dequeue(video->ep, video->req[i]);
63933 uvcg_queue_enable(&video->queue, 0);
63934 + if (cpu_latency_qos_request_active(&uvc->pm_qos))
63935 + cpu_latency_qos_remove_request(&uvc->pm_qos);
63939 + cpu_latency_qos_add_request(&uvc->pm_qos, opts->pm_qos_latency);
63940 if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
63943 diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
63945 --- a/drivers/usb/gadget/udc/core.c
63947 @@ -755,7 +755,7 @@ int usb_gadget_deactivate(struct usb_gadget *gadget)
63951 - if (gadget->deactivated)
63952 + if (!gadget || gadget->deactivated)
63955 if (gadget->connected) {
63956 diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
63958 --- a/drivers/usb/storage/scsiglue.c
63960 @@ -102,6 +102,10 @@ static int slave_configure(struct scsi_device *sdev)
63961 if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) {
63964 + if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == 0x05e3 &&
63965 + le16_to_cpu(us->pusb_dev->descriptor.idProduct) == 0x0749)
63968 if (us->fflags & US_FL_MAX_SECTORS_MIN)
63970 if (queue_max_hw_sectors(sdev->request_queue) > max_sectors)
63971 diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
63973 --- a/drivers/usb/storage/unusual_devs.h
63975 @@ -927,6 +927,12 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451,
63988 diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
63990 --- a/drivers/usb/storage/unusual_uas.h
63992 @@ -62,6 +62,12 @@ UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128,
64002 /* Reported-by: David Webb <djw@noc.ac.uk> */
64005 @@ -97,6 +103,12 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
64015 /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
64018 @@ -111,6 +123,12 @@ UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999,
64028 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
64031 diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
64033 --- a/drivers/video/Kconfig
64035 @@ -18,6 +18,7 @@ source "drivers/gpu/host1x/Kconfig"
64036 source "drivers/gpu/ipu-v3/Kconfig"
64043 @@ -25,6 +26,10 @@ endmenu
64054 diff --git a/drivers/video/Makefile b/drivers/video/Makefile
64056 --- a/drivers/video/Makefile
64058 @@ -6,6 +6,7 @@ obj-$(CONFIG_VT) += console/
64059 obj-$(CONFIG_FB_STI) += console/
64060 obj-$(CONFIG_LOGO) += logo/
64061 obj-y += backlight/
64062 +obj-y += rockchip/
64064 obj-y += fbdev/
64066 diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
64068 --- a/drivers/video/backlight/pwm_bl.c
64070 @@ -603,6 +603,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
64071 pb->scale = data->max_brightness;
64074 + pwm_adjust_config(pb->pwm);
64076 pb->lth_brightness = data->lth_brightness * (div_u64(state.period,
64077 pb->scale));
64079 --