• Home
  • Raw
  • Download

Lines Matching +full:gpio2 +full:- +full:src +full:- +full:select

1 diff --git a/drivers/Makefile b/drivers/Makefile
3 --- a/drivers/Makefile
5 @@ -6,6 +6,8 @@
6 # Rewritten to use lists instead of if-statements.
11 obj-y += irqchip/
12 obj-y += bus/
14 diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
16 --- a/drivers/block/nbd.c
18 @@ -2398,12 +2398,6 @@ static int nbd_genl_status(struct sk_buff *skb, struct genl_info *info)
22 - if (!dev_list) {
23 - nlmsg_free(reply);
24 - ret = -EMSGSIZE;
25 - goto out;
26 - }
27 -
28 if (index == -1) {
31 diff --git a/drivers/char/Makefile b/drivers/char/Makefile
33 --- a/drivers/char/Makefile
35 @@ -3,6 +3,8 @@
39 +obj-y += jy.o
40 +obj-y += mcu.o
41 obj-y += mem.o random.o
42 obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o
43 obj-y += misc.o
44 diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
46 --- a/drivers/clk/Kconfig
48 @@ -38,6 +38,13 @@ menuconfig COMMON_CLK
62 diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
64 --- a/drivers/clk/clk.c
66 @@ -1313,7 +1313,7 @@ static int __init clk_disable_unused(void)
70 -late_initcall_sync(clk_disable_unused);
75 diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
77 --- a/drivers/clk/rockchip/Kconfig
79 @@ -2,7 +2,7 @@
83 - bool "Rockchip clock controller common support"
88 @@ -11,68 +11,88 @@ config COMMON_CLK_ROCKCHIP
92 - default y
99 - default y
106 - default y
113 - default y
120 - default y
127 - default y
135 - default y
142 - default y
149 - default y
156 - default y
172 + Say y here to enable clk compensation(+/- 1000 ppm).
187 diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
189 --- a/drivers/clk/rockchip/Makefile
191 @@ -13,6 +13,8 @@ clk-rockchip-y += clk-inverter.o
192 clk-rockchip-y += clk-mmc-phase.o
193 clk-rockchip-y += clk-muxgrf.o
194 clk-rockchip-y += clk-ddr.o
195 +clk-rockchip-y += clk-dclk-divider.o
196 +clk-rockchip-y += clk-pvtm.o
197 clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
199 obj-$(CONFIG_CLK_PX30) += clk-px30.o
200 diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
202 --- a/drivers/clk/rockchip/clk-cpu.c
203 +++ b/drivers/clk/rockchip/clk-cpu.c
204 @@ -51,6 +51,7 @@
212 @@ -88,10 +89,10 @@ static unsigned long rockchip_cpuclk_recalc_rate(struct clk_hw *hw,
215 const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
216 - u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg);
217 + u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg[0]);
219 - clksel0 >>= reg_data->div_core_shift;
220 - clksel0 &= reg_data->div_core_mask;
221 + clksel0 >>= reg_data->div_core_shift[0];
222 + clksel0 &= reg_data->div_core_mask[0];
226 @@ -124,6 +125,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
233 rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
234 @@ -133,6 +135,8 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
235 return -EINVAL;
238 + rockchip_boost_enable_recovery_sw_low(cpuclk->pll_hw);
240 alt_prate = clk_get_rate(cpuclk->alt_parent);
242 spin_lock_irqsave(cpuclk->lock, flags);
243 @@ -146,10 +150,10 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
244 if (alt_prate > ndata->old_rate) {
246 alt_div = DIV_ROUND_UP(alt_prate, ndata->old_rate) - 1;
247 - if (alt_div > reg_data->div_core_mask) {
248 + if (alt_div > reg_data->div_core_mask[0]) {
249 pr_warn("%s: limiting alt-divider %lu to %d\n",
250 - __func__, alt_div, reg_data->div_core_mask);
251 - alt_div = reg_data->div_core_mask;
252 + __func__, alt_div, reg_data->div_core_mask[0]);
253 + alt_div = reg_data->div_core_mask[0];
257 @@ -162,20 +166,21 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
258 pr_debug("%s: setting div %lu as alt-rate %lu > old-rate %lu\n",
259 __func__, alt_div, alt_prate, ndata->old_rate);
261 - writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask,
262 - reg_data->div_core_shift) |
263 - HIWORD_UPDATE(reg_data->mux_core_alt,
264 - reg_data->mux_core_mask,
265 - reg_data->mux_core_shift),
266 - cpuclk->reg_base + reg_data->core_reg);
267 - } else {
268 - /* select alternate parent */
269 - writel(HIWORD_UPDATE(reg_data->mux_core_alt,
270 - reg_data->mux_core_mask,
271 - reg_data->mux_core_shift),
272 - cpuclk->reg_base + reg_data->core_reg);
273 + for (i = 0; i < reg_data->num_cores; i++) {
274 + writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask[i],
275 + reg_data->div_core_shift[i]),
276 + cpuclk->reg_base + reg_data->core_reg[i]);
280 + rockchip_boost_add_core_div(cpuclk->pll_hw, alt_prate);
282 + /* select alternate parent */
283 + writel(HIWORD_UPDATE(reg_data->mux_core_alt,
284 + reg_data->mux_core_mask,
285 + reg_data->mux_core_shift),
286 + cpuclk->reg_base + reg_data->core_reg[0]);
288 spin_unlock_irqrestore(cpuclk->lock, flags);
291 @@ -186,6 +191,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
292 const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
297 rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
299 @@ -206,16 +212,23 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
303 - writel(HIWORD_UPDATE(0, reg_data->div_core_mask,
304 - reg_data->div_core_shift) |
305 - HIWORD_UPDATE(reg_data->mux_core_main,
306 - reg_data->mux_core_mask,
307 - reg_data->mux_core_shift),
308 - cpuclk->reg_base + reg_data->core_reg);
309 + writel(HIWORD_UPDATE(reg_data->mux_core_main,
310 + reg_data->mux_core_mask,
311 + reg_data->mux_core_shift),
312 + cpuclk->reg_base + reg_data->core_reg[0]);
315 + for (i = 0; i < reg_data->num_cores; i++) {
316 + writel(HIWORD_UPDATE(0, reg_data->div_core_mask[i],
317 + reg_data->div_core_shift[i]),
318 + cpuclk->reg_base + reg_data->core_reg[i]);
321 if (ndata->old_rate > ndata->new_rate)
324 + rockchip_boost_disable_recovery_sw(cpuclk->pll_hw);
326 spin_unlock_irqrestore(cpuclk->lock, flags);
329 @@ -244,14 +257,16 @@ static int rockchip_cpuclk_notifier_cb(struct notifier_block *nb,
333 - const char *const *parent_names, u8 num_parents,
342 - struct clk *clk, *cclk;
348 @@ -259,12 +274,18 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
349 return ERR_PTR(-EINVAL);
354 + return ERR_PTR(-EINVAL);
359 return ERR_PTR(-ENOMEM);
363 - init.parent_names = &parent_names[reg_data->mux_core_main];
368 @@ -281,8 +302,19 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
369 cpuclk->reg_data = reg_data;
370 cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb;
371 cpuclk->hw.init = &init;
372 + if (reg_data->pll_name) {
376 + __func__, reg_data->pll_name);
377 + ret = -EINVAL;
380 + cpuclk->pll_hw = __clk_get_hw(pll_clk);
381 + rockchip_boost_init(cpuclk->pll_hw);
384 - cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]);
385 + cpuclk->alt_parent = alt_parent;
386 if (!cpuclk->alt_parent) {
388 __func__, reg_data->mux_core_alt);
389 @@ -297,11 +329,11 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
393 - clk = __clk_lookup(parent_names[reg_data->mux_core_main]);
397 __func__, reg_data->mux_core_main,
398 - parent_names[reg_data->mux_core_main]);
400 ret = -EINVAL;
403 diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
405 --- a/drivers/clk/rockchip/clk-ddr.c
406 +++ b/drivers/clk/rockchip/clk-ddr.c
407 @@ -8,10 +8,20 @@
409 #include <linux/clk-provider.h>
428 @@ -21,25 +31,47 @@ struct rockchip_ddrclk {
432 - spinlock_t *lock;
464 - struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
465 - unsigned long flags;
468 - spin_lock_irqsave(ddrclk->lock, flags);
472 - spin_unlock_irqrestore(ddrclk->lock, flags);
474 - return res.a0;
478 + return -EPERM;
482 @@ -87,18 +119,134 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = {
497 + lcdc_type = p->lcdc_type;
505 + ret = -1;
546 + p->hz = drate;
581 + p->hz = rate;
603 - int ddr_flag, void __iomem *reg_base,
604 - spinlock_t *lock)
618 return ERR_PTR(-ENOMEM);
619 @@ -114,6 +262,12 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
632 @@ -121,7 +275,6 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
635 ddrclk->reg_base = reg_base;
636 - ddrclk->lock = lock;
637 ddrclk->hw.init = &init;
638 ddrclk->mux_offset = mux_offset;
639 ddrclk->mux_shift = mux_shift;
640 diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c
642 --- a/drivers/clk/rockchip/clk-half-divider.c
643 +++ b/drivers/clk/rockchip/clk-half-divider.c
644 @@ -14,9 +14,9 @@ static bool _is_best_half_div(unsigned long rate, unsigned long now,
648 - return abs(rate - now) < abs(rate - best);
649 + return abs(rate - now) <= abs(rate - best);
651 - return now <= rate && now > best;
656 @@ -38,7 +38,7 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
660 - unsigned long parent_rate_saved = *best_parent_rate;
665 @@ -51,7 +51,7 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
669 - bestdiv = (bestdiv - 3) / 2;
670 + bestdiv = DIV_ROUND_UP(bestdiv - 3, 2);
674 @@ -63,28 +63,20 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
678 - if (((u64)rate * (i * 2 + 3)) == ((u64)parent_rate_saved * 2)) {
679 - /*
680 - * It's the most ideal case if the requested rate can be
681 - * divided from parent clock without needing to change
682 - * parent rate, so return the divider immediately.
683 - */
684 - *best_parent_rate = parent_rate_saved;
685 - return i;
686 - }
700 - if (!bestdiv) {
705 @@ -114,7 +106,7 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate,
709 - value = (value - 3) / 2;
710 + value = DIV_ROUND_UP(value - 3, 2);
711 value = min_t(unsigned int, value, div_mask(divider->width));
713 if (divider->lock)
714 @@ -160,10 +152,10 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
718 - u8 div_shift, u8 div_width,
719 - u8 div_flags, int gate_offset,
720 - u8 gate_shift, u8 gate_flags,
721 - unsigned long flags,
728 struct clk_hw *hw = ERR_PTR(-ENOMEM);
729 @@ -205,7 +197,10 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
732 div->flags = div_flags;
733 - div->reg = base + muxdiv_offset;
735 + div->reg = base + div_offset;
737 + div->reg = base + muxdiv_offset;
738 div->shift = div_shift;
739 div->width = div_width;
740 div->lock = lock;
741 diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
743 --- a/drivers/clk/rockchip/clk-pll.c
744 +++ b/drivers/clk/rockchip/clk-pll.c
745 @@ -15,6 +15,9 @@
755 @@ -38,15 +41,291 @@ struct rockchip_clk_pll {
815 + return -EINVAL;
819 + return -EINVAL;
821 + pll->sel = sel;
835 + return -EINVAL;
839 + return -EINVAL;
841 + rate_table = pll->rate_table;
842 + for (i = 0; i < pll->rate_count; i++) {
847 + return -EINVAL;
859 + return -EINVAL;
863 + return -EINVAL;
865 + rate_table = pll->rate_table;
866 + for (i = 0; i < pll->rate_count; i++) {
871 + return -EINVAL;
923 + rate_table->postdiv1 = postdiv1;
924 + rate_table->postdiv2 = postdiv2;
925 + rate_table->dsmpd = 1;
931 + rate_table->refdiv = fin_hz / clk_gcd;
932 + rate_table->fbdiv = foutvco / clk_gcd;
934 + rate_table->frac = 0;
937 + fin_hz, fout_hz, clk_gcd, rate_table->refdiv,
938 + rate_table->fbdiv, rate_table->postdiv1,
939 + rate_table->postdiv2, rate_table->frac);
946 + rate_table->postdiv1, rate_table->postdiv2, foutvco);
948 + rate_table->refdiv = fin_hz / MHZ / clk_gcd;
949 + rate_table->fbdiv = foutvco / MHZ / clk_gcd;
951 + rate_table->refdiv, rate_table->fbdiv);
953 + rate_table->frac = 0;
957 + do_div(fin_64, (u64)rate_table->refdiv);
960 + rate_table->frac = (u32)frac_64;
961 + if (rate_table->frac > 0)
962 + rate_table->dsmpd = 0;
963 + pr_debug("frac = %x\n", rate_table->frac);
1022 + /* select the best from all available PLL settings */
1034 + rate_table->nr = nr_out;
1035 + rate_table->nf = nf_out;
1036 + rate_table->no = no_out;
1047 @@ -54,28 +333,27 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
1050 for (i = 0; i < pll->rate_count; i++) {
1051 - if (rate == rate_table[i].rate)
1053 + if (i < pll->sel) {
1054 + pll->scaling = rate;
1055 + return &rate_table[pll->sel];
1057 + pll->scaling = 0;
1061 + pll->scaling = 0;
1063 - return NULL;
1064 + if (pll->type == pll_rk3066)
1073 - struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1074 - const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
1075 - int i;
1076 -
1077 - /* Assumming rate_table is in descending order */
1078 - for (i = 0; i < pll->rate_count; i++) {
1079 - if (drate >= rate_table[i].rate)
1080 - return rate_table[i].rate;
1081 - }
1082 -
1083 - /* return minimum supported value */
1084 - return rate_table[i - 1].rate;
1089 @@ -136,6 +414,30 @@ static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
1120 @@ -165,7 +467,10 @@ static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
1124 - u64 rate64 = prate;
1127 + if (pll->sel && pll->scaling)
1128 + return pll->scaling;
1132 @@ -174,7 +479,7 @@ static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
1136 - u64 frac_rate64 = prate * cur.frac;
1141 @@ -231,6 +536,8 @@ static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
1142 pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
1143 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
1150 @@ -412,6 +719,9 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
1154 + if (pll->sel && pll->scaling)
1155 + return pll->scaling;
1160 @@ -485,9 +795,18 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
1165 + struct regmap *grf = pll->ctx->grf;
1168 - pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
1169 - __func__, clk_hw_get_name(hw), drate, prate);
1181 @@ -497,7 +816,11 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
1182 return -EINVAL;
1185 - return rockchip_rk3066_pll_set_params(pll, rate);
1188 + pll->scaling = 0;
1194 @@ -649,6 +972,9 @@ static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
1198 + if (pll->sel && pll->scaling)
1199 + return pll->scaling;
1204 @@ -692,6 +1018,11 @@ static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
1211 + pll->reg_base + RK3399_PLLCON(3));
1214 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
1216 @@ -715,6 +1046,11 @@ static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
1218 pll->reg_base + RK3399_PLLCON(3));
1223 + pll->reg_base + RK3399_PLLCON(3));
1228 @@ -734,9 +1070,11 @@ static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drat…
1235 - pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
1236 - __func__, __clk_get_name(hw->clk), drate, prate);
1238 + __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
1242 @@ -746,7 +1084,11 @@ static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drat…
1243 return -EINVAL;
1246 - return rockchip_rk3399_pll_set_params(pll, rate);
1249 + pll->scaling = 0;
1255 @@ -842,6 +1184,80 @@ static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
1269 + if ((ppm > 1000) || (ppm < -1000))
1270 + return -EINVAL;
1273 + return -EINVAL;
1277 + return -EINVAL;
1279 + switch (pll->type) {
1289 + return -EINVAL;
1298 + return -EINVAL;
1305 + frac = readl_relaxed(pll->reg_base + pllcon2) & frac_mask;
1306 + fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
1311 + * -------------- = (fbdiv + ----------) * ---------
1318 + fracdiv = negative ? frac - (m + n) : frac + (m + n);
1321 + return -EINVAL;
1323 + pllcon = readl_relaxed(pll->reg_base + pllcon2);
1326 + writel_relaxed(pllcon, pll->reg_base + pllcon2);
1336 @@ -914,8 +1330,12 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1349 @@ -940,7 +1360,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1353 - if (!pll->rate_table)
1354 + if (!pll->rate_table || IS_ERR(ctx->grf))
1358 @@ -987,3 +1407,316 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1366 + switch (pll->type) {
1390 + np = of_parse_phandle(pll->ctx->cru_node, "rockchip,boost", 0);
1395 + pll->boost = syscon_node_to_regmap(np);
1396 + if (IS_ERR(pll->boost)) {
1401 + if (!of_property_read_u32(np, "rockchip,boost-low-con0", &con0) &&
1402 + !of_property_read_u32(np, "rockchip,boost-low-con1", &con1)) {
1403 + pr_debug("boost-low-con=0x%x 0x%x\n", con0, con1);
1404 + regmap_write(pll->boost, BOOST_PLL_L_CON(0),
1406 + regmap_write(pll->boost, BOOST_PLL_L_CON(1),
1408 + pll->boost_low_rate = rockchip_pll_con_to_rate(pll, con0,
1410 + pr_debug("boost-low-rate=%lu\n", pll->boost_low_rate);
1412 + if (!of_property_read_u32(np, "rockchip,boost-high-con0", &con0) &&
1413 + !of_property_read_u32(np, "rockchip,boost-high-con1", &con1)) {
1414 + pr_debug("boost-high-con=0x%x 0x%x\n", con0, con1);
1415 + regmap_write(pll->boost, BOOST_PLL_H_CON(0),
1417 + regmap_write(pll->boost, BOOST_PLL_H_CON(1),
1419 + pll->boost_high_rate = rockchip_pll_con_to_rate(pll, con0,
1421 + pr_debug("boost-high-rate=%lu\n", pll->boost_high_rate);
1423 + if (!of_property_read_u32(np, "rockchip,boost-backup-pll", &value)) {
1424 + pr_debug("boost-backup-pll=0x%x\n", value);
1425 + regmap_write(pll->boost, BOOST_CLK_CON,
1429 + if (!of_property_read_u32(np, "rockchip,boost-backup-pll-usage",
1430 + &pll->boost_backup_pll_usage)) {
1431 + pr_debug("boost-backup-pll-usage=0x%x\n",
1432 + pll->boost_backup_pll_usage);
1433 + regmap_write(pll->boost, BOOST_CLK_CON,
1434 + HIWORD_UPDATE(pll->boost_backup_pll_usage,
1438 + if (!of_property_read_u32(np, "rockchip,boost-switch-threshold",
1440 + pr_debug("boost-switch-threshold=0x%x\n", value);
1441 + regmap_write(pll->boost, BOOST_SWITCH_THRESHOLD, value);
1443 + if (!of_property_read_u32(np, "rockchip,boost-statis-threshold",
1445 + pr_debug("boost-statis-threshold=0x%x\n", value);
1446 + regmap_write(pll->boost, BOOST_STATIS_THRESHOLD, value);
1448 + if (!of_property_read_u32(np, "rockchip,boost-statis-enable",
1450 + pr_debug("boost-statis-enable=0x%x\n", value);
1451 + regmap_write(pll->boost, BOOST_BOOST_CON,
1455 + if (!of_property_read_u32(np, "rockchip,boost-enable", &value)) {
1456 + pr_debug("boost-enable=0x%x\n", value);
1457 + regmap_write(pll->boost, BOOST_BOOST_CON,
1461 + pll->boost_enabled = true;
1464 + if (pll->boost_enabled) {
1466 + hlist_add_head(&pll->debug_node, &clk_boost_list);
1480 + if (!pll->boost_enabled)
1483 + regmap_write(pll->boost, BOOST_BOOST_CON,
1487 + regmap_read(pll->boost, BOOST_FSM_STATUS, &val);
1490 + regmap_write(pll->boost, BOOST_BOOST_CON,
1499 + if (!pll->boost_enabled)
1502 + regmap_write(pll->boost, BOOST_BOOST_CON,
1514 + if (!pll->boost_enabled)
1517 + regmap_write(pll->boost, BOOST_BOOST_CON,
1520 + regmap_write(pll->boost, BOOST_BOOST_CON,
1533 + if (!pll->boost_enabled || pll->boost_backup_pll_rate == prate)
1537 + if (pll->boost_backup_pll_usage == BOOST_BACKUP_PLL_USAGE_TARGET)
1543 + if (pll->boost_low_rate && prate > pll->boost_low_rate) {
1544 + div = DIV_ROUND_UP(prate, pll->boost_low_rate) - 1;
1545 + regmap_write(pll->boost, BOOST_CLK_CON,
1548 + pll->boost_backup_pll_rate = prate;
1558 + struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
1566 + seq_puts(s, "------------------------------------------------------------------------------------…
1567 + seq_printf(s, " %s\n", clk_hw_get_name(&pll->hw));
1569 + regmap_read(pll->boost, BOOST_SWITCH_CNT, &boost_count);
1571 + regmap_read(pll->boost, BOOST_HIGH_PERF_CNT0, &freq_cnt0);
1572 + regmap_read(pll->boost, BOOST_HIGH_PERF_CNT1, &freq_cnt1);
1577 + regmap_read(pll->boost, BOOST_SHORT_SWITCH_CNT, &short_count);
1578 + regmap_read(pll->boost, BOOST_STATIS_THRESHOLD, &short_threshold);
1579 + regmap_read(pll->boost, BOOST_SWITCH_THRESHOLD, &interval_time);
1590 + return single_open(file, boost_summary_show, inode->i_private);
1602 + struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
1604 + seq_printf(s, "boost_enabled: %d\n", pll->boost_enabled);
1605 + seq_printf(s, "boost_low_rate: %lu\n", pll->boost_low_rate);
1606 + seq_printf(s, "boost_high_rate: %lu\n", pll->boost_high_rate);
1613 + return single_open(file, boost_config_show, inode->i_private);
1628 + pdentry = debugfs_lookup(clk_hw_get_name(&pll->hw), rootdir);
1631 + clk_hw_get_name(&pll->hw));
1632 + return -ENOMEM;
1639 + return -ENOMEM;
1646 + return -ENOMEM;
1660 + return -ENOMEM;
1675 diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
1677 --- a/drivers/clk/rockchip/clk-rk3399.c
1678 +++ b/drivers/clk/rockchip/clk-rk3399.c
1679 @@ -15,6 +15,12 @@
1680 #include <dt-bindings/clock/rk3399-cru.h>
1692 @@ -105,25 +111,95 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
1718 -PNAME(mux_armclkl_p) = { "clk_core_l_lpll_src",
1719 - "clk_core_l_bpll_src",
1720 - "clk_core_l_dpll_src",
1721 - "clk_core_l_gpll_src" };
1722 -PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src",
1723 - "clk_core_b_bpll_src",
1724 - "clk_core_b_dpll_src",
1725 - "clk_core_b_gpll_src" };
1792 - "vpll_aclk_cci_src" };
1797 @@ -148,26 +224,17 @@ PNAME(mux_pll_src_cpll_gpll_npll_upll_24m_p) = { "cpll", "gpll", "npll",
1801 -
1802 -PNAME(mux_pll_src_vpll_cpll_gpll_p) = { "vpll", "cpll", "gpll" };
1803 -PNAME(mux_pll_src_vpll_cpll_gpll_npll_p) = { "vpll", "cpll", "gpll",
1811 -PNAME(mux_pll_src_vpll_cpll_gpll_24m_p) = { "vpll", "cpll", "gpll",
1812 - "xin24m" };
1813 -
1814 -PNAME(mux_dclk_vop0_p) = { "dclk_vop0_div",
1815 - "dclk_vop0_frac" };
1816 -PNAME(mux_dclk_vop1_p) = { "dclk_vop1_div",
1817 - "dclk_vop1_frac" };
1818 -
1819 -PNAME(mux_clk_cif_p) = { "clk_cifout_src", "xin24m" };
1820 -
1821 -PNAME(mux_pll_src_24m_usbphy480m_p) = { "xin24m", "clk_usbphy_480m" };
1822 -PNAME(mux_pll_src_24m_pciephy_p) = { "xin24m", "clk_pciephy_ref100m" };
1827 -PNAME(mux_pciecore_cru_phy_p) = { "clk_pcie_core_cru",
1828 - "clk_pcie_core_phy" };
1832 @@ -180,14 +247,26 @@ PNAME(mux_fclk_cm0s_p) = { "cpll_fclk_cm0s_src",
1856 -PNAME(mux_aclk_gmac_p) = { "cpll_aclk_gmac_src",
1857 - "gpll_aclk_gmac_src" };
1861 @@ -201,20 +280,22 @@ PNAME(mux_i2sch_p) = { "clk_i2s0", "clk_i2s1",
1865 -PNAME(mux_uart0_p) = { "clk_uart0_div", "clk_uart0_frac", "xin24m" };
1866 -PNAME(mux_uart1_p) = { "clk_uart1_div", "clk_uart1_frac", "xin24m" };
1867 -PNAME(mux_uart2_p) = { "clk_uart2_div", "clk_uart2_frac", "xin24m" };
1868 -PNAME(mux_uart3_p) = { "clk_uart3_div", "clk_uart3_frac", "xin24m" };
1879 -PNAME(mux_uart4_pmu_p) = { "clk_uart4_div", "clk_uart4_frac",
1880 - "xin24m" };
1890 @@ -222,18 +303,23 @@ static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = {
1902 - RK3399_PLL_CON(35), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
1907 - RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
1912 - [ppll] = PLL(pll_rk3399, PLL_PPLL, "ppll", mux_pll_p, 0, RK3399_PMU_PLL_CON(0),
1917 @@ -259,24 +345,24 @@ static struct rockchip_clk_branch rk3399_i2s2_fracmux __initdata =
1921 - MUX(SCLK_UART0, "clk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
1922 - RK3399_CLKSEL_CON(33), 8, 2, MFLAGS);
1927 - MUX(SCLK_UART1, "clk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
1928 - RK3399_CLKSEL_CON(34), 8, 2, MFLAGS);
1933 - MUX(SCLK_UART2, "clk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
1934 - RK3399_CLKSEL_CON(35), 8, 2, MFLAGS);
1939 - MUX(SCLK_UART3, "clk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
1940 - RK3399_CLKSEL_CON(36), 8, 2, MFLAGS);
1945 - MUX(SCLK_UART4_PMU, "clk_uart4_pmu", mux_uart4_pmu_p, CLK_SET_RATE_PARENT,
1946 - RK3399_PMU_CLKSEL_CON(5), 8, 2, MFLAGS);
1952 @@ -291,9 +377,10 @@ static struct rockchip_clk_branch rk3399_pmuclk_wifi_fracmux __initdata =
1956 - .core_reg = RK3399_CLKSEL_CON(0),
1957 - .div_core_shift = 0,
1958 - .div_core_mask = 0x1f,
1966 @@ -301,9 +388,10 @@ static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = {
1970 - .core_reg = RK3399_CLKSEL_CON(2),
1971 - .div_core_shift = 0,
1972 - .div_core_mask = 0x1f,
1980 @@ -406,9 +494,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
1984 - GATE(0, "clk_usbphy0_480m_src", "clk_usbphy0_480m", 0,
1987 - GATE(0, "clk_usbphy1_480m_src", "clk_usbphy1_480m", 0,
1992 @@ -423,7 +511,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
1996 - GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", CLK_IGNORE_UNUSED,
2001 @@ -549,7 +637,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2005 - GATE(ACLK_GMAC_NOC, "aclk_gmac_noc", "aclk_gmac_pre", CLK_IGNORE_UNUSED,
2010 @@ -559,7 +647,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2014 - GATE(PCLK_GMAC_NOC, "pclk_gmac_noc", "pclk_gmac_pre", CLK_IGNORE_UNUSED,
2019 @@ -578,13 +666,13 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2023 - COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0,
2027 - COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", 0,
2031 - &rk3399_spdif_fracmux),
2036 @@ -592,84 +680,84 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2040 - COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
2044 - COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0,
2048 - &rk3399_i2s0_fracmux),
2053 - COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
2057 - COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0,
2061 - &rk3399_i2s1_fracmux),
2066 - COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
2070 - COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0,
2074 - &rk3399_i2s2_fracmux),
2079 - MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT,
2087 - MUX(0, "clk_uart0_src", mux_pll_src_cpll_gpll_upll_p, 0,
2093 - COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", 0,
2097 - &rk3399_uart0_fracmux),
2100 - MUX(0, "clk_uart_src", mux_pll_src_cpll_gpll_p, 0,
2106 - COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", 0,
2110 - &rk3399_uart1_fracmux),
2116 - COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", 0,
2120 - &rk3399_uart2_fracmux),
2126 - COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", 0,
2130 - &rk3399_uart3_fracmux),
2133 - COMPOSITE(PCLK_DDR, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
2138 - GATE(PCLK_CENTER_MAIN_NOC, "pclk_center_main_noc", "pclk_ddr", CLK_IGNORE_UNUSED,
2143 @@ -686,30 +774,30 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2147 - GATE(0, "cpll_aclk_cci_src", "cpll", CLK_IGNORE_UNUSED,
2150 - GATE(0, "gpll_aclk_cci_src", "gpll", CLK_IGNORE_UNUSED,
2153 - GATE(0, "npll_aclk_cci_src", "npll", CLK_IGNORE_UNUSED,
2156 - GATE(0, "vpll_aclk_cci_src", "vpll", CLK_IGNORE_UNUSED,
2160 - COMPOSITE(0, "aclk_cci_pre", mux_aclk_cci_p, CLK_IGNORE_UNUSED,
2165 - GATE(ACLK_ADB400M_PD_CORE_L, "aclk_adb400m_pd_core_l", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2168 - GATE(ACLK_ADB400M_PD_CORE_B, "aclk_adb400m_pd_core_b", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2171 - GATE(ACLK_CCI, "aclk_cci", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2174 - GATE(ACLK_CCI_NOC0, "aclk_cci_noc0", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2177 - GATE(ACLK_CCI_NOC1, "aclk_cci_noc1", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2180 - GATE(ACLK_CCI_GRF, "aclk_cci_grf", "aclk_cci_pre", CLK_IGNORE_UNUSED,
2185 @@ -717,20 +805,20 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2189 - RK3399_CLKSEL_CON(5), 15, 2, MFLAGS, 8, 5, DFLAGS,
2193 - GATE(0, "cpll_cs", "cpll", CLK_IGNORE_UNUSED,
2196 - GATE(0, "gpll_cs", "gpll", CLK_IGNORE_UNUSED,
2199 - GATE(0, "npll_cs", "npll", CLK_IGNORE_UNUSED,
2202 - COMPOSITE_NOGATE(0, "clk_cs", mux_cs_p, CLK_IGNORE_UNUSED,
2207 - GATE(0, "clk_dbg_noc", "clk_cs", CLK_IGNORE_UNUSED,
2212 @@ -742,12 +830,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2216 - GATE(0, "hclk_vcodec_noc", "hclk_vcodec_pre", CLK_IGNORE_UNUSED,
2222 - GATE(0, "aclk_vcodec_noc", "aclk_vcodec_pre", CLK_IGNORE_UNUSED,
2227 @@ -766,12 +854,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2231 - GATE(HCLK_VDU_NOC, "hclk_vdu_noc", "hclk_vdu_pre", CLK_IGNORE_UNUSED,
2237 - GATE(ACLK_VDU_NOC, "aclk_vdu_noc", "aclk_vdu_pre", CLK_IGNORE_UNUSED,
2242 @@ -783,12 +871,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2246 - GATE(HCLK_IEP_NOC, "hclk_iep_noc", "hclk_iep_pre", CLK_IGNORE_UNUSED,
2252 - GATE(ACLK_IEP_NOC, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED,
2257 @@ -804,21 +892,21 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2261 - GATE(HCLK_RGA_NOC, "hclk_rga_noc", "hclk_rga_pre", CLK_IGNORE_UNUSED,
2267 - GATE(ACLK_RGA_NOC, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED,
2272 - COMPOSITE(0, "aclk_center", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED,
2276 - GATE(ACLK_CENTER_MAIN_NOC, "aclk_center_main_noc", "aclk_center", CLK_IGNORE_UNUSED,
2279 - GATE(ACLK_CENTER_PERI_NOC, "aclk_center_peri_noc", "aclk_center", CLK_IGNORE_UNUSED,
2284 @@ -835,25 +923,25 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2288 - GATE(0, "cpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED,
2291 - GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED,
2294 - COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED,
2298 - COMPOSITE_NOMUX(HCLK_PERIHP, "hclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
2302 - COMPOSITE_NOMUX(PCLK_PERIHP, "pclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
2303 - RK3399_CLKSEL_CON(14), 12, 2, DFLAGS,
2312 - GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED,
2317 @@ -866,16 +954,16 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2321 - GATE(0, "hclk_perihp_noc", "hclk_perihp", CLK_IGNORE_UNUSED,
2327 - GATE(PCLK_PERIHP_GRF, "pclk_perihp_grf", "pclk_perihp", CLK_IGNORE_UNUSED,
2332 - GATE(0, "pclk_perihp_noc", "pclk_perihp", CLK_IGNORE_UNUSED,
2337 @@ -886,7 +974,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2341 - GATE(0, "hclk_sdmmc_noc", "hclk_sd", CLK_IGNORE_UNUSED,
2346 @@ -933,23 +1021,23 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2350 - GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", CLK_IGNORE_UNUSED,
2357 - GATE(0, "cpll_aclk_perilp0_src", "cpll", CLK_IGNORE_UNUSED,
2360 - GATE(0, "gpll_aclk_perilp0_src", "gpll", CLK_IGNORE_UNUSED,
2363 - COMPOSITE(ACLK_PERILP0, "aclk_perilp0", mux_aclk_perilp0_p, CLK_IGNORE_UNUSED,
2367 - COMPOSITE_NOMUX(HCLK_PERILP0, "hclk_perilp0", "aclk_perilp0", CLK_IGNORE_UNUSED,
2371 - COMPOSITE_NOMUX(PCLK_PERILP0, "pclk_perilp0", "aclk_perilp0", 0,
2376 @@ -964,8 +1052,8 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2380 - GATE(ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 6, GFLAGS…
2381 - GATE(ACLK_PERILP0_NOC, "aclk_perilp0_noc", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(…
2387 @@ -973,7 +1061,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2391 - GATE(HCLK_PERILP0_NOC, "hclk_perilp0_noc", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(…
2396 @@ -1001,29 +1089,29 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2400 - GATE(HCLK_M0_PERILP_NOC, "hclk_m0_perilp_noc", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON…
2404 - GATE(0, "cpll_hclk_perilp1_src", "cpll", CLK_IGNORE_UNUSED,
2407 - GATE(0, "gpll_hclk_perilp1_src", "gpll", CLK_IGNORE_UNUSED,
2410 - COMPOSITE_NOGATE(HCLK_PERILP1, "hclk_perilp1", mux_hclk_perilp1_p, CLK_IGNORE_UNUSED,
2413 - COMPOSITE_NOMUX(PCLK_PERILP1, "pclk_perilp1", "hclk_perilp1", CLK_IGNORE_UNUSED,
2419 - GATE(0, "hclk_perilp1_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 9, GFLAGS),
2420 - GATE(0, "hclk_sdio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 12, GFLAGS),
2429 - GATE(0, "hclk_sdioaudio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 6, GFLAG…
2434 @@ -1046,7 +1134,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2438 - GATE(0, "pclk_perilp1_noc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(25), 10, GFLAGS),
2443 @@ -1075,24 +1163,23 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2447 - COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0,
2452 - GATE(ACLK_VIO_NOC, "aclk_vio_noc", "aclk_vio", CLK_IGNORE_UNUSED,
2460 - GATE(PCLK_VIO_GRF, "pclk_vio_grf", "pclk_vio", CLK_IGNORE_UNUSED,
2465 - COMPOSITE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, 0,
2466 - RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS,
2467 - RK3399_CLKGATE_CON(11), 12, GFLAGS),
2473 @@ -1100,17 +1187,17 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2477 - GATE(ACLK_HDCP_NOC, "aclk_hdcp_noc", "aclk_hdcp", CLK_IGNORE_UNUSED,
2483 - GATE(HCLK_HDCP_NOC, "hclk_hdcp_noc", "hclk_hdcp", CLK_IGNORE_UNUSED,
2489 - GATE(PCLK_HDCP_NOC, "pclk_hdcp_noc", "pclk_hdcp", CLK_IGNORE_UNUSED,
2494 @@ -1129,7 +1216,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2498 - GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED,
2503 @@ -1143,7 +1230,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2507 - COMPOSITE(ACLK_VOP0_PRE, "aclk_vop0_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
2512 @@ -1152,28 +1239,35 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2516 - GATE(ACLK_VOP0_NOC, "aclk_vop0_noc", "aclk_vop0_pre", CLK_IGNORE_UNUSED,
2522 - GATE(HCLK_VOP0_NOC, "hclk_vop0_noc", "hclk_vop0_pre", CLK_IGNORE_UNUSED,
2526 - COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, 0,
2537 - COMPOSITE_FRACMUX_NOGATE(DCLK_VOP0_FRAC, "dclk_vop0_frac", "dclk_vop0_div", 0,
2538 + /* The VOP0 is main screen, it is able to re-set parent rate. */
2541 - &rk3399_dclk_vop0_fracmux),
2544 - COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, 0,
2550 - COMPOSITE(ACLK_VOP1_PRE, "aclk_vop1_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
2555 @@ -1182,23 +1276,30 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2559 - GATE(ACLK_VOP1_NOC, "aclk_vop1_noc", "aclk_vop1_pre", CLK_IGNORE_UNUSED,
2565 - GATE(HCLK_VOP1_NOC, "hclk_vop1_noc", "hclk_vop1_pre", CLK_IGNORE_UNUSED,
2569 - COMPOSITE(DCLK_VOP1_DIV, "dclk_vop1_div", mux_pll_src_vpll_cpll_gpll_p, 0,
2570 + /* The VOP1 is sub screen, it is note able to re-set parent rate. */
2583 - &rk3399_dclk_vop1_fracmux),
2586 - COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, CLK_IGNORE_UNUSED,
2591 @@ -1210,14 +1311,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2595 - GATE(ACLK_ISP0_NOC, "aclk_isp0_noc", "aclk_isp0", CLK_IGNORE_UNUSED,
2600 - GATE(HCLK_ISP1_WRAPPER, "hclk_isp1_wrapper", "aclk_isp0", 0,
2601 - RK3399_CLKGATE_CON(27), 7, GFLAGS),
2603 - GATE(HCLK_ISP0_NOC, "hclk_isp0_noc", "hclk_isp0", CLK_IGNORE_UNUSED,
2608 @@ -1233,13 +1332,15 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2612 - GATE(ACLK_ISP1_NOC, "aclk_isp1_noc", "aclk_isp1", CLK_IGNORE_UNUSED,
2618 - GATE(HCLK_ISP1_NOC, "hclk_isp1_noc", "hclk_isp1", CLK_IGNORE_UNUSED,
2621 - GATE(ACLK_ISP1_WRAPPER, "aclk_isp1_wrapper", "hclk_isp1", 0,
2622 - RK3399_CLKGATE_CON(27), 8, GFLAGS),
2628 @@ -1257,7 +1358,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2632 - COMPOSITE_NODIV(0, "clk_cifout_src", mux_pll_src_cpll_gpll_npll_p, 0,
2637 @@ -1265,12 +1366,12 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2641 - COMPOSITE(ACLK_GIC_PRE, "aclk_gic_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
2646 - GATE(ACLK_GIC, "aclk_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 0, GFLAGS),
2647 - GATE(ACLK_GIC_NOC, "aclk_gic_noc", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 1, …
2653 @@ -1301,19 +1402,19 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2657 - GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21)…
2661 - GATE(SCLK_DPHY_TX0_CFG, "clk_dphy_tx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE…
2662 - GATE(SCLK_DPHY_TX1RX1_CFG, "clk_dphy_tx1rx1_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_C…
2663 - GATE(SCLK_DPHY_RX0_CFG, "clk_dphy_rx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE…
2673 - RK3399_CLKGATE_CON(13), 9, GFLAGS),
2678 @@ -1385,13 +1486,13 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
2682 - GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3),
2685 - GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3),
2688 - GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3),
2691 - GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3),
2696 @@ -1402,10 +1503,10 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2697 * PMU CRU Clock-Architecture
2700 - GATE(0, "fclk_cm0s_pmu_ppll_src", "ppll", 0,
2704 - COMPOSITE_NOGATE(FCLK_CM0S_SRC_PMU, "fclk_cm0s_src_pmu", mux_fclk_cm0s_pmu_ppll_p, 0,
2709 @@ -1416,9 +1517,9 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2713 - COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", 0,
2716 - &rk3399_pmuclk_wifi_fracmux),
2721 @@ -1440,23 +1541,26 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2725 - COMPOSITE(0, "clk_uart4_div", mux_24m_ppll_p, 0,
2726 - RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS,
2734 - COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", 0,
2738 - &rk3399_uart4_pmu_fracmux),
2741 - DIV(PCLK_SRC_PMU, "pclk_pmu_src", "ppll", CLK_IGNORE_UNUSED,
2749 - GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 7, GF…
2754 @@ -1464,69 +1568,60 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
2758 - GATE(PCLK_NOC_PMU, "pclk_noc_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), …
2763 - GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 10, GFLAGS),
2771 - GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
2772 - GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
2773 - GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
2774 - GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_C…
2775 - GATE(HCLK_NOC_PMU, "hclk_noc_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON…
2783 -static const char *const rk3399_cru_critical_clocks[] __initconst = {
2784 - "aclk_cci_pre",
2785 - "aclk_gic",
2786 - "aclk_gic_noc",
2787 - "aclk_hdcp_noc",
2788 - "hclk_hdcp_noc",
2789 - "pclk_hdcp_noc",
2790 - "pclk_perilp0",
2791 - "pclk_perilp0",
2792 - "hclk_perilp0",
2793 - "hclk_perilp0_noc",
2794 - "pclk_perilp1",
2795 - "pclk_perilp1_noc",
2796 - "pclk_perihp",
2797 - "pclk_perihp_noc",
2798 - "hclk_perihp",
2799 - "aclk_perihp",
2800 - "aclk_perihp_noc",
2801 - "aclk_perilp0",
2802 - "aclk_perilp0_noc",
2803 - "hclk_perilp1",
2804 - "hclk_perilp1_noc",
2805 - "aclk_dmac0_perilp",
2806 - "aclk_emmc_noc",
2807 - "gpll_hclk_perilp1_src",
2808 - "gpll_aclk_perilp0_src",
2809 - "gpll_aclk_perihp_src",
2810 - "aclk_vio_noc",
2814 - /* ddrc */
2815 - "sclk_ddrc"
2816 -};
2841 -static const char *const rk3399_pmucru_critical_clocks[] __initconst = {
2842 - "ppll",
2843 - "pclk_pmu_src",
2844 - "fclk_cm0s_src_pmu",
2845 - "clk_timer_src_pmu",
2846 - "pclk_rkpwm_pmu",
2859 @@ -1534,12 +1629,15 @@ static void __init rk3399_clk_init(struct device_node *np)
2871 + clks = ctx->clk_data.clks;
2874 ARRAY_SIZE(rk3399_pll_clks), -1);
2875 @@ -1547,16 +1645,13 @@ static void __init rk3399_clk_init(struct device_node *np)
2879 - rockchip_clk_protect_critical(rk3399_cru_critical_clocks,
2880 - ARRAY_SIZE(rk3399_cru_critical_clocks));
2881 -
2883 - mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
2889 - mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p),
2894 @@ -1580,6 +1675,8 @@ static void __init rk3399_pmu_clk_init(struct device_node *np)
2903 @@ -1593,13 +1690,13 @@ static void __init rk3399_pmu_clk_init(struct device_node *np)
2907 - rockchip_clk_protect_critical(rk3399_pmucru_critical_clocks,
2908 - ARRAY_SIZE(rk3399_pmucru_critical_clocks));
2909 -
2918 CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init);
2920 diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
2922 --- a/drivers/clk/rockchip/clk.c
2924 @@ -38,6 +38,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
2932 @@ -60,6 +61,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
2933 mux->shift = mux_shift;
2934 mux->mask = BIT(mux_width) - 1;
2935 mux->flags = mux_flags;
2936 + mux->table = mux_table;
2937 mux->lock = lock;
2940 @@ -182,12 +184,43 @@ static void rockchip_fractional_approximation(struct clk_hw *hw,
2947 - if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
2949 + (fd->max_prate && fd->max_prate < p_rate)) {
2951 - p_parent_rate = clk_hw_get_rate(p_parent);
2952 - *parent_rate = p_parent_rate;
2958 + if (fd->max_prate && p_parent_rate > fd->max_prate) {
2960 + fd->max_prate);
2975 + } else if (!(fd->flags & CLK_FRAC_DIVIDER_NO_LIMIT)) {
2976 + pr_warn("%s p_rate(%ld) is low than rate(%ld)*20, use integer or half-div\n",
2987 @@ -210,7 +243,7 @@ static struct clk *rockchip_clk_register_frac_branch(
2991 - spinlock_t *lock)
2996 @@ -251,6 +284,7 @@ static struct clk *rockchip_clk_register_frac_branch(
2997 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
2998 div->lock = lock;
2999 div->approximation = rockchip_fractional_approximation;
3000 + div->max_prate = max_prate;
3004 @@ -278,6 +312,8 @@ static struct clk *rockchip_clk_register_frac_branch(
3005 frac_mux->shift = child->mux_shift;
3006 frac_mux->mask = BIT(child->mux_width) - 1;
3007 frac_mux->flags = child->mux_flags;
3008 + if (child->mux_table)
3009 + frac_mux->table = child->mux_table;
3010 frac_mux->lock = lock;
3011 frac_mux->hw.init = &init;
3013 @@ -360,6 +396,61 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name,
3014 return hw->clk;
3031 + if (brother && brother->branch_type != branch_half_divider) {
3034 + return ERR_PTR(-EINVAL);
3047 + brother_clk = rockchip_clk_register_halfdiv(brother->name,
3048 + brother->parent_names, brother->num_parents,
3049 + base, brother->muxdiv_offset,
3050 + brother->mux_shift, brother->mux_width,
3051 + brother->mux_flags, brother->div_offset,
3052 + brother->div_shift, brother->div_width,
3053 + brother->div_flags, brother->gate_offset,
3054 + brother->gate_shift, brother->gate_flags,
3058 + rockchip_clk_add_lookup(ctx, brother_clk, brother->id);
3065 + composite->brother_hw = brother_hw;
3066 + brother_composite->brother_hw = hw;
3075 @@ -387,6 +478,8 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
3077 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
3079 + ctx->pmugrf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
3084 @@ -452,11 +545,22 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3086 switch (list->branch_type) {
3088 - clk = clk_register_mux(NULL, list->name,
3089 - list->parent_names, list->num_parents,
3090 - flags, ctx->reg_base + list->muxdiv_offset,
3091 - list->mux_shift, list->mux_width,
3092 - list->mux_flags, &ctx->lock);
3093 + if (list->mux_table)
3094 + clk = clk_register_mux_table(NULL, list->name,
3095 + list->parent_names, list->num_parents,
3097 + ctx->reg_base + list->muxdiv_offset,
3098 + list->mux_shift,
3099 + BIT(list->mux_width) - 1,
3100 + list->mux_flags, list->mux_table,
3101 + &ctx->lock);
3103 + clk = clk_register_mux(NULL, list->name,
3104 + list->parent_names, list->num_parents,
3106 + ctx->reg_base + list->muxdiv_offset,
3107 + list->mux_shift, list->mux_width,
3108 + list->mux_flags, &ctx->lock);
3111 clk = rockchip_clk_register_muxgrf(list->name,
3112 @@ -465,6 +569,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3113 list->mux_shift, list->mux_width,
3114 list->mux_flags);
3117 + clk = rockchip_clk_register_muxgrf(list->name,
3118 + list->parent_names, list->num_parents,
3119 + flags, ctx->pmugrf, list->muxdiv_offset,
3120 + list->mux_shift, list->mux_width,
3121 + list->mux_flags);
3124 if (list->div_table)
3126 @@ -488,17 +599,18 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3127 list->div_flags,
3128 list->gate_offset, list->gate_shift,
3129 list->gate_flags, flags, list->child,
3130 - &ctx->lock);
3131 + list->max_prate, &ctx->lock);
3134 clk = rockchip_clk_register_halfdiv(list->name,
3135 list->parent_names, list->num_parents,
3136 ctx->reg_base, list->muxdiv_offset,
3137 list->mux_shift, list->mux_width,
3138 - list->mux_flags, list->div_shift,
3139 - list->div_width, list->div_flags,
3140 - list->gate_offset, list->gate_shift,
3141 - list->gate_flags, flags, &ctx->lock);
3142 + list->mux_flags, list->div_offset,
3143 + list->div_shift, list->div_width,
3144 + list->div_flags, list->gate_offset,
3145 + list->gate_shift, list->gate_flags,
3146 + flags, &ctx->lock);
3150 @@ -514,11 +626,25 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3151 ctx->reg_base, list->muxdiv_offset,
3152 list->mux_shift,
3153 list->mux_width, list->mux_flags,
3154 - list->div_offset, list->div_shift, list->div_width,
3155 + list->mux_table, list->div_offset,
3156 + list->div_shift, list->div_width,
3157 list->div_flags, list->div_table,
3158 list->gate_offset, list->gate_shift,
3159 list->gate_flags, flags, &ctx->lock);
3163 + ctx, list->name, list->parent_names,
3164 + list->num_parents, ctx->reg_base,
3165 + list->muxdiv_offset, list->mux_shift,
3166 + list->mux_width, list->mux_flags,
3167 + list->mux_table, list->div_offset,
3168 + list->div_shift, list->div_width,
3169 + list->div_flags, list->div_table,
3170 + list->gate_offset, list->gate_shift,
3171 + list->gate_flags, flags, list->child,
3172 + &ctx->lock);
3176 list->name,
3177 @@ -549,7 +675,17 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3178 list->muxdiv_offset, list->mux_shift,
3179 list->mux_width, list->div_shift,
3180 list->div_width, list->div_flags,
3181 - ctx->reg_base, &ctx->lock);
3182 + ctx->reg_base);
3185 + clk = rockchip_clk_register_dclk_branch(list->name,
3186 + list->parent_names, list->num_parents,
3187 + ctx->reg_base, list->muxdiv_offset, list->mux_shift,
3188 + list->mux_width, list->mux_flags,
3189 + list->div_offset, list->div_shift, list->div_width,
3190 + list->div_flags, list->div_table,
3191 + list->gate_offset, list->gate_shift,
3192 + list->gate_flags, flags, list->max_prate, &ctx->lock);
3196 @@ -573,15 +709,17 @@ EXPORT_SYMBOL_GPL(rockchip_clk_register_branches);
3200 - const char *name, const char *const *parent_names,
3210 - clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents,
3214 ctx->reg_base, &ctx->lock);
3216 @@ -594,20 +732,20 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
3220 -void rockchip_clk_protect_critical(const char *const clocks[],
3221 - int nclocks)
3222 -{
3223 - int i;
3224 -
3225 - /* Protect the clocks that needs to stay on */
3226 - for (i = 0; i < nclocks; i++) {
3227 - struct clk *clk = __clk_lookup(clocks[i]);
3231 - if (clk)
3232 - clk_prepare_enable(clk);
3233 - }
3241 -EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical);
3249 @@ -641,5 +779,7 @@ rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
3257 diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
3259 --- a/drivers/clk/rockchip/clk.h
3261 @@ -37,12 +37,25 @@ struct clk;
3287 @@ -79,6 +92,51 @@ struct clk;
3339 @@ -188,6 +246,34 @@ struct clk;
3374 @@ -238,22 +324,30 @@ struct rockchip_clk_provider {
3384 - unsigned int nr;
3385 - unsigned int nf;
3386 - unsigned int no;
3387 - unsigned int nb;
3388 - /* for RK3036/RK3399 */
3389 - unsigned int fbdiv;
3390 - unsigned int postdiv1;
3391 - unsigned int refdiv;
3392 - unsigned int postdiv2;
3393 - unsigned int dsmpd;
3394 - unsigned int frac;
3416 @@ -317,12 +411,21 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
3433 -#define ROCKCHIP_CPUCLK_NUM_DIVIDERS 2
3439 @@ -330,26 +433,29 @@ struct rockchip_cpuclk_rate_table {
3442 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
3443 - * @core_reg: register offset of the core settings register
3444 - * @div_core_shift: core divider offset used to divide the pll value
3445 - * @div_core_mask: core divider mask
3446 - * @mux_core_alt: mux value to select alternate parent
3451 * @mux_core_main: mux value to select main parent of core
3456 - int core_reg;
3457 - u8 div_core_shift;
3458 - u32 div_core_mask;
3459 - u8 mux_core_alt;
3460 - u8 mux_core_main;
3461 - u8 mux_core_shift;
3462 - u32 mux_core_mask;
3475 - const char *const *parent_names, u8 num_parents,
3481 @@ -361,16 +467,21 @@ struct clk *rockchip_clk_register_mmc(const char *name,
3499 - int ddr_flags, void __iomem *reg_base,
3500 - spinlock_t *lock);
3505 @@ -388,8 +499,10 @@ struct clk *rockchip_clk_register_muxgrf(const char *name,
3516 @@ -398,6 +511,7 @@ enum rockchip_clk_branch_type {
3524 @@ -411,6 +525,7 @@ struct rockchip_clk_branch {
3532 @@ -420,6 +535,7 @@ struct rockchip_clk_branch {
3540 @@ -443,6 +559,50 @@ struct rockchip_clk_branch {
3591 @@ -539,6 +699,26 @@ struct rockchip_clk_branch {
3592 .gate_offset = -1, \
3611 + .gate_offset = -1, \
3618 @@ -559,7 +739,7 @@ struct rockchip_clk_branch {
3619 .gate_offset = -1, \
3622 -#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
3627 @@ -574,9 +754,10 @@ struct rockchip_clk_branch {
3634 -#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
3639 @@ -592,9 +773,10 @@ struct rockchip_clk_branch {
3646 -#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
3651 @@ -608,6 +790,7 @@ struct rockchip_clk_branch {
3653 .gate_offset = -1, \
3659 @@ -643,6 +826,22 @@ struct rockchip_clk_branch {
3660 .gate_offset = -1, \
3675 + .gate_offset = -1, \
3682 @@ -658,6 +857,21 @@ struct rockchip_clk_branch {
3683 .gate_offset = -1, \
3698 + .gate_offset = -1, \
3704 @@ -772,6 +986,28 @@ struct rockchip_clk_branch {
3733 @@ -824,6 +1060,28 @@ struct rockchip_clk_branch {
3734 .gate_offset = -1, \
3762 @@ -840,13 +1098,17 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
3766 -void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
3767 - unsigned int lookup_id, const char *name,
3768 - const char *const *parent_names, u8 num_parents,
3769 - const struct rockchip_cpuclk_reg_data *reg_data,
3770 - const struct rockchip_cpuclk_rate_table *rates,
3771 - int nrates);
3772 -void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
3787 @@ -857,12 +1119,27 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
3791 - u8 div_shift, u8 div_width,
3792 - u8 div_flags, int gate_offset,
3793 - u8 gate_shift, u8 gate_flags,
3794 - unsigned long flags,
3819 @@ -874,5 +1151,6 @@ static inline void rockchip_register_softrst(struct device_node *np,
3826 diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
3828 --- a/drivers/clocksource/Kconfig
3830 @@ -85,7 +85,9 @@ config IXP4XX_TIMER
3834 - bool "Rockchip timer driver" if COMPILE_TEST
3839 select TIMER_OF
3840 select CLKSRC_MMIO
3841 diff --git a/drivers/clocksource/timer-rockchip.c b/drivers/clocksource/timer-rockchip.c
3843 --- a/drivers/clocksource/timer-rockchip.c
3844 +++ b/drivers/clocksource/timer-rockchip.c
3845 @@ -8,11 +8,13 @@
3859 @@ -45,7 +47,9 @@ struct rk_clkevt {
3869 @@ -119,10 +123,12 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
3876 return ~readl_relaxed(rk_clksrc->base + TIMER_CURRENT_VALUE0);
3882 @@ -250,6 +256,7 @@ static int __init rk_clkevt_init(struct device_node *np)
3889 int ret = -EINVAL;
3890 @@ -287,14 +294,17 @@ static int __init rk_clksrc_init(struct device_node *np)
3907 return -EINVAL;
3908 @@ -302,3 +312,26 @@ static int __init rk_timer_init(struct device_node *np)
3910 TIMER_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_init);
3911 TIMER_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_init);
3916 + return rk_timer_init(pdev->dev.of_node);
3920 + { .compatible = "rockchip,rk3288-timer" },
3921 + { .compatible = "rockchip,rk3399-timer" },
3935 diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
3937 --- a/drivers/cpufreq/Kconfig.arm
3939 @@ -158,6 +158,16 @@ config ARM_RASPBERRYPI_CPUFREQ
3946 + select PM_OPP
3949 + based on cpufreq-dt.
3956 diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
3958 --- a/drivers/cpufreq/Makefile
3960 @@ -5,7 +5,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o
3962 obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o
3964 -# CPUfreq governors
3966 obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
3967 obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
3968 obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
3969 @@ -64,6 +64,7 @@ obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
3970 obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW) += qcom-cpufreq-hw.o
3971 obj-$(CONFIG_ARM_QCOM_CPUFREQ_NVMEM) += qcom-cpufreq-nvmem.o
3972 obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o
3973 +obj-$(CONFIG_ARM_ROCKCHIP_CPUFREQ) += rockchip-cpufreq.o
3974 obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
3975 obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
3976 obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
3977 diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
3979 --- a/drivers/cpufreq/cpufreq-dt-platdev.c
3980 +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
3981 @@ -66,21 +66,6 @@ static const struct of_device_id whitelist[] __initconst = {
3985 - { .compatible = "rockchip,rk2928", },
3986 - { .compatible = "rockchip,rk3036", },
3987 - { .compatible = "rockchip,rk3066a", },
3988 - { .compatible = "rockchip,rk3066b", },
3989 - { .compatible = "rockchip,rk3188", },
3990 - { .compatible = "rockchip,rk3228", },
3991 - { .compatible = "rockchip,rk3288", },
3992 - { .compatible = "rockchip,rk3328", },
3993 - { .compatible = "rockchip,rk3366", },
3994 - { .compatible = "rockchip,rk3368", },
3995 - { .compatible = "rockchip,rk3399",
3996 - .data = &(struct cpufreq_dt_platform_data)
3997 - { .have_governor_per_policy = true, },
3998 - },
3999 -
4000 { .compatible = "st-ericsson,u8500", },
4001 { .compatible = "st-ericsson,u8540", },
4002 { .compatible = "st-ericsson,u9500", },
4003 @@ -137,6 +122,28 @@ static const struct of_device_id blacklist[] __initconst = {
4032 diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
4034 --- a/drivers/cpufreq/cpufreq-dt.c
4035 +++ b/drivers/cpufreq/cpufreq-dt.c
4036 @@ -23,6 +23,9 @@
4039 #include "cpufreq-dt.h"
4041 +#include "rockchip-cpufreq.h"
4046 @@ -30,7 +33,7 @@ struct private_data {
4050 - struct opp_table *reg_opp_table;
4055 @@ -59,7 +62,11 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
4056 struct private_data *priv = policy->driver_data;
4057 unsigned long freq = policy->freq_table[index].frequency;
4060 + return rockchip_cpufreq_opp_set_rate(priv->cpu_dev, freq * 1000);
4062 return dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000);
4067 @@ -102,7 +109,6 @@ static const char *find_supply_name(struct device *dev)
4071 - struct cpufreq_frequency_table *freq_table;
4075 @@ -114,9 +120,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
4076 pr_err("failed to find data for cpu%d\n", policy->cpu);
4077 return -ENODEV;
4079 -
4080 cpu_dev = priv->cpu_dev;
4081 - cpumask_copy(policy->cpus, priv->cpus);
4085 @@ -125,67 +129,32 @@ static int cpufreq_init(struct cpufreq_policy *policy)
4089 - /*
4090 - * Initialize OPP tables for all policy->cpus. They will be shared by
4091 - * all CPUs which have marked their CPUs shared with OPP bindings.
4092 - *
4093 - * For platforms not using operating-points-v2 bindings, we do this
4094 - * before updating policy->cpus. Otherwise, we will end up creating
4095 - * duplicate OPPs for policy->cpus.
4096 - *
4097 - * OPPs might be populated at runtime, don't check for error here
4098 - */
4099 - if (!dev_pm_opp_of_cpumask_add_table(policy->cpus))
4100 - priv->have_static_opps = true;
4101 -
4102 - /*
4103 - * But we need OPP table to function so if it is not there let's
4104 - * give platform code chance to provide it for us.
4105 - */
4106 - ret = dev_pm_opp_get_opp_count(cpu_dev);
4107 - if (ret <= 0) {
4108 - dev_err(cpu_dev, "OPP table can't be empty\n");
4109 - ret = -ENODEV;
4110 - goto out_free_opp;
4111 - }
4112 -
4113 - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
4114 - if (ret) {
4115 - dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
4116 - goto out_free_opp;
4117 - }
4122 + cpumask_copy(policy->cpus, priv->cpus);
4123 policy->driver_data = priv;
4124 policy->clk = cpu_clk;
4125 - policy->freq_table = freq_table;
4126 -
4127 + policy->freq_table = priv->freq_table;
4128 policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(cpu_dev) / 1000;
4129 + policy->cpuinfo.transition_latency = transition_latency;
4130 + policy->dvfs_possible_from_any_cpu = true;
4137 - goto out_free_cpufreq_table;
4142 - transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
4143 - if (!transition_latency)
4144 - transition_latency = CPUFREQ_ETERNAL;
4145 -
4146 - policy->cpuinfo.transition_latency = transition_latency;
4147 - policy->dvfs_possible_from_any_cpu = true;
4148 -
4149 dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
4153 -out_free_cpufreq_table:
4154 - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
4155 -out_free_opp:
4156 - if (priv->have_static_opps)
4157 - dev_pm_opp_of_cpumask_remove_table(policy->cpus);
4162 @@ -208,11 +177,6 @@ static int cpufreq_offline(struct cpufreq_policy *policy)
4166 - struct private_data *priv = policy->driver_data;
4167 -
4168 - dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
4169 - if (priv->have_static_opps)
4170 - dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
4171 clk_put(policy->clk);
4174 @@ -236,6 +200,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
4182 @@ -254,68 +219,91 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
4183 if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL))
4184 return -ENOMEM;
4186 + cpumask_set_cpu(cpu, priv->cpus);
4187 priv->cpu_dev = cpu_dev;
4189 - /* Try to get OPP table early to ensure resources are available */
4190 - priv->opp_table = dev_pm_opp_get_opp_table(cpu_dev);
4191 - if (IS_ERR(priv->opp_table)) {
4192 - ret = PTR_ERR(priv->opp_table);
4193 - if (ret != -EPROBE_DEFER)
4194 - dev_err(cpu_dev, "failed to get OPP table: %d\n", ret);
4195 - goto free_cpumask;
4196 - }
4197 -
4204 - priv->reg_opp_table = dev_pm_opp_set_regulators(cpu_dev,
4205 - &reg_name, 1);
4206 - if (IS_ERR(priv->reg_opp_table)) {
4207 - ret = PTR_ERR(priv->reg_opp_table);
4208 + priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, &reg_name,
4210 + if (IS_ERR(priv->opp_table)) {
4211 + ret = PTR_ERR(priv->opp_table);
4212 if (ret != -EPROBE_DEFER)
4215 - goto put_table;
4220 - /* Find OPP sharing information so we can fill pri->cpus here */
4221 /* Get OPP-sharing information from "operating-points-v2" bindings */
4222 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->cpus);
4224 if (ret != -ENOENT)
4225 - goto put_reg;
4229 * operating-points-v2 not supported, fallback to all CPUs share
4233 - if (dev_pm_opp_get_sharing_cpus(cpu_dev, priv->cpus)) {
4234 - cpumask_setall(priv->cpus);
4235 -
4236 - /*
4237 - * OPP tables are initialized only for cpu, do it for
4238 - * others as well.
4239 - */
4240 - ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->cpus);
4241 - if (ret)
4242 - dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
4243 - __func__, ret);
4244 - }
4245 + if (dev_pm_opp_get_sharing_cpus(cpu_dev, priv->cpus))
4250 + * Initialize OPP tables for all priv->cpus. They will be shared by
4253 + * For platforms not using operating-points-v2 bindings, we do this
4254 + * before updating priv->cpus. Otherwise, we will end up creating
4259 + if (!dev_pm_opp_of_cpumask_add_table(priv->cpus))
4260 + priv->have_static_opps = true;
4269 + ret = -ENODEV;
4274 + cpumask_setall(priv->cpus);
4275 + ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->cpus);
4285 + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &priv->freq_table);
4291 list_add(&priv->node, &priv_list);
4294 -put_reg:
4295 - if (priv->reg_opp_table)
4296 - dev_pm_opp_put_regulators(priv->reg_opp_table);
4297 -put_table:
4298 - dev_pm_opp_put_opp_table(priv->opp_table);
4300 + if (priv->have_static_opps)
4301 + dev_pm_opp_of_cpumask_remove_table(priv->cpus);
4302 + if (priv->opp_table)
4303 + dev_pm_opp_put_regulators(priv->opp_table);
4305 free_cpumask_var(priv->cpus);
4307 @@ -326,9 +314,11 @@ static void dt_cpufreq_release(void)
4311 - if (priv->reg_opp_table)
4312 - dev_pm_opp_put_regulators(priv->reg_opp_table);
4313 - dev_pm_opp_put_opp_table(priv->opp_table);
4314 + dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table);
4315 + if (priv->have_static_opps)
4316 + dev_pm_opp_of_cpumask_remove_table(priv->cpus);
4317 + if (priv->opp_table)
4318 + dev_pm_opp_put_regulators(priv->opp_table);
4319 free_cpumask_var(priv->cpus);
4320 list_del(&priv->node);
4322 diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
4324 --- a/drivers/cpufreq/cpufreq.c
4326 @@ -688,8 +688,12 @@ static ssize_t show_##file_name \
4327 return sprintf(buf, "%u\n", policy->object); \
4332 + unsigned int max_freq = policy->cpuinfo.max_freq;
4336 -show_one(cpuinfo_max_freq, cpuinfo.max_freq);
4340 @@ -2535,6 +2539,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
4347 * cpufreq_update_policy - Re-evaluate an existing cpufreq policy.
4348 diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
4350 --- a/drivers/cpufreq/cpufreq_userspace.c
4352 @@ -78,20 +78,18 @@ static int cpufreq_userspace_policy_start(struct cpufreq_policy *policy)
4355 per_cpu(cpu_is_managed, policy->cpu) = 1;
4356 - *setspeed = policy->cur;
4358 + *setspeed = policy->cur;
4365 - unsigned int *setspeed = policy->governor_data;
4366 -
4367 pr_debug("managing cpu %u stopped\n", policy->cpu);
4370 per_cpu(cpu_is_managed, policy->cpu) = 0;
4371 - *setspeed = 0;
4375 diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
4377 --- a/drivers/cpuidle/driver.c
4379 @@ -381,3 +381,4 @@ void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
4384 diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
4386 --- a/drivers/cpuidle/governor.c
4388 @@ -102,6 +102,7 @@ int cpuidle_register_governor(struct cpuidle_governor *gov)
4395 * cpuidle_governor_latency_req - Compute a latency constraint for CPU
4396 @@ -118,3 +119,4 @@ s64 cpuidle_governor_latency_req(unsigned int cpu)
4401 diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
4403 --- a/drivers/devfreq/Kconfig
4405 @@ -131,15 +131,20 @@ config ARM_TEGRA20_DEVFREQ
4409 -config ARM_RK3399_DMC_DEVFREQ
4410 - tristate "ARM RK3399 DMC DEVFREQ Driver"
4421 select DEVFREQ_EVENT_ROCKCHIP_DFI
4422 - select DEVFREQ_GOV_SIMPLE_ONDEMAND
4423 select PM_DEVFREQ_EVENT
4425 - This adds the DEVFREQ driver for the RK3399 DMC(Dynamic Memory Controller).
4430 diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
4432 --- a/drivers/devfreq/Makefile
4434 @@ -11,9 +11,12 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o
4435 obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o
4436 obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o
4437 obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o
4438 -obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o
4439 +obj-$(CONFIG_ARM_ROCKCHIP_BUS_DEVFREQ) += rockchip_bus.o
4440 +obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ) += rockchip_dmc.o rockchip_dmc_common.o
4441 obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o
4442 obj-$(CONFIG_ARM_TEGRA20_DEVFREQ) += tegra20-devfreq.o
4445 obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
4447 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/gpu/drm/
4448 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
4450 --- a/drivers/devfreq/devfreq.c
4452 @@ -1763,6 +1763,40 @@ static ssize_t timer_store(struct device *dev, struct device_attribute *attr,
4461 + struct devfreq_dev_status stat = devfreq->last_status;
4480 + if (devfreq->profile->get_cur_freq &&
4481 + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
4484 + len += sprintf(buf + len, "@%luHz\n", devfreq->previous_freq);
4493 @@ -1775,6 +1809,7 @@ static struct attribute *devfreq_attrs[] = {
4501 diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig
4503 --- a/drivers/devfreq/event/Kconfig
4505 @@ -39,4 +39,11 @@ config DEVFREQ_EVENT_ROCKCHIP_DFI
4506 This add the devfreq-event driver for Rockchip SoC. It provides DFI
4513 + This add the devfreq-event driver for Rockchip SoC. It provides NoC
4517 diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile
4519 --- a/drivers/devfreq/event/Makefile
4521 @@ -4,3 +4,4 @@
4522 obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP) += exynos-nocp.o
4523 obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o
4524 obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI) += rockchip-dfi.o
4525 +obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP) += rockchip-nocp.o
4526 diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
4528 --- a/drivers/devfreq/event/rockchip-dfi.c
4529 +++ b/drivers/devfreq/event/rockchip-dfi.c
4530 @@ -20,23 +20,70 @@
4534 -#define RK3399_DMC_NUM_CH 2
4535 -
4572 -#define DDRMON_CTRL 0x04
4573 -#define CLR_DDRMON_CTRL (0x1f0000 << 0)
4574 -#define LPDDR4_EN (0x10001 << 4)
4575 -#define HARDWARE_EN (0x10001 << 3)
4576 -#define LPDDR3_EN (0x10001 << 2)
4577 -#define SOFTWARE_EN (0x10001 << 1)
4578 -#define SOFTWARE_DIS (0x10000 << 1)
4579 -#define TIME_CNT_EN (0x10001 << 0)
4611 @@ -50,33 +97,261 @@ struct dmc_usage {
4615 - struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
4635 + regmap_write(info->regmap_grf,
4644 + regmap_write(info->regmap_grf,
4679 + regmap_read(info->regmap_grf, RK3128_GRF_DFI_WRNUM, &dfi_wr);
4680 + regmap_read(info->regmap_grf, RK3128_GRF_DFI_RDNUM, &dfi_rd);
4681 + regmap_read(info->regmap_grf, RK3128_GRF_DFI_TIMERVAL, &dfi_timer);
4683 + edata->load_count = (dfi_wr + dfi_rd) * 4;
4684 + edata->total_count = dfi_timer;
4704 + regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_EN);
4711 + regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_DIS);
4744 + if (!(info->ch_msk & BIT(i)))
4746 + regmap_read(info->regmap_grf,
4748 + regmap_read(info->regmap_grf,
4750 + regmap_read(info->regmap_grf,
4752 + info->ch_usage[i].access = (wr_count + rd_count) * 4;
4753 + info->ch_usage[i].total = total_count;
4754 + tmp = info->ch_usage[i].access;
4776 + edata->load_count = info->ch_usage[busier_ch].access;
4777 + edata->total_count = info->ch_usage[busier_ch].total;
4793 + regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_EN);
4800 + regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_DIS);
4833 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS5, &dfi0_wr);
4834 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS6, &dfi0_rd);
4835 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS9, &dfi1_wr);
4836 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS10, &dfi1_rd);
4837 + regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS8, &dfi_timer);
4839 + edata->load_count = (dfi0_wr + dfi0_rd + dfi1_wr + dfi1_rd) * 2;
4840 + edata->total_count = dfi_timer;
4859 void __iomem *dfi_regs = info->regs;
4860 - u32 val;
4861 - u32 ddr_type;
4862 -
4863 - /* get ddr type */
4864 - regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
4865 - ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
4866 - RK3399_PMUGRF_DDRTYPE_MASK;
4872 - if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
4873 - writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
4874 - else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
4875 + if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
4877 + else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
4879 + else if (info->dram_type == DDR4)
4884 @@ -100,12 +375,22 @@ static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
4888 - for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
4889 - info->ch_usage[i].access = readl_relaxed(dfi_regs +
4890 - DDRMON_CH0_DFI_ACCESS_NUM + i * 20) * 4;
4892 + if (!(info->ch_msk & BIT(i)))
4895 info->ch_usage[i].total = readl_relaxed(dfi_regs +
4897 - tmp = info->ch_usage[i].access;
4902 + if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
4906 + info->ch_usage[i].access = tmp;
4911 @@ -121,7 +406,8 @@ static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
4915 - clk_disable_unprepare(info->clk);
4916 + if (info->clk)
4917 + clk_disable_unprepare(info->clk);
4921 @@ -131,10 +417,13 @@ static int rockchip_dfi_enable(struct devfreq_event_dev *edev)
4925 - ret = clk_prepare_enable(info->clk);
4926 - if (ret) {
4927 - dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret);
4928 - return ret;
4929 + if (info->clk) {
4930 + ret = clk_prepare_enable(info->clk);
4932 + dev_err(&edev->dev, "failed to enable dfi clk: %d\n",
4939 @@ -151,8 +440,11 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev *edev,
4949 edata->load_count = info->ch_usage[busier_ch].access;
4950 edata->total_count = info->ch_usage[busier_ch].total;
4951 @@ -167,22 +459,120 @@ static const struct devfreq_event_ops rockchip_dfi_ops = {
4955 -static const struct of_device_id rockchip_dfi_id_match[] = {
4956 - { .compatible = "rockchip,rk3399-dfi" },
4957 - { },
4958 -};
4959 -MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match);
4964 + struct device_node *np = pdev->dev.of_node, *node;
4968 -static int rockchip_dfi_probe(struct platform_device *pdev)
4970 + data->regs = devm_ioremap_resource(&pdev->dev, res);
4971 + if (IS_ERR(data->regs))
4972 + return PTR_ERR(data->regs);
4976 + data->regmap_pmugrf = syscon_node_to_regmap(node);
4977 + if (IS_ERR(data->regmap_pmugrf))
4978 + return PTR_ERR(data->regmap_pmugrf);
4981 + regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG2, &val_2);
4982 + regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG3, &val_3);
4984 + data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3);
4986 + data->dram_type = READ_DRAMTYPE_INFO(val_2);
4987 + data->ch_msk = 1;
4988 + data->clk = NULL;
4990 + desc->ops = &rockchip_dfi_ops;
4999 - struct device *dev = &pdev->dev;
5000 - struct rockchip_dfi *data;
5001 - struct devfreq_event_desc *desc;
5002 struct device_node *np = pdev->dev.of_node, *node;
5004 - data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL);
5005 - if (!data)
5006 - return -ENOMEM;
5009 + data->regmap_grf = syscon_node_to_regmap(node);
5010 + if (IS_ERR(data->regmap_grf))
5011 + return PTR_ERR(data->regmap_grf);
5014 + desc->ops = &rk3128_dfi_ops;
5023 + struct device_node *np = pdev->dev.of_node, *node;
5028 + data->regmap_pmu = syscon_node_to_regmap(node);
5029 + if (IS_ERR(data->regmap_pmu))
5030 + return PTR_ERR(data->regmap_pmu);
5035 + data->regmap_grf = syscon_node_to_regmap(node);
5036 + if (IS_ERR(data->regmap_grf))
5037 + return PTR_ERR(data->regmap_grf);
5040 + regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val);
5041 + data->dram_type = READ_DRAMTYPE_INFO(val);
5042 + data->ch_msk = READ_CH_INFO(val);
5044 + if (data->dram_type == DDR3)
5045 + regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
5048 + regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
5051 + desc->ops = &rk3288_dfi_ops;
5060 + struct device *dev = &pdev->dev;
5062 + if (!dev->parent || !dev->parent->of_node)
5063 + return -EINVAL;
5065 + data->regmap_grf = syscon_node_to_regmap(dev->parent->of_node);
5066 + if (IS_ERR(data->regmap_grf))
5067 + return PTR_ERR(data->regmap_grf);
5069 + desc->ops = &rk3368_dfi_ops;
5078 + struct device *dev = &pdev->dev;
5079 + struct device_node *np = pdev->dev.of_node, *node;
5082 data->regs = devm_platform_ioremap_resource(pdev, 0);
5083 if (IS_ERR(data->regs))
5084 @@ -202,23 +592,100 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
5085 if (IS_ERR(data->regmap_pmu))
5086 return PTR_ERR(data->regmap_pmu);
5088 - data->dev = dev;
5090 + regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val);
5091 + data->dram_type = READ_DRAMTYPE_INFO(val);
5092 + data->ch_msk = READ_CH_INFO(val);
5094 + desc->ops = &rockchip_dfi_ops;
5103 + struct device_node *np = pdev->dev.of_node, *node;
5108 + data->regs = devm_ioremap_resource(&pdev->dev, res);
5109 + if (IS_ERR(data->regs))
5110 + return PTR_ERR(data->regs);
5114 + data->regmap_grf = syscon_node_to_regmap(node);
5115 + if (IS_ERR(data->regmap_grf))
5116 + return PTR_ERR(data->regmap_grf);
5119 + regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val);
5120 + data->dram_type = READ_DRAMTYPE_INFO(val);
5121 + data->ch_msk = 1;
5122 + data->clk = NULL;
5124 + desc->ops = &rockchip_dfi_ops;
5130 + { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init },
5131 + { .compatible = "rockchip,rk1808-dfi", .data = px30_dfi_init },
5132 + { .compatible = "rockchip,rk3128-dfi", .data = rk3128_dfi_init },
5133 + { .compatible = "rockchip,rk3288-dfi", .data = rk3288_dfi_init },
5134 + { .compatible = "rockchip,rk3328-dfi", .data = rk3328_dfi_init },
5135 + { .compatible = "rockchip,rk3368-dfi", .data = rk3368_dfi_init },
5136 + { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init },
5137 + { .compatible = "rockchip,rk3568-dfi", .data = px30_dfi_init },
5138 + { .compatible = "rockchip,rv1126-dfi", .data = px30_dfi_init },
5144 + struct device *dev = &pdev->dev;
5147 + struct device_node *np = pdev->dev.of_node;
5154 + return -ENOMEM;
5158 return -ENOMEM;
5160 - desc->ops = &rockchip_dfi_ops;
5161 + match = of_match_node(rockchip_dfi_id_match, pdev->dev.of_node);
5163 + init = match->data;
5166 + return -EINVAL;
5174 desc->driver_data = data;
5175 desc->name = np->name;
5176 - data->desc = desc;
5178 - data->edev = devm_devfreq_event_add_edev(&pdev->dev, desc);
5179 + data->edev = devm_devfreq_event_add_edev(dev, desc);
5180 if (IS_ERR(data->edev)) {
5181 - dev_err(&pdev->dev,
5182 - "failed to add devfreq-event device\n");
5183 + dev_err(dev, "failed to add devfreq-event device\n");
5184 return PTR_ERR(data->edev);
5186 + data->desc = desc;
5187 + data->dev = &pdev->dev;
5191 diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig
5193 --- a/drivers/dma-buf/Kconfig
5194 +++ b/drivers/dma-buf/Kconfig
5195 @@ -21,7 +21,6 @@ config SW_SYNC
5199 - depends on DEBUG_FS
5203 @@ -80,7 +79,7 @@ menuconfig DMABUF_HEAPS
5206 bool "DMA-BUF sysfs statistics"
5207 - depends on DMA_SHARED_BUFFER
5208 + select DMA_SHARED_BUFFER
5210 Choose this option to enable DMA-BUF sysfs statistics
5212 diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.h b/drivers/dma-buf/dma-buf-sysfs-stats.h
5214 --- a/drivers/dma-buf/dma-buf-sysfs-stats.h
5215 +++ b/drivers/dma-buf/dma-buf-sysfs-stats.h
5216 @@ -14,8 +14,23 @@ int dma_buf_init_sysfs_statistics(void);
5225 + struct dma_buf_attach_sysfs_entry *entry = attach->sysfs_entry;
5227 + entry->map_counter += delta;
5233 + struct dma_buf_sysfs_entry *entry = dmabuf->sysfs_entry;
5235 + return entry->attachment_uid++;
5240 @@ -29,7 +44,19 @@ static inline int dma_buf_stats_setup(struct dma_buf *dmabuf)
5260 diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
5262 --- a/drivers/dma-buf/dma-buf.c
5263 +++ b/drivers/dma-buf/dma-buf.c
5264 @@ -32,8 +32,6 @@
5265 #include "dma-buf-sysfs-stats.h"
5266 #include "dma-buf-process-info.h"
5268 -static inline int is_dma_buf_file(struct file *);
5269 -
5273 @@ -41,6 +39,30 @@ struct dma_buf_list {
5304 @@ -129,6 +151,54 @@ static struct file_system_type dma_buf_fs_type = {
5311 + struct dma_buf *dmabuf = vma->vm_file->private_data;
5313 + dmabuf->mmap_count++;
5315 + if (dmabuf->exp_vm_ops->open)
5316 + dmabuf->exp_vm_ops->open(vma);
5321 + struct dma_buf *dmabuf = vma->vm_file->private_data;
5323 + if (dmabuf->mmap_count)
5324 + dmabuf->mmap_count--;
5326 + if (dmabuf->exp_vm_ops->close)
5327 + dmabuf->exp_vm_ops->close(vma);
5332 + /* call this first because the exporter might override vma->vm_ops */
5333 + int ret = dmabuf->ops->mmap(dmabuf, vma);
5339 + dmabuf->exp_vm_ops = vma->vm_ops;
5340 + dmabuf->vm_ops = *(dmabuf->exp_vm_ops);
5342 + dmabuf->vm_ops.open = dma_buf_vma_open;
5343 + dmabuf->vm_ops.close = dma_buf_vma_close;
5344 + vma->vm_ops = &dmabuf->vm_ops;
5345 + dmabuf->mmap_count++;
5352 + return dmabuf->ops->mmap(dmabuf, vma);
5359 @@ -147,7 +217,7 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
5360 dmabuf->size >> PAGE_SHIFT)
5361 return -EINVAL;
5363 - return dmabuf->ops->mmap(dmabuf, vma);
5368 @@ -442,10 +512,11 @@ static const struct file_operations dma_buf_fops = {
5370 * is_dma_buf_file - Check if struct file* is associated with dma_buf
5372 -static inline int is_dma_buf_file(struct file *file)
5375 return file->f_op == &dma_buf_fops;
5381 @@ -1132,6 +1203,30 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
5392 + return -EINVAL;
5394 + if (dmabuf->ops->begin_cpu_access_partial)
5395 + ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction,
5398 + /* Ensure that all fences are waited upon - but we first allow
5400 + * chooses. A double invocation here will be reasonably cheap no-op.
5410 * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the
5411 * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific
5412 @@ -1158,6 +1253,21 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf,
5424 + if (dmabuf->ops->end_cpu_access_partial)
5425 + ret = dmabuf->ops->end_cpu_access_partial(dmabuf, direction,
5433 * dma_buf_mmap - Setup up a userspace mmap with the given vma
5434 @@ -1286,6 +1396,32 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
5443 + return -EINVAL;
5445 + if (dmabuf->ops->get_flags)
5446 + ret = dmabuf->ops->get_flags(dmabuf, flags);
5455 + return -EINVAL;
5457 + if (!dmabuf->ops->get_uuid)
5458 + return -ENODEV;
5460 + return dmabuf->ops->get_uuid(dmabuf, uuid);
5467 diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
5469 --- a/drivers/dma-buf/dma-fence.c
5470 +++ b/drivers/dma-buf/dma-fence.c
5471 @@ -312,22 +312,25 @@ void __dma_fence_might_wait(void)
5475 - * dma_fence_signal_locked - signal completion of a fence
5476 + * dma_fence_signal_timestamp_locked - signal completion of a fence
5484 - * only be effective the first time.
5488 - * Unlike dma_fence_signal(), this function must be called with &dma_fence.lock
5489 - * held.
5496 -int dma_fence_signal_locked(struct dma_fence *fence)
5502 @@ -341,7 +344,7 @@ int dma_fence_signal_locked(struct dma_fence *fence)
5504 list_replace(&fence->cb_list, &cb_list);
5506 - fence->timestamp = ktime_get();
5507 + fence->timestamp = timestamp;
5508 set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
5511 @@ -352,6 +355,59 @@ int dma_fence_signal_locked(struct dma_fence *fence)
5518 + * dma_fence_signal_timestamp - signal completion of a fence
5538 + return -EINVAL;
5540 + spin_lock_irqsave(fence->lock, flags);
5542 + spin_unlock_irqrestore(fence->lock, flags);
5549 + * dma_fence_signal_locked - signal completion of a fence
5571 @@ -379,7 +435,7 @@ int dma_fence_signal(struct dma_fence *fence)
5574 spin_lock_irqsave(fence->lock, flags);
5575 - ret = dma_fence_signal_locked(fence);
5577 spin_unlock_irqrestore(fence->lock, flags);
5580 diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
5582 --- a/drivers/dma-buf/dma-heap.c
5583 +++ b/drivers/dma-buf/dma-heap.c
5584 @@ -31,6 +31,7 @@
5592 @@ -41,6 +42,8 @@ struct dma_heap {
5601 @@ -49,20 +52,72 @@ static dev_t dma_heap_devt;
5605 -static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
5606 - unsigned int fd_flags,
5607 - unsigned int heap_flags)
5614 + if (!strcmp(h->name, name)) {
5615 + kref_get(&h->refcount);
5637 + return ERR_PTR(-EINVAL);
5640 + return ERR_PTR(-EINVAL);
5647 - return -EINVAL;
5648 + return ERR_PTR(-EINVAL);
5650 return heap->ops->allocate(heap, len, fd_flags, heap_flags);
5678 @@ -90,15 +145,9 @@ static long dma_heap_ioctl_allocate(struct file *file, void *data)
5679 if (heap_allocation->fd)
5680 return -EINVAL;
5682 - if (heap_allocation->fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
5683 - return -EINVAL;
5684 -
5685 - if (heap_allocation->heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
5686 - return -EINVAL;
5687 -
5688 - fd = dma_heap_buffer_alloc(heap, heap_allocation->len,
5689 - heap_allocation->fd_flags,
5690 - heap_allocation->heap_flags);
5691 + fd = dma_heap_bufferfd_alloc(heap, heap_allocation->len,
5692 + heap_allocation->fd_flags,
5693 + heap_allocation->heap_flags);
5697 @@ -191,6 +240,47 @@ void *dma_heap_get_drvdata(struct dma_heap *heap)
5699 return heap->priv;
5706 + int minor = MINOR(heap->heap_devt);
5709 + list_del(&heap->list);
5711 + device_destroy(dma_heap_class, heap->heap_devt);
5712 + cdev_del(&heap->heap_cdev);
5725 + kref_put(&h->refcount, dma_heap_release);
5731 + * dma_heap_get_dev() - get device struct for the heap
5732 + * @heap: DMA-Heap to retrieve device struct from
5739 + return heap->heap_dev;
5744 * dma_heap_get_name() - get heap name
5745 @@ -203,11 +293,11 @@ const char *dma_heap_get_name(struct dma_heap *heap)
5747 return heap->name;
5753 - struct dma_heap *heap, *h, *err_ret;
5754 - struct device *dev_ret;
5759 @@ -221,10 +311,18 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
5760 return ERR_PTR(-EINVAL);
5763 + heap = dma_heap_find(exp_info->name);
5766 + exp_info->name);
5768 + return ERR_PTR(-EINVAL);
5772 return ERR_PTR(-ENOMEM);
5774 + kref_init(&heap->refcount);
5775 heap->name = exp_info->name;
5776 heap->ops = exp_info->ops;
5777 heap->priv = exp_info->priv;
5778 @@ -249,28 +347,20 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
5782 - dev_ret = device_create(dma_heap_class,
5783 - NULL,
5784 - heap->heap_devt,
5785 - NULL,
5786 - heap->name);
5787 - if (IS_ERR(dev_ret)) {
5788 + heap->heap_dev = device_create(dma_heap_class,
5790 + heap->heap_devt,
5792 + heap->name);
5793 + if (IS_ERR(heap->heap_dev)) {
5795 - err_ret = ERR_CAST(dev_ret);
5796 + err_ret = ERR_CAST(heap->heap_dev);
5800 - mutex_lock(&heap_list_lock);
5801 - /* check the name is unique */
5802 - list_for_each_entry(h, &heap_list, list) {
5803 - if (!strcmp(h->name, exp_info->name)) {
5804 - mutex_unlock(&heap_list_lock);
5805 - pr_err("dma_heap: Already registered heap named %s\n",
5806 - exp_info->name);
5807 - err_ret = ERR_PTR(-EINVAL);
5808 - goto err3;
5809 - }
5810 - }
5812 + heap->heap_dev = get_device(heap->heap_dev);
5816 list_add(&heap->list, &heap_list);
5817 @@ -288,27 +378,88 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
5836 + if (heap->ops->get_pool_size)
5837 + total_pool_size += heap->ops->get_pool_size(heap);
5862 + return -ENOMEM;
5882 - ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME);
5893 - unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS);
5894 - return PTR_ERR(dma_heap_class);
5898 dma_heap_class->devnode = dma_heap_devnode;
5910 diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
5912 --- a/drivers/dma-buf/heaps/Kconfig
5913 +++ b/drivers/dma-buf/heaps/Kconfig
5914 @@ -1,12 +1,22 @@
5916 + bool "DMA-BUF heaps deferred-free library"
5918 + Choose this option to enable the DMA-BUF heaps deferred-free library.
5921 + bool "DMA-BUF heaps page-pool library"
5923 + Choose this option to enable the DMA-BUF heaps page-pool library.
5926 - bool "DMA-BUF System Heap"
5927 - depends on DMABUF_HEAPS
5928 + tristate "DMA-BUF System Heap"
5935 - bool "DMA-BUF CMA Heap"
5936 + tristate "DMA-BUF CMA Heap"
5939 Choose this option to enable dma-buf CMA heap. This heap is backed
5940 diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
5942 --- a/drivers/dma-buf/heaps/Makefile
5943 +++ b/drivers/dma-buf/heaps/Makefile
5944 @@ -1,4 +1,5 @@
5945 # SPDX-License-Identifier: GPL-2.0
5946 -obj-y += heap-helpers.o
5947 +obj-$(CONFIG_DMABUF_HEAPS_DEFERRED_FREE) += deferred-free-helper.o
5948 +obj-$(CONFIG_DMABUF_HEAPS_PAGE_POOL) += page_pool.o
5949 obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
5950 obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
5951 diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
5953 --- a/drivers/dma-buf/heaps/cma_heap.c
5954 +++ b/drivers/dma-buf/heaps/cma_heap.c
5955 @@ -2,76 +2,304 @@
5959 - * Copyright (C) 2012, 2019 Linaro Ltd.
5961 * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
5964 + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
5967 -
5969 -#include <linux/device.h>
5970 #include <linux/dma-buf.h>
5971 #include <linux/dma-heap.h>
5972 #include <linux/dma-map-ops.h>
5974 -#include <linux/errno.h>
5979 -#include <linux/slab.h>
5981 -#include <linux/sched/signal.h>
5985 -#include "heap-helpers.h"
5992 -static void cma_heap_free(struct heap_helper_buffer *buffer)
6015 + struct cma_heap_buffer *buffer = dmabuf->priv;
6021 + return -ENOMEM;
6023 + ret = sg_alloc_table_from_pages(&a->table, buffer->pages,
6024 + buffer->pagecount, 0,
6025 + buffer->pagecount << PAGE_SHIFT,
6032 + a->dev = attachment->dev;
6033 + INIT_LIST_HEAD(&a->list);
6034 + a->mapped = false;
6036 + attachment->priv = a;
6038 + mutex_lock(&buffer->lock);
6039 + list_add(&a->list, &buffer->attachments);
6040 + mutex_unlock(&buffer->lock);
6048 + struct cma_heap_buffer *buffer = dmabuf->priv;
6049 + struct dma_heap_attachment *a = attachment->priv;
6051 + mutex_lock(&buffer->lock);
6052 + list_del(&a->list);
6053 + mutex_unlock(&buffer->lock);
6055 + sg_free_table(&a->table);
6062 - struct cma_heap *cma_heap = dma_heap_get_drvdata(buffer->heap);
6063 - unsigned long nr_pages = buffer->pagecount;
6064 - struct page *cma_pages = buffer->priv_virt;
6065 + struct dma_heap_attachment *a = attachment->priv;
6066 + struct sg_table *table = &a->table;
6069 + ret = dma_map_sgtable(attachment->dev, table, direction, 0);
6071 + return ERR_PTR(-ENOMEM);
6072 + a->mapped = true;
6080 + struct dma_heap_attachment *a = attachment->priv;
6082 + a->mapped = false;
6083 + dma_unmap_sgtable(attachment->dev, table, direction, 0);
6089 + struct cma_heap_buffer *buffer = dmabuf->priv;
6092 + if (buffer->vmap_cnt)
6093 + invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
6095 + mutex_lock(&buffer->lock);
6096 + list_for_each_entry(a, &buffer->attachments, list) {
6097 + if (!a->mapped)
6099 + dma_sync_sgtable_for_cpu(a->dev, &a->table, direction);
6101 + mutex_unlock(&buffer->lock);
6109 + struct cma_heap_buffer *buffer = dmabuf->priv;
6112 + if (buffer->vmap_cnt)
6113 + flush_kernel_vmap_range(buffer->vaddr, buffer->len);
6115 + mutex_lock(&buffer->lock);
6116 + list_for_each_entry(a, &buffer->attachments, list) {
6117 + if (!a->mapped)
6119 + dma_sync_sgtable_for_device(a->dev, &a->table, direction);
6121 + mutex_unlock(&buffer->lock);
6128 + struct vm_area_struct *vma = vmf->vma;
6129 + struct cma_heap_buffer *buffer = vma->vm_private_data;
6131 + if (vmf->pgoff > buffer->pagecount)
6134 + vmf->page = buffer->pages[vmf->pgoff];
6135 + get_page(vmf->page);
6146 + struct cma_heap_buffer *buffer = dmabuf->priv;
6148 + if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
6149 + return -EINVAL;
6151 + vma->vm_ops = &dma_heap_vm_ops;
6152 + vma->vm_private_data = buffer;
6161 + vaddr = vmap(buffer->pages, buffer->pagecount, VM_MAP, PAGE_KERNEL);
6163 + return ERR_PTR(-ENOMEM);
6170 + struct cma_heap_buffer *buffer = dmabuf->priv;
6173 + mutex_lock(&buffer->lock);
6174 + if (buffer->vmap_cnt) {
6175 + buffer->vmap_cnt++;
6176 + vaddr = buffer->vaddr;
6184 + buffer->vaddr = vaddr;
6185 + buffer->vmap_cnt++;
6187 + mutex_unlock(&buffer->lock);
6194 + struct cma_heap_buffer *buffer = dmabuf->priv;
6196 + mutex_lock(&buffer->lock);
6197 + if (!--buffer->vmap_cnt) {
6198 + vunmap(buffer->vaddr);
6199 + buffer->vaddr = NULL;
6201 + mutex_unlock(&buffer->lock);
6206 + struct cma_heap_buffer *buffer = dmabuf->priv;
6207 + struct cma_heap *cma_heap = buffer->heap;
6209 + if (buffer->vmap_cnt > 0) {
6211 + vunmap(buffer->vaddr);
6215 kfree(buffer->pages);
6217 - cma_release(cma_heap->cma, cma_pages, nr_pages);
6218 + cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount);
6222 -/* dmabuf heap CMA operations functions */
6223 -static int cma_heap_allocate(struct dma_heap *heap,
6224 - unsigned long len,
6225 - unsigned long fd_flags,
6226 - unsigned long heap_flags)
6246 - struct heap_helper_buffer *helper_buffer;
6247 - struct page *cma_pages;
6251 - unsigned long nr_pages = size >> PAGE_SHIFT;
6256 int ret = -ENOMEM;
6259 - if (align > CONFIG_CMA_ALIGNMENT)
6260 - align = CONFIG_CMA_ALIGNMENT;
6263 + return ERR_PTR(-ENOMEM);
6265 - helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
6266 - if (!helper_buffer)
6267 - return -ENOMEM;
6268 + INIT_LIST_HEAD(&buffer->attachments);
6269 + mutex_init(&buffer->lock);
6270 + buffer->len = size;
6272 - init_heap_helper_buffer(helper_buffer, cma_heap_free);
6273 - helper_buffer->heap = heap;
6274 - helper_buffer->size = len;
6278 - cma_pages = cma_alloc(cma_heap->cma, nr_pages, align, false);
6279 + cma_pages = cma_alloc(cma_heap->cma, pagecount, align, GFP_KERNEL);
6281 - goto free_buf;
6286 - unsigned long nr_clear_pages = nr_pages;
6291 @@ -85,7 +313,6 @@ static int cma_heap_allocate(struct dma_heap *heap,
6295 -
6297 nr_clear_pages--;
6299 @@ -93,44 +320,41 @@ static int cma_heap_allocate(struct dma_heap *heap,
6303 - helper_buffer->pagecount = nr_pages;
6304 - helper_buffer->pages = kmalloc_array(helper_buffer->pagecount,
6305 - sizeof(*helper_buffer->pages),
6306 - GFP_KERNEL);
6307 - if (!helper_buffer->pages) {
6308 + buffer->pages = kmalloc_array(pagecount, sizeof(*buffer->pages), GFP_KERNEL);
6309 + if (!buffer->pages) {
6310 ret = -ENOMEM;
6314 - for (pg = 0; pg < helper_buffer->pagecount; pg++)
6315 - helper_buffer->pages[pg] = &cma_pages[pg];
6317 + buffer->pages[pg] = &cma_pages[pg];
6319 + buffer->cma_pages = cma_pages;
6320 + buffer->heap = cma_heap;
6321 + buffer->pagecount = pagecount;
6324 - dmabuf = heap_helper_export_dmabuf(helper_buffer, fd_flags);
6327 + exp_info.size = buffer->len;
6336 - helper_buffer->dmabuf = dmabuf;
6337 - helper_buffer->priv_virt = cma_pages;
6338 -
6339 - ret = dma_buf_fd(dmabuf, fd_flags);
6340 - if (ret < 0) {
6341 - dma_buf_put(dmabuf);
6342 - /* just return, as put will call release and that will free */
6343 - return ret;
6344 - }
6345 -
6346 - return ret;
6350 - kfree(helper_buffer->pages);
6351 + kfree(buffer->pages);
6353 - cma_release(cma_heap->cma, cma_pages, nr_pages);
6354 -free_buf:
6355 - kfree(helper_buffer);
6356 - return ret;
6357 + cma_release(cma_heap->cma, cma_pages, pagecount);
6365 diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
6367 --- a/drivers/dma-buf/heaps/system_heap.c
6368 +++ b/drivers/dma-buf/heaps/system_heap.c
6369 @@ -3,7 +3,11 @@
6373 - * Copyright (C) 2019 Linaro Ltd.
6377 + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6381 #include <linux/dma-buf.h>
6382 @@ -15,99 +19,546 @@
6386 -#include <linux/sched/signal.h>
6387 -#include <asm/page.h>
6391 +#include "deferred-free-helper.h"
6415 -#include "heap-helpers.h"
6419 -struct dma_heap *sys_heap;
6435 -static void system_heap_free(struct heap_helper_buffer *buffer)
6438 - pgoff_t pg;
6443 - for (pg = 0; pg < buffer->pagecount; pg++)
6444 - __free_page(buffer->pages[pg]);
6445 - kfree(buffer->pages);
6446 - kfree(buffer);
6449 + return ERR_PTR(-ENOMEM);
6451 + ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL);
6454 + return ERR_PTR(-ENOMEM);
6457 + new_sg = new_table->sgl;
6459 + sg_set_page(new_sg, sg_page(sg), sg->length, sg->offset);
6466 -static int system_heap_allocate(struct dma_heap *heap,
6467 - unsigned long len,
6468 - unsigned long fd_flags,
6469 - unsigned long heap_flags)
6473 - struct heap_helper_buffer *helper_buffer;
6474 - struct dma_buf *dmabuf;
6475 - int ret = -ENOMEM;
6476 - pgoff_t pg;
6477 + struct system_heap_buffer *buffer = dmabuf->priv;
6483 + return -ENOMEM;
6485 - helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
6486 - if (!helper_buffer)
6487 + table = dup_sg_table(&buffer->sg_table);
6490 return -ENOMEM;
6493 + a->table = table;
6494 + a->dev = attachment->dev;
6495 + INIT_LIST_HEAD(&a->list);
6496 + a->mapped = false;
6497 + a->uncached = buffer->uncached;
6498 + attachment->priv = a;
6500 + mutex_lock(&buffer->lock);
6501 + list_add(&a->list, &buffer->attachments);
6502 + mutex_unlock(&buffer->lock);
6510 + struct system_heap_buffer *buffer = dmabuf->priv;
6511 + struct dma_heap_attachment *a = attachment->priv;
6513 + mutex_lock(&buffer->lock);
6514 + list_del(&a->list);
6515 + mutex_unlock(&buffer->lock);
6517 + sg_free_table(a->table);
6518 + kfree(a->table);
6522 - init_heap_helper_buffer(helper_buffer, system_heap_free);
6523 - helper_buffer->heap = heap;
6524 - helper_buffer->size = len;
6528 + struct dma_heap_attachment *a = attachment->priv;
6529 + struct sg_table *table = a->table;
6533 + if (a->uncached)
6536 + ret = dma_map_sgtable(attachment->dev, table, direction, attr);
6540 + a->mapped = true;
6548 + struct dma_heap_attachment *a = attachment->priv;
6551 + if (a->uncached)
6553 + a->mapped = false;
6554 + dma_unmap_sgtable(attachment->dev, table, direction, attr);
6557 - helper_buffer->pagecount = len / PAGE_SIZE;
6558 - helper_buffer->pages = kmalloc_array(helper_buffer->pagecount,
6559 - sizeof(*helper_buffer->pages),
6560 - GFP_KERNEL);
6561 - if (!helper_buffer->pages) {
6562 - ret = -ENOMEM;
6563 - goto err0;
6567 + struct system_heap_buffer *buffer = dmabuf->priv;
6570 + mutex_lock(&buffer->lock);
6572 + if (buffer->vmap_cnt)
6573 + invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
6575 + if (!buffer->uncached) {
6576 + list_for_each_entry(a, &buffer->attachments, list) {
6577 + if (!a->mapped)
6579 + dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
6582 + mutex_unlock(&buffer->lock);
6590 + struct system_heap_buffer *buffer = dmabuf->priv;
6593 + mutex_lock(&buffer->lock);
6595 + if (buffer->vmap_cnt)
6596 + flush_kernel_vmap_range(buffer->vaddr, buffer->len);
6598 + if (!buffer->uncached) {
6599 + list_for_each_entry(a, &buffer->attachments, list) {
6600 + if (!a->mapped)
6602 + dma_sync_sgtable_for_device(a->dev, a->table, direction);
6605 + mutex_unlock(&buffer->lock);
6612 + struct system_heap_buffer *buffer = dmabuf->priv;
6613 + struct sg_table *table = &buffer->sg_table;
6614 + unsigned long addr = vma->vm_start;
6618 + if (buffer->uncached)
6619 + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
6621 + for_each_sgtable_page(table, &piter, vma->vm_pgoff) {
6625 + vma->vm_page_prot);
6629 + if (addr >= vma->vm_end)
6637 + struct sg_table *table = &buffer->sg_table;
6638 + int npages = PAGE_ALIGN(buffer->len) / PAGE_SIZE;
6646 + return ERR_PTR(-ENOMEM);
6648 + if (buffer->uncached)
6652 + WARN_ON(tmp - pages >= npages);
6660 + return ERR_PTR(-ENOMEM);
6667 + struct system_heap_buffer *buffer = dmabuf->priv;
6670 + mutex_lock(&buffer->lock);
6671 + if (buffer->vmap_cnt) {
6672 + buffer->vmap_cnt++;
6673 + vaddr = buffer->vaddr;
6681 + buffer->vaddr = vaddr;
6682 + buffer->vmap_cnt++;
6684 + mutex_unlock(&buffer->lock);
6686 - for (pg = 0; pg < helper_buffer->pagecount; pg++) {
6692 + struct system_heap_buffer *buffer = dmabuf->priv;
6694 + mutex_lock(&buffer->lock);
6695 + if (!--buffer->vmap_cnt) {
6696 + vunmap(buffer->vaddr);
6697 + buffer->vaddr = NULL;
6699 + mutex_unlock(&buffer->lock);
6704 + struct sg_table *sgt = &buffer->sg_table;
6734 + table = &buffer->sg_table;
6735 + for_each_sg(table->sgl, sg, table->nents, i) {
6754 + struct system_heap_buffer *buffer = dmabuf->priv;
6755 + int npages = PAGE_ALIGN(buffer->len) / PAGE_SIZE;
6757 + deferred_free(&buffer->deferred_free, system_heap_buf_free, npages);
6807 + int i, ret = -ENOMEM;
6811 + return ERR_PTR(-ENOMEM);
6813 + INIT_LIST_HEAD(&buffer->attachments);
6814 + mutex_init(&buffer->lock);
6815 + buffer->heap = heap;
6816 + buffer->len = len;
6817 + buffer->uncached = uncached;
6824 - * has been killed by by SIGKILL
6828 - goto err1;
6835 + list_add_tail(&page->lru, &pages);
6836 + size_remaining -= page_size(page);
6841 - helper_buffer->pages[pg] = alloc_page(GFP_KERNEL | __GFP_ZERO);
6842 - if (!helper_buffer->pages[pg])
6843 - goto err1;
6844 + table = &buffer->sg_table;
6848 + sg = table->sgl;
6852 + list_del(&page->lru);
6856 - dmabuf = heap_helper_export_dmabuf(helper_buffer, fd_flags);
6859 + exp_info.size = buffer->len;
6865 - goto err1;
6875 + if (buffer->uncached) {
6880 - helper_buffer->dmabuf = dmabuf;
6883 - ret = dma_buf_fd(dmabuf, fd_flags);
6884 - if (ret < 0) {
6885 - dma_buf_put(dmabuf);
6886 - /* just return, as put will call release and that will free */
6887 - return ret;
6900 - return ret;
6904 -err1:
6905 - while (pg > 0)
6906 - __free_page(helper_buffer->pages[--pg]);
6907 - kfree(helper_buffer->pages);
6908 -err0:
6909 - kfree(helper_buffer);
6918 - return ret;
6927 + num_pages += ((*pool)->count[POOL_LOWPAGE] +
6928 + (*pool)->count[POOL_HIGHPAGE]) << (*pool)->order;
6953 + return ERR_PTR(-EBUSY);
6964 - int ret = 0;
6976 + return -ENOMEM;
6982 @@ -115,9 +566,21 @@ static int system_heap_create(void)
6986 - ret = PTR_ERR(sys_heap);
6989 - return ret;
6990 + exp_info.name = "system-uncached";
7006 diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
7008 --- a/drivers/dma-buf/sw_sync.c
7009 +++ b/drivers/dma-buf/sw_sync.c
7010 @@ -7,6 +7,8 @@
7019 @@ -410,3 +412,13 @@ const struct file_operations sw_sync_debugfs_fops = {
7033 diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c
7035 --- a/drivers/dma-buf/sync_debug.c
7036 +++ b/drivers/dma-buf/sync_debug.c
7037 @@ -8,6 +8,7 @@
7045 @@ -188,3 +189,4 @@ static __init int sync_debugfs_init(void)
7050 diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
7052 --- a/drivers/dma-buf/sync_debug.h
7053 +++ b/drivers/dma-buf/sync_debug.h
7054 @@ -62,11 +62,18 @@ struct sync_pt {
7073 diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
7075 --- a/drivers/firmware/Kconfig
7077 @@ -9,7 +9,7 @@ menu "Firmware Drivers"
7081 - depends on MAILBOX || HAVE_ARM_SMCCC_DISCOVERY
7085 set of operating system-independent software interfaces that are
7086 @@ -251,6 +251,13 @@ config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
7100 diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
7102 --- a/drivers/firmware/Makefile
7104 @@ -16,6 +16,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
7105 obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
7106 obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
7107 obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
7108 +obj-$(CONFIG_ROCKCHIP_SIP) += ../$(VENDOR_DRIVER_DIR)/firmware/
7109 obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
7110 obj-$(CONFIG_QCOM_SCM) += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
7111 obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o
7112 diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
7114 --- a/drivers/gpio/Kconfig
7116 @@ -495,6 +495,14 @@ config GPIO_REG
7117 A 32-bit single register GPIO fixed in/out implementation. This
7123 + select GPIOLIB_IRQCHIP
7131 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
7133 --- a/drivers/gpio/Makefile
7135 @@ -125,6 +125,7 @@ obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
7136 obj-$(CONFIG_GPIO_RDA) += gpio-rda.o
7137 obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
7138 obj-$(CONFIG_GPIO_REG) += gpio-reg.o
7139 +obj-$(CONFIG_GPIO_ROCKCHIP) += ../$(VENDOR_DRIVER_DIR)/gpio/
7140 obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
7141 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
7142 obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
7143 diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
7145 --- a/drivers/gpio/gpiolib-of.c
7146 +++ b/drivers/gpio/gpiolib-of.c
7147 @@ -1046,3 +1046,14 @@ void of_gpiochip_remove(struct gpio_chip *chip)
7149 of_node_put(chip->of_node);
7155 + if (gc->of_node)
7156 + gdev->dev.of_node = gc->of_node;
7158 + gc->of_node = gdev->dev.of_node;
7159 + if (gdev->dev.of_node)
7160 + gdev->dev.fwnode = of_fwnode_handle(gdev->dev.of_node);
7162 diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h
7164 --- a/drivers/gpio/gpiolib-of.h
7165 +++ b/drivers/gpio/gpiolib-of.h
7166 @@ -15,6 +15,7 @@ int of_gpiochip_add(struct gpio_chip *gc);
7174 @@ -33,6 +34,10 @@ static inline bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
7185 diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
7187 --- a/drivers/gpu/drm/Kconfig
7189 @@ -9,10 +9,10 @@ menuconfig DRM
7192 select DRM_PANEL_ORIENTATION_QUIRKS
7193 - select HDMI
7194 + select HDMI if !ROCKCHIP_MINI_KERNEL
7195 select FB_CMDLINE
7196 select I2C
7197 - select I2C_ALGOBIT
7198 + select I2C_ALGOBIT if !ROCKCHIP_MINI_KERNEL
7199 select DMA_SHARED_BUFFER
7200 select SYNC_FILE
7201 # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate
7202 @@ -31,10 +31,30 @@ config DRM_MIPI_DBI
7204 select DRM_KMS_HELPER
7233 diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
7235 --- a/drivers/gpu/drm/Makefile
7237 @@ -7,7 +7,7 @@ drm-y := drm_auth.o drm_cache.o \
7241 - drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \
7246 @@ -20,6 +20,7 @@ drm-y := drm_auth.o drm_cache.o \
7250 +drm-$(CONFIG_DRM_EDID) += drm_edid.o
7251 …drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm…
7252 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
7253 drm-$(CONFIG_DRM_VM) += drm_vm.o
7254 @@ -39,10 +40,10 @@ obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
7255 drm_ttm_helper-y := drm_gem_ttm_helper.o
7256 obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
7258 -drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
7259 +drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
7261 - drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
7262 - drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
7268 @@ -51,6 +52,8 @@ drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
7269 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
7270 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
7271 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
7272 +drm_kms_helper-$(CONFIG_DRM_DP) += drm_dp_helper.o drm_dp_mst_topology.o \
7274 drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
7275 drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
7277 diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
7279 --- a/drivers/gpu/drm/amd/display/Kconfig
7281 @@ -33,8 +33,6 @@ config DRM_AMD_DC_HDCP
7285 - depends on DRM_AMDGPU_SI
7286 - depends on DRM_AMD_DC
7290 diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
7292 --- a/drivers/gpu/drm/bridge/Kconfig
7294 @@ -126,6 +126,22 @@ config DRM_PARADE_PS8640
7295 The PS8640 is a high-performance and low-power
7302 + select DRM_KMS_HELPER
7309 + select DRM_KMS_HELPER
7310 + select MFD_RK1000
7317 diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
7319 --- a/drivers/gpu/drm/bridge/Makefile
7321 @@ -8,6 +8,8 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v
7322 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
7323 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
7324 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
7325 +obj-$(CONFIG_DRM_RK630_TVE) += rk630-tve.o
7326 +obj-$(CONFIG_DRM_RK1000_TVE) += rk1000.o
7327 obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
7328 obj-$(CONFIG_DRM_SII902X) += sii902x.o
7329 obj-$(CONFIG_DRM_SII9234) += sii9234.o
7330 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/a…
7332 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
7334 @@ -8,11 +8,13 @@
7338 +#include <linux/extcon-provider.h>
7348 @@ -35,11 +37,30 @@
7368 + req_bw = mode->clock * bpp / 8;
7379 @@ -64,6 +85,46 @@ static int analogix_dp_init_dp(struct analogix_dp_device *dp)
7387 + mutex_lock(&dp->panel_lock);
7389 + if (dp->panel_is_prepared)
7392 + ret = drm_panel_prepare(dp->plat_data->panel);
7396 + dp->panel_is_prepared = true;
7399 + mutex_unlock(&dp->panel_lock);
7407 + mutex_lock(&dp->panel_lock);
7409 + if (!dp->panel_is_prepared)
7412 + ret = drm_panel_unprepare(dp->plat_data->panel);
7416 + dp->panel_is_prepared = false;
7419 + mutex_unlock(&dp->panel_lock);
7426 @@ -108,6 +169,9 @@ static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
7430 + if (!device_property_read_bool(dp->dev, "support-psr"))
7433 ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version);
7435 dev_err(dp->dev, "failed to get PSR version, disable it\n");
7436 @@ -216,8 +280,24 @@ static int analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp)
7446 + ret = drm_dp_dpcd_readb(&dp->aux, DP_EDP_CONFIGURATION_CAP,
7456 + dp->link_train.enhanced_framing = data;
7461 @@ -233,32 +313,10 @@ static int analogix_dp_training_pattern_dis(struct analogix_dp_device *dp)
7465 -static void
7466 -analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp,
7467 - int pre_emphasis, int lane)
7468 -{
7469 - switch (lane) {
7470 - case 0:
7471 - analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
7472 - break;
7473 - case 1:
7474 - analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
7475 - break;
7476 -
7477 - case 2:
7478 - analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
7479 - break;
7480 -
7481 - case 3:
7482 - analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
7483 - break;
7484 - }
7485 -}
7486 -
7490 - int lane, lane_count, pll_tries, retval;
7493 lane_count = dp->link_train.lane_count;
7495 @@ -278,6 +336,14 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
7496 retval = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, 2);
7503 + retval = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, 2);
7510 @@ -285,22 +351,12 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
7514 - /* Set TX pre-emphasis to minimum */
7515 + /* Set TX voltage-swing and pre-emphasis to minimum */
7517 - analogix_dp_set_lane_lane_pre_emphasis(dp,
7518 - PRE_EMPHASIS_LEVEL_0, lane);
7519 -
7520 - /* Wait for PLL lock */
7521 - pll_tries = 0;
7522 - while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
7523 - if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
7524 - dev_err(dp->dev, "Wait for PLL lock timed out\n");
7525 - return -ETIMEDOUT;
7526 - }
7527 -
7528 - pll_tries++;
7529 - usleep_range(90, 120);
7530 - }
7531 + dp->link_train.training_lane[lane] =
7538 @@ -383,54 +439,6 @@ static unsigned char analogix_dp_get_adjust_request_pre_emphasis(
7542 -static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp,
7543 - u8 training_lane_set, int lane)
7544 -{
7545 - switch (lane) {
7546 - case 0:
7547 - analogix_dp_set_lane0_link_training(dp, training_lane_set);
7548 - break;
7549 - case 1:
7550 - analogix_dp_set_lane1_link_training(dp, training_lane_set);
7551 - break;
7552 -
7553 - case 2:
7554 - analogix_dp_set_lane2_link_training(dp, training_lane_set);
7555 - break;
7556 -
7557 - case 3:
7558 - analogix_dp_set_lane3_link_training(dp, training_lane_set);
7559 - break;
7560 - }
7561 -}
7562 -
7563 -static unsigned int
7564 -analogix_dp_get_lane_link_training(struct analogix_dp_device *dp,
7565 - int lane)
7566 -{
7567 - u32 reg;
7568 -
7569 - switch (lane) {
7570 - case 0:
7571 - reg = analogix_dp_get_lane0_link_training(dp);
7572 - break;
7573 - case 1:
7574 - reg = analogix_dp_get_lane1_link_training(dp);
7575 - break;
7576 - case 2:
7577 - reg = analogix_dp_get_lane2_link_training(dp);
7578 - break;
7579 - case 3:
7580 - reg = analogix_dp_get_lane3_link_training(dp);
7581 - break;
7582 - default:
7583 - WARN_ON(1);
7584 - return 0;
7585 - }
7586 -
7587 - return reg;
7588 -}
7589 -
7593 @@ -463,13 +471,27 @@ static void analogix_dp_get_adjust_training_lane(struct analogix_dp_device *d…
7603 + dp->video_info.max_link_rate == DP_LINK_BW_5_4;
7604 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &dpcd);
7617 - usleep_range(100, 101);
7618 + drm_dp_link_train_clock_recovery_delay(dp->dpcd);
7620 lane_count = dp->link_train.lane_count;
7622 @@ -483,12 +505,16 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
7626 - /* set training pattern 2 for EQ */
7627 - analogix_dp_set_training_pattern(dp, TRAINING_PTN2);
7634 retval = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
7636 - DP_TRAINING_PATTERN_2);
7642 @@ -522,10 +548,7 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
7646 -
7647 - for (lane = 0; lane < lane_count; lane++)
7648 - analogix_dp_set_lane_link_training(dp,
7649 - dp->link_train.training_lane[lane], lane);
7652 retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
7653 dp->link_train.training_lane, lane_count);
7654 @@ -537,11 +560,11 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
7658 - int lane, lane_count, retval;
7663 - usleep_range(400, 401);
7664 + drm_dp_link_train_channel_eq_delay(dp->dpcd);
7666 lane_count = dp->link_train.lane_count;
7668 @@ -597,9 +620,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
7669 return -EIO;
7672 - for (lane = 0; lane < lane_count; lane++)
7673 - analogix_dp_set_lane_link_training(dp,
7674 - dp->link_train.training_lane[lane], lane);
7677 retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
7678 dp->link_train.training_lane, lane_count);
7679 @@ -609,10 +630,11 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *…
7683 -static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
7684 - u8 *bandwidth)
7693 @@ -620,28 +642,41 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
7697 - drm_dp_dpcd_readb(&dp->aux, DP_MAX_LINK_RATE, &data);
7698 + ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LINK_RATE, &data);
7707 -static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp,
7708 - u8 *lane_count)
7719 - drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data);
7720 + ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data);
7732 + struct video_info *video = &dp->video_info;
7739 @@ -667,6 +702,16 @@ static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
7740 dp->link_train.lane_count = (u8)LANE_COUNT1;
7743 + if (!analogix_dp_bandwidth_ok(dp, &video->mode,
7744 + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate),
7745 + dp->link_train.lane_count)) {
7746 + dev_err(dp->dev, "bandwidth overflow\n");
7747 + return -EINVAL;
7750 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &dpcd);
7751 + dp->link_train.ssc = !!(dpcd & DP_MAX_DOWNSPREAD_0_5);
7754 if (dp->link_train.lane_count > max_lanes)
7755 dp->link_train.lane_count = max_lanes;
7756 @@ -711,27 +756,15 @@ static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
7760 - int i, ret;
7763 - enum pll_status status;
7767 analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
7768 analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
7769 -
7770 - for (i = 0; i < dp->link_train.lane_count; i++) {
7771 - analogix_dp_set_lane_link_training(dp,
7772 - dp->link_train.training_lane[i], i);
7773 - }
7774 -
7775 - ret = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status,
7776 - status != PLL_UNLOCKED, 120,
7777 - 120 * DP_TIMEOUT_LOOP_COUNT);
7778 - if (ret) {
7779 - DRM_DEV_ERROR(dp->dev, "Wait for pll lock failed %d\n", ret);
7780 - return ret;
7781 - }
7783 + analogix_dp_enable_enhanced_mode(dp, dp->link_train.enhanced_framing);
7787 @@ -742,7 +775,6 @@ static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
7788 /* From DP spec, pattern must be on-screen for a minimum 500us */
7791 - /* TODO: enhanced_mode?*/
7795 @@ -884,38 +916,21 @@ static int analogix_dp_enable_scramble(struct analogix_dp_device *dp,
7799 -static irqreturn_t analogix_dp_hardirq(int irq, void *arg)
7803 - irqreturn_t ret = IRQ_NONE;
7804 - enum dp_irq_type irq_type;
7806 - irq_type = analogix_dp_get_irq_type(dp);
7807 - if (irq_type != DP_IRQ_TYPE_UNKNOWN) {
7808 - analogix_dp_mute_hpd_interrupt(dp);
7809 - ret = IRQ_WAKE_THREAD;
7810 - }
7811 + if (dp->drm_dev)
7812 + drm_helper_hpd_irq_event(dp->drm_dev);
7814 - return ret;
7821 - enum dp_irq_type irq_type;
7823 - irq_type = analogix_dp_get_irq_type(dp);
7824 - if (irq_type & DP_IRQ_TYPE_HP_CABLE_IN ||
7825 - irq_type & DP_IRQ_TYPE_HP_CABLE_OUT) {
7826 - dev_dbg(dp->dev, "Detected cable status changed!\n");
7827 - if (dp->drm_dev)
7828 - drm_helper_hpd_irq_event(dp->drm_dev);
7829 - }
7830 -
7831 - if (irq_type != DP_IRQ_TYPE_UNKNOWN) {
7832 - analogix_dp_clear_hotplug_interrupts(dp);
7833 - analogix_dp_unmute_hpd_interrupt(dp);
7834 - }
7839 @@ -936,16 +951,73 @@ static int analogix_dp_fast_link_train_detection(struct analogix_dp_device *d…
7848 + if (dp->dpcd[DP_DPCD_REV] < 0x11)
7851 + ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value);
7858 + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value);
7872 + if (dp->dpcd[DP_DPCD_REV] < 0x11)
7875 + ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value);
7882 + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value);
7891 + struct video_info *video = &dp->video_info;
7894 - /* Keep the panel disabled while we configure video */
7895 - if (dp->plat_data->panel) {
7896 - if (drm_panel_disable(dp->plat_data->panel))
7897 - DRM_ERROR("failed to disable the panel\n");
7898 + ret = drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd);
7900 + dev_err(dp->dev, "failed to read dpcd caps: %d\n", ret);
7906 + dev_err(dp->dev, "failed to power up link: %d\n", ret);
7910 + if (device_property_read_bool(dp->dev, "panel-self-test"))
7911 + return drm_dp_dpcd_writeb(&dp->aux, DP_EDP_CONFIGURATION_SET,
7916 dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
7917 @@ -959,21 +1031,17 @@ static int analogix_dp_commit(struct analogix_dp_device *dp)
7923 + if (video->video_bist_enable)
7928 dev_err(dp->dev, "unable to config video\n");
7932 - /* Safe to enable the panel now */
7933 - if (dp->plat_data->panel) {
7934 - ret = drm_panel_enable(dp->plat_data->panel);
7935 - if (ret) {
7936 - DRM_ERROR("failed to enable the panel\n");
7937 - return ret;
7938 - }
7939 - }
7940 -
7944 @@ -1010,9 +1078,20 @@ static int analogix_dp_enable_psr(struct analogix_dp_device *dp)
7948 - if (!ret)
7952 + if (dp->phy) {
7957 + ret = phy_configure(dp->phy, &phy_cfg);
7966 @@ -1058,70 +1137,24 @@ static int analogix_dp_disable_psr(struct analogix_dp_device *dp)
7970 -/*
7971 - * This function is a bit of a catch-all for panel preparation, hopefully
7972 - * simplifying the logic of functions that need to prepare/unprepare the panel
7973 - * below.
7974 - *
7975 - * If @prepare is true, this function will prepare the panel. Conversely, if it
7976 - * is false, the panel will be unprepared.
7977 - *
7978 - * If @is_modeset_prepare is true, the function will disregard the current state
7979 - * of the panel and either prepare/unprepare the panel based on @prepare. Once
7980 - * it finishes, it will update dp->panel_is_modeset to reflect the current state
7981 - * of the panel.
7982 - */
7983 -static int analogix_dp_prepare_panel(struct analogix_dp_device *dp,
7984 - bool prepare, bool is_modeset_prepare)
7985 -{
7986 - int ret = 0;
7987 -
7988 - if (!dp->plat_data->panel)
7989 - return 0;
7990 -
7991 - mutex_lock(&dp->panel_lock);
7992 -
7993 - /*
7994 - * Exit early if this is a temporary prepare/unprepare and we're already
7995 - * modeset (since we neither want to prepare twice or unprepare early).
7996 - */
7997 - if (dp->panel_is_modeset && !is_modeset_prepare)
7998 - goto out;
7999 -
8000 - if (prepare)
8001 - ret = drm_panel_prepare(dp->plat_data->panel);
8002 - else
8003 - ret = drm_panel_unprepare(dp->plat_data->panel);
8004 -
8005 - if (ret)
8006 - goto out;
8007 -
8008 - if (is_modeset_prepare)
8009 - dp->panel_is_modeset = prepare;
8010 -
8011 -out:
8012 - mutex_unlock(&dp->panel_lock);
8013 - return ret;
8014 -}
8015 -
8022 - if (dp->plat_data->panel) {
8023 + if (dp->plat_data->panel)
8024 num_modes += drm_panel_get_modes(dp->plat_data->panel, connector);
8025 - } else {
8026 - ret = analogix_dp_prepare_panel(dp, true, false);
8027 - if (ret) {
8028 - DRM_ERROR("Failed to prepare panel (%d)\n", ret);
8034 - }
8036 - pm_runtime_get_sync(dp->dev);
8037 + if (dp->plat_data->panel)
8040 edid = drm_get_edid(connector, &dp->aux.ddc);
8041 - pm_runtime_put(dp->dev);
8043 drm_connector_update_edid_property(&dp->connector,
8045 @@ -1129,14 +1162,19 @@ static int analogix_dp_get_modes(struct drm_connector *connector)
8049 - ret = analogix_dp_prepare_panel(dp, false, false);
8050 - if (ret)
8051 - DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
8055 if (dp->plat_data->get_modes)
8056 num_modes += dp->plat_data->get_modes(dp->plat_data, connector);
8058 + if (num_modes > 0 && dp->plat_data->split_mode) {
8061 + list_for_each_entry(mode, &connector->probed_modes, head)
8062 + dp->plat_data->convert_to_split_mode(mode);
8068 @@ -1182,38 +1220,76 @@ static const struct drm_connector_helper_funcs analogix_dp_connector_helper…
8072 -analogix_dp_detect(struct drm_connector *connector, bool force)
8075 - struct analogix_dp_device *dp = to_dp(connector);
8079 - if (dp->plat_data->panel)
8080 - return connector_status_connected;
8081 -
8082 - ret = analogix_dp_prepare_panel(dp, true, false);
8085 - DRM_ERROR("Failed to prepare panel (%d)\n", ret);
8086 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
8090 - if (!analogix_dp_detect_hpd(dp))
8091 + if (dp->plat_data->panel)
8095 + ret = analogix_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
8097 + dev_err(dp->dev, "failed to read max link rate\n");
8101 + ret = analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
8103 + dev_err(dp->dev, "failed to read max lane count\n");
8110 - ret = analogix_dp_prepare_panel(dp, false, false);
8111 - if (ret)
8112 - DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
8117 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true);
8119 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
8129 + if (dp->plat_data->right && analogix_dp_detect(dp->plat_data->right) != connector_status_connecte…
8139 + if (connector->status == connector_status_connected)
8140 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true);
8142 + extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
8147 - .detect = analogix_dp_detect,
8157 @@ -1224,10 +1300,8 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
8161 - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
8162 - DRM_ERROR("Fix bridge driver to make connector optional!");
8163 - return -EINVAL;
8164 - }
8168 if (!bridge->encoder) {
8170 @@ -1240,6 +1314,8 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
8172 ret = drm_connector_init(dp->drm_dev, connector,
8174 + dp->plat_data->bridge ?
8175 + dp->plat_data->bridge->type :
8179 @@ -1268,6 +1344,14 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
8185 + struct analogix_dp_device *dp = bridge->driver_private;
8187 + if (dp->plat_data->detach)
8188 + dp->plat_data->detach(dp->plat_data, bridge);
8194 @@ -1291,7 +1375,8 @@ static
8198 - struct drm_encoder *encoder = dp->encoder;
8199 + struct drm_bridge *bridge = &dp->bridge;
8200 + struct drm_encoder *encoder = bridge->encoder;
8204 @@ -1314,7 +1399,6 @@ analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
8205 struct analogix_dp_device *dp = bridge->driver_private;
8208 - int ret;
8212 @@ -1325,27 +1409,20 @@ analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
8213 if (old_crtc_state && old_crtc_state->self_refresh_active)
8216 - ret = analogix_dp_prepare_panel(dp, true, true);
8217 - if (ret)
8218 - DRM_ERROR("failed to setup the panel ret = %d\n", ret);
8219 + if (dp->plat_data->panel)
8227 - pm_runtime_get_sync(dp->dev);
8228 -
8229 - ret = clk_prepare_enable(dp->clock);
8230 - if (ret < 0) {
8231 - DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
8232 - goto out_dp_clk_pre;
8233 - }
8234 -
8235 if (dp->plat_data->power_on_start)
8236 dp->plat_data->power_on_start(dp->plat_data);
8238 - phy_power_on(dp->phy);
8245 @@ -1363,28 +1440,35 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
8249 - if (ret) {
8255 + if (dp->plat_data->panel)
8256 + drm_panel_enable(dp->plat_data->panel);
8258 if (dp->plat_data->power_on_end)
8259 dp->plat_data->power_on_end(dp->plat_data);
8261 - enable_irq(dp->irq);
8265 - phy_power_off(dp->phy);
8267 if (dp->plat_data->power_off)
8268 dp->plat_data->power_off(dp->plat_data);
8269 - clk_disable_unprepare(dp->clock);
8270 -out_dp_clk_pre:
8271 - pm_runtime_put_sync(dp->dev);
8272 -
8282 + drm_kms_helper_hotplug_event(dp->bridge.dev);
8288 @@ -1423,12 +1507,14 @@ analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge,
8291 dev_err(dp->dev, "too many times retry set bridge, give it up\n");
8294 + schedule_work(&dp->modeset_retry_work);
8299 struct analogix_dp_device *dp = bridge->driver_private;
8300 - int ret;
8302 if (dp->dpms_mode != DRM_MODE_DPMS_ON)
8304 @@ -1440,21 +1526,17 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
8308 - disable_irq(dp->irq);
8312 if (dp->plat_data->power_off)
8313 dp->plat_data->power_off(dp->plat_data);
8316 - phy_power_off(dp->phy);
8317 -
8318 - clk_disable_unprepare(dp->clock);
8319 -
8320 - pm_runtime_put_sync(dp->dev);
8323 - ret = analogix_dp_prepare_panel(dp, false, true);
8324 - if (ret)
8325 - DRM_ERROR("failed to setup the panel ret = %d\n", ret);
8326 + if (dp->plat_data->panel)
8329 dp->fast_train_enable = false;
8330 dp->psr_supported = false;
8331 @@ -1526,14 +1608,19 @@ analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge,
8335 - const struct drm_display_mode *mode)
8338 struct analogix_dp_device *dp = bridge->driver_private;
8339 struct drm_display_info *display_info = &dp->connector.display_info;
8340 struct video_info *video = &dp->video_info;
8341 + struct drm_display_mode *mode = &video->mode;
8342 struct device_node *dp_node = dp->dev->of_node;
8346 + if (dp->plat_data->split_mode)
8347 + dp->plat_data->convert_to_origin_mode(mode);
8350 video->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
8351 video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
8352 @@ -1542,16 +1629,12 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
8356 - (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) {
8358 video->dynamic_range = CEA;
8359 - video->ycbcr_coeff = COLOR_YCBCR601;
8360 - } else if (vic) {
8362 video->dynamic_range = CEA;
8363 - video->ycbcr_coeff = COLOR_YCBCR709;
8364 - } else {
8366 video->dynamic_range = VESA;
8367 - video->ycbcr_coeff = COLOR_YCBCR709;
8368 - }
8371 switch (display_info->bpc) {
8372 @@ -1571,12 +1654,16 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
8373 video->color_depth = COLOR_8;
8376 - if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
8377 + if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB444) {
8378 video->color_space = COLOR_YCBCR444;
8379 - else if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
8380 + video->ycbcr_coeff = COLOR_YCBCR709;
8381 + } else if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422) {
8382 video->color_space = COLOR_YCBCR422;
8383 - else
8384 + video->ycbcr_coeff = COLOR_YCBCR709;
8386 video->color_space = COLOR_RGB;
8387 + video->ycbcr_coeff = COLOR_YCBCR601;
8392 @@ -1601,6 +1688,56 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
8393 video->interlaced = true;
8424 + struct analogix_dp_device *dp = bridge->driver_private;
8430 + if (dp->plat_data->split_mode)
8431 + dp->plat_data->convert_to_origin_mode(&m);
8433 + max_link_rate = min_t(u32, dp->video_info.max_link_rate,
8434 + dp->link_train.link_rate);
8435 + max_lane_count = min_t(u32, dp->video_info.max_lane_count,
8436 + dp->link_train.lane_count);
8449 @@ -1611,29 +1748,30 @@ static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
8457 -static int analogix_dp_create_bridge(struct drm_device *drm_dev,
8458 - struct analogix_dp_device *dp)
8461 - struct drm_bridge *bridge;
8462 + struct drm_bridge *bridge = &dp->bridge;
8465 - bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
8466 - if (!bridge) {
8467 - DRM_ERROR("failed to allocate for drm bridge\n");
8468 - return -ENOMEM;
8469 + if (!dp->plat_data->left) {
8470 + ret = drm_bridge_attach(dp->encoder, bridge, NULL, 0);
8477 - dp->bridge = bridge;
8478 -
8479 - bridge->driver_private = dp;
8480 - bridge->funcs = &analogix_dp_bridge_funcs;
8481 + if (dp->plat_data->right) {
8482 + struct analogix_dp_device *secondary = dp->plat_data->right;
8484 - ret = drm_bridge_attach(dp->encoder, bridge, NULL, 0);
8485 - if (ret) {
8486 - DRM_ERROR("failed to attach drm bridge\n");
8487 - return -EINVAL;
8488 + ret = drm_bridge_attach(dp->encoder, &secondary->bridge, bridge,
8495 @@ -1643,10 +1781,11 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
8497 struct device_node *dp_node = dp->dev->of_node;
8498 struct video_info *video_info = &dp->video_info;
8502 switch (dp->plat_data->dev_type) {
8504 - case RK3399_EDP:
8508 @@ -1654,6 +1793,10 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
8509 video_info->max_link_rate = 0x0A;
8510 video_info->max_lane_count = 0x04;
8513 + video_info->max_link_rate = 0x14;
8514 + video_info->max_lane_count = 0x04;
8519 @@ -1666,6 +1809,35 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
8523 + video_info->video_bist_enable =
8524 + of_property_read_bool(dp_node, "analogix,video-bist-enable");
8526 + prop = of_find_property(dp_node, "data-lanes", &len);
8528 + video_info->lane_map[0] = 0;
8529 + video_info->lane_map[1] = 1;
8530 + video_info->lane_map[2] = 2;
8531 + video_info->lane_map[3] = 3;
8532 + DRM_DEV_DEBUG(dp->dev, "failed to find data lane mapping, using default\n");
8539 + DRM_DEV_ERROR(dp->dev, "bad number of data lanes\n");
8540 + return -EINVAL;
8543 + video_info->max_lane_count = num_lanes;
8545 + ret = of_property_read_u32_array(dp_node, "data-lanes",
8546 + video_info->lane_map, num_lanes);
8548 + DRM_DEV_ERROR(dp->dev, "failed to read lane data\n");
8555 @@ -1673,20 +1845,96 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux,
8567 + switch (daifmt->fmt) {
8575 + DRM_DEV_ERROR(dp->dev, "invalid daifmt %d\n", daifmt->fmt);
8576 + return -EINVAL;
8599 + memcpy(buf, dp->connector.eld, min(sizeof(dp->connector.eld), len));
8612 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &spread);
8614 + dp->link_train.link_rate = link_rate;
8615 + dp->link_train.lane_count = lane_count;
8616 + dp->link_train.enhanced_framing = analogix_dp_get_enhanced_mode(dp);
8617 + dp->link_train.ssc = !!(spread & DP_MAX_DOWNSPREAD_0_5);
8620 + dp->link_train.training_lane[lane] =
8628 - pm_runtime_get_sync(dp->dev);
8633 - ret = analogix_dp_detect_hpd(dp);
8634 + dp->dpms_mode = DRM_MODE_DPMS_ON;
8640 - goto out;
8643 - ret = analogix_dp_transfer(dp, msg);
8644 -out:
8645 - pm_runtime_put(dp->dev);
8652 - return ret;
8659 @@ -1694,7 +1942,6 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
8663 - unsigned int irq_flags;
8667 @@ -1708,9 +1955,10 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_dat…
8669 dp->dev = &pdev->dev;
8670 dp->dpms_mode = DRM_MODE_DPMS_OFF;
8671 + INIT_WORK(&dp->modeset_retry_work, analogix_dp_modeset_retry_work_fn);
8673 mutex_init(&dp->panel_lock);
8674 - dp->panel_is_modeset = false;
8675 + dp->panel_is_prepared = false;
8679 @@ -1739,21 +1987,19 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_da…
8683 - dp->clock = devm_clk_get(&pdev->dev, "dp");
8684 - if (IS_ERR(dp->clock)) {
8685 - dev_err(&pdev->dev, "failed to get clock\n");
8686 - return ERR_CAST(dp->clock);
8687 + ret = devm_clk_bulk_get_all(dev, &dp->clks);
8693 - clk_prepare_enable(dp->clock);
8694 + dp->nr_clks = ret;
8698 dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
8699 - if (IS_ERR(dp->reg_base)) {
8700 - ret = PTR_ERR(dp->reg_base);
8701 - goto err_disable_clk;
8702 - }
8703 + if (IS_ERR(dp->reg_base))
8704 + return ERR_CAST(dp->reg_base);
8706 dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
8708 @@ -1765,46 +2011,55 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_da…
8709 if (IS_ERR(dp->hpd_gpiod)) {
8711 PTR_ERR(dp->hpd_gpiod));
8712 - ret = PTR_ERR(dp->hpd_gpiod);
8713 - goto err_disable_clk;
8714 + return ERR_CAST(dp->hpd_gpiod);
8717 if (dp->hpd_gpiod) {
8718 - /*
8719 - * Set up the hotplug GPIO from the device tree as an interrupt.
8720 - * Simply specifying a different interrupt in the device tree
8721 - * doesn't work since we handle hotplug rather differently when
8722 - * using a GPIO. We also need the actual GPIO specifier so
8723 - * that we can get the current state of the GPIO.
8724 - */
8725 - dp->irq = gpiod_to_irq(dp->hpd_gpiod);
8726 - irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
8727 - } else {
8728 - dp->irq = platform_get_irq(pdev, 0);
8729 - irq_flags = 0;
8731 + gpiod_to_irq(dp->hpd_gpiod),
8737 + "analogix-hpd", dp);
8744 + dp->irq = platform_get_irq(pdev, 0);
8745 if (dp->irq == -ENXIO) {
8746 dev_err(&pdev->dev, "failed to get irq\n");
8747 - ret = -ENODEV;
8748 - goto err_disable_clk;
8749 + return ERR_PTR(-ENODEV);
8752 - ret = devm_request_threaded_irq(&pdev->dev, dp->irq,
8753 - analogix_dp_hardirq,
8754 + irq_set_status_flags(dp->irq, IRQ_NOAUTOEN);
8755 + ret = devm_request_threaded_irq(dev, dp->irq, NULL,
8757 - irq_flags, "analogix-dp", dp);
8760 dev_err(&pdev->dev, "failed to request irq\n");
8761 - goto err_disable_clk;
8764 - disable_irq(dp->irq);
8766 - return dp;
8767 + dp->extcon = devm_extcon_dev_allocate(dev, analogix_dp_cable);
8768 + if (IS_ERR(dp->extcon)) {
8770 + return ERR_CAST(dp->extcon);
8773 + ret = devm_extcon_dev_register(dev, dp->extcon);
8779 + dp->bridge.driver_private = dp;
8780 + dp->bridge.funcs = &analogix_dp_bridge_funcs;
8782 -err_disable_clk:
8783 - clk_disable_unprepare(dp->clock);
8784 - return ERR_PTR(ret);
8789 @@ -1824,16 +2079,21 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_…
8792 pm_runtime_enable(dp->dev);
8793 + pm_runtime_get_sync(dp->dev);
8796 - ret = analogix_dp_create_bridge(drm_dev, dp);
8799 - DRM_ERROR("failed to create bridge (%d)\n", ret);
8804 + enable_irq(dp->irq);
8809 + pm_runtime_put(dp->dev);
8810 pm_runtime_disable(dp->dev);
8813 @@ -1842,47 +2102,50 @@ EXPORT_SYMBOL_GPL(analogix_dp_bind);
8817 - analogix_dp_bridge_disable(dp->bridge);
8818 + disable_irq(dp->irq);
8819 dp->connector.funcs->destroy(&dp->connector);
8820 -
8821 - if (dp->plat_data->panel) {
8822 - if (drm_panel_unprepare(dp->plat_data->panel))
8823 - DRM_ERROR("failed to turnoff the panel\n");
8824 - }
8825 -
8826 drm_dp_aux_unregister(&dp->aux);
8827 + pm_runtime_put(dp->dev);
8828 pm_runtime_disable(dp->dev);
8834 - clk_disable_unprepare(dp->clock);
8835 + cancel_work_sync(&dp->modeset_retry_work);
8839 -#ifdef CONFIG_PM
8842 - clk_disable_unprepare(dp->clock);
8843 + pm_runtime_force_suspend(dp->dev);
8851 - int ret;
8852 -
8853 - ret = clk_prepare_enable(dp->clock);
8854 - if (ret < 0) {
8855 - DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
8856 - return ret;
8857 - }
8858 + pm_runtime_force_resume(dp->dev);
8864 -#endif
8868 + clk_bulk_disable_unprepare(dp->nr_clks, dp->clks);
8876 + return clk_bulk_prepare_enable(dp->nr_clks, dp->clks);
8882 @@ -1909,3 +2172,4 @@ EXPORT_SYMBOL_GPL(analogix_dp_stop_crc);
8887 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/a…
8889 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
8891 @@ -10,6 +10,7 @@
8899 @@ -69,6 +70,7 @@ enum pattern_set {
8907 @@ -120,15 +122,9 @@ enum analog_power_block {
8911 -enum dp_irq_type {
8912 - DP_IRQ_TYPE_HP_CABLE_IN = BIT(0),
8913 - DP_IRQ_TYPE_HP_CABLE_OUT = BIT(1),
8914 - DP_IRQ_TYPE_HP_CHANGE = BIT(2),
8915 - DP_IRQ_TYPE_UNKNOWN = BIT(3),
8916 -};
8917 -
8924 @@ -141,6 +137,9 @@ struct video_info {
8934 @@ -150,6 +149,8 @@ struct link_train {
8943 @@ -159,9 +160,10 @@ struct analogix_dp_device {
8947 - struct drm_bridge *bridge;
8950 - struct clk *clock;
8956 @@ -173,17 +175,19 @@ struct analogix_dp_device {
8963 - bool panel_is_modeset;
8974 -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable);
8978 @@ -199,7 +203,6 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
8982 -enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
8986 @@ -211,28 +214,11 @@ void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count);
8993 -void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
8994 - u32 level);
8995 -void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
8996 - u32 level);
8997 -void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
8998 - u32 level);
8999 -void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
9000 - u32 level);
9001 -void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
9002 - u32 training_lane);
9003 -void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
9004 - u32 training_lane);
9005 -void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
9006 - u32 training_lane);
9007 -void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
9008 - u32 training_lane);
9009 -u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp);
9010 -u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp);
9011 -u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp);
9012 -u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp);
9018 @@ -255,5 +241,16 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
9035 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/an…
9037 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
9039 @@ -11,30 +11,44 @@
9051 -#define COMMON_INT_MASK_1 0
9052 -#define COMMON_INT_MASK_2 0
9053 -#define COMMON_INT_MASK_3 0
9054 -#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
9055 -#define INT_STA_MASK INT_HPD
9058 + if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
9059 + readl(dp->reg_base);
9060 + writel(val, dp->reg_base + reg);
9063 + writel(val, dp->reg_base + reg);
9068 + if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
9069 + readl(dp->reg_base + reg);
9071 + return readl(dp->reg_base + reg);
9079 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9082 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9085 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9088 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9093 @@ -42,23 +56,20 @@ void analogix_dp_stop_video(struct analogix_dp_device *dp)
9097 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9100 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
9104 -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
9107 - u32 reg;
9108 + struct video_info *video_info = &dp->video_info;
9111 - if (enable)
9112 - reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
9113 - LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
9114 - else
9115 - reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
9116 - LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
9117 + for (i = 0; i < video_info->max_lane_count; i++)
9118 + reg |= video_info->lane_map[i] << (2 * i);
9120 - writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
9125 @@ -66,53 +77,54 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
9129 - writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1);
9133 - writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
9136 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
9138 if (dp->plat_data->dev_type == RK3288_DP)
9141 - writel(reg, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
9142 - writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
9143 - writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
9144 - writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
9145 - writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
9155 - writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
9160 - writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1);
9165 - writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL);
9172 - writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL);
9176 - writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
9177 - writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2);
9178 - writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3);
9179 - writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
9180 - writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA);
9188 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
9189 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
9190 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
9191 - writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9192 - writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9201 @@ -130,65 +142,54 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
9205 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
9211 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9216 - analogix_dp_lane_swap(dp, 0);
9217 -
9218 - writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
9219 - writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
9220 - writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9221 - writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
9224 - writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
9225 - writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL);
9231 - writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L);
9232 - writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H);
9236 - writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL);
9239 - writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST);
9242 - writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD);
9243 - writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN);
9247 - writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH);
9248 - writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH);
9252 - writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
9258 - writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET);
9264 - u32 reg;
9265 -
9267 - reg = COMMON_INT_MASK_1;
9268 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
9269 -
9270 - reg = COMMON_INT_MASK_2;
9271 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
9272 -
9273 - reg = COMMON_INT_MASK_3;
9274 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
9279 - reg = COMMON_INT_MASK_4;
9280 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9281 -
9282 - reg = INT_STA_MASK;
9283 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9284 + if (dp->force_hpd || dp->hpd_gpiod)
9291 @@ -196,13 +197,13 @@ void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp)
9295 - reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9296 - reg &= ~COMMON_INT_MASK_4;
9297 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9302 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9303 - reg &= ~INT_STA_MASK;
9304 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9311 @@ -210,18 +211,20 @@ void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp)
9315 - reg = COMMON_INT_MASK_4;
9316 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
9321 - reg = INT_STA_MASK;
9322 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
9332 - reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
9337 @@ -239,12 +242,12 @@ void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enabl…
9341 - reg = readl(dp->reg_base + pd_addr);
9347 - writel(reg, dp->reg_base + pd_addr);
9352 @@ -265,52 +268,54 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
9356 - reg = readl(dp->reg_base + phy_pd_addr);
9357 - if (enable)
9362 - else
9365 - writel(reg, dp->reg_base + phy_pd_addr);
9371 - reg = readl(dp->reg_base + phy_pd_addr);
9378 - writel(reg, dp->reg_base + phy_pd_addr);
9383 - reg = readl(dp->reg_base + phy_pd_addr);
9390 - writel(reg, dp->reg_base + phy_pd_addr);
9395 - reg = readl(dp->reg_base + phy_pd_addr);
9402 - writel(reg, dp->reg_base + phy_pd_addr);
9407 - reg = readl(dp->reg_base + phy_pd_addr);
9414 - writel(reg, dp->reg_base + phy_pd_addr);
9419 @@ -323,29 +328,29 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
9423 - reg = readl(dp->reg_base + phy_pd_addr);
9430 - writel(reg, dp->reg_base + phy_pd_addr);
9432 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
9438 - writel(reg, dp->reg_base + phy_pd_addr);
9442 - writel(reg, dp->reg_base + phy_pd_addr);
9446 - writel(reg, dp->reg_base + phy_pd_addr);
9450 - writel(0x00, dp->reg_base + phy_pd_addr);
9455 @@ -356,36 +361,24 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
9459 - int timeout_loop = 0;
9464 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
9467 - reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
9470 - writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
9474 - if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
9475 - analogix_dp_set_pll_power_down(dp, 0);
9476 -
9477 - while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
9478 - timeout_loop++;
9479 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
9480 - dev_err(dp->dev, "failed to get pll lock status\n");
9481 - return -ETIMEDOUT;
9482 - }
9483 - usleep_range(10, 20);
9484 - }
9485 - }
9489 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9493 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9498 @@ -397,10 +390,10 @@ void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
9502 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
9506 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
9511 @@ -410,47 +403,47 @@ void analogix_dp_init_hpd(struct analogix_dp_device *dp)
9512 if (dp->hpd_gpiod)
9515 - analogix_dp_clear_hotplug_interrupts(dp);
9519 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9522 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9530 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9531 - reg = (F_HPD | HPD_CTRL);
9532 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9538 -enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
9544 - if (dp->hpd_gpiod) {
9545 - reg = gpiod_get_value(dp->hpd_gpiod);
9546 - if (reg)
9547 - return DP_IRQ_TYPE_HP_CABLE_IN;
9548 - else
9549 - return DP_IRQ_TYPE_HP_CABLE_OUT;
9550 - } else {
9551 - /* Parse hotplug interrupt status register */
9552 - reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
9553 -
9554 - if (reg & PLUG)
9555 - return DP_IRQ_TYPE_HP_CABLE_IN;
9558 + dev_info(dp->dev, "irq-hpd, it's being ignored for now\n");
9562 - if (reg & HPD_LOST)
9563 - return DP_IRQ_TYPE_HP_CABLE_OUT;
9570 - if (reg & HOTPLUG_CHG)
9571 - return DP_IRQ_TYPE_HP_CHANGE;
9573 + drm_helper_hpd_irq_event(dp->drm_dev);
9576 - return DP_IRQ_TYPE_UNKNOWN;
9577 - }
9584 @@ -458,9 +451,9 @@ void analogix_dp_reset_aux(struct analogix_dp_device *dp)
9588 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9591 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9596 @@ -469,7 +462,7 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
9600 - writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
9605 @@ -487,16 +480,17 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
9609 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
9614 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL);
9618 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9622 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9627 @@ -507,7 +501,7 @@ int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp)
9628 if (gpiod_get_value(dp->hpd_gpiod))
9631 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
9636 @@ -519,148 +513,193 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
9640 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
9643 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
9647 -int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp)
9650 - int reg;
9651 - int retval = 0;
9652 - int timeout_loop = 0;
9653 -
9654 - /* Enable AUX CH operation */
9655 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
9656 - reg |= AUX_EN;
9657 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
9658 -
9659 - /* Is AUX CH command reply received? */
9660 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
9661 - while (!(reg & RPLY_RECEIV)) {
9662 - timeout_loop++;
9663 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
9664 - dev_err(dp->dev, "AUX CH command reply failed!\n");
9665 - return -ETIMEDOUT;
9666 - }
9667 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
9668 - usleep_range(10, 11);
9669 - }
9670 -
9671 - /* Clear interrupt source for AUX CH command reply */
9672 - writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
9673 -
9674 - /* Clear interrupt source for AUX CH access error */
9675 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
9676 - if (reg & AUX_ERR) {
9677 - writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
9678 - return -EREMOTEIO;
9679 - }
9680 -
9681 - /* Check AUX CH error access status */
9682 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
9683 - if ((reg & AUX_STATUS_MASK) != 0) {
9684 - dev_err(dp->dev, "AUX CH error happens: %d\n\n",
9685 - reg & AUX_STATUS_MASK);
9686 - return -EREMOTEIO;
9687 - }
9690 - return retval;
9692 + writel(0x19, dp->reg_base + ANALOIGX_DP_SSC_REG);
9697 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9699 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9701 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9704 -int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
9705 - unsigned int reg_addr,
9706 - unsigned char data)
9710 - int i;
9711 - int retval;
9712 -
9713 - for (i = 0; i < 3; i++) {
9714 - /* Clear AUX CH data buffer */
9715 - reg = BUF_CLR;
9716 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
9717 -
9718 - /* Select DPCD device address */
9719 - reg = AUX_ADDR_7_0(reg_addr);
9720 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
9721 - reg = AUX_ADDR_15_8(reg_addr);
9722 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
9723 - reg = AUX_ADDR_19_16(reg_addr);
9724 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
9725 -
9726 - /* Write data buffer */
9727 - reg = (unsigned int)data;
9728 - writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
9729 -
9730 - /*
9731 - * Set DisplayPort transaction and write 1 byte
9732 - * If bit 3 is 1, DisplayPort transaction.
9733 - * If Bit 3 is 0, I2C transaction.
9734 - */
9735 - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
9736 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
9738 - /* Start AUX transaction */
9739 - retval = analogix_dp_start_aux_transaction(dp);
9740 - if (retval == 0)
9741 - break;
9742 -
9743 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
9744 - }
9745 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9747 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
9750 - return retval;
9754 + return dp->plat_data->ssc && dp->link_train.ssc;
9759 - u32 reg;
9763 - reg = bwtype;
9764 - if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
9765 - writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
9768 + if (dp->phy) {
9771 + phy_cfg.dp.lanes = dp->link_train.lane_count;
9773 + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
9778 + ret = phy_configure(dp->phy, &phy_cfg);
9779 + if (ret && ret != -EOPNOTSUPP) {
9780 + dev_err(dp->dev, "%s: phy_configure failed: %d\n",
9795 + dev_err(dp->dev, "Wait for pll lock failed %d\n", ret);
9804 - reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
9815 - writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
9818 + if (dp->phy) {
9821 + phy_cfg.dp.lanes = dp->link_train.lane_count;
9825 + ret = phy_configure(dp->phy, &phy_cfg);
9826 + if (ret && ret != -EOPNOTSUPP) {
9827 + dev_err(dp->dev, "%s: phy_configure() failed: %d\n",
9838 - reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
9848 + for (lane = 0; lane < dp->link_train.lane_count; lane++)
9851 + dp->link_train.training_lane[lane]);
9853 + if (dp->phy) {
9856 + for (lane = 0; lane < dp->link_train.lane_count; lane++) {
9857 + u8 training_lane = dp->link_train.training_lane[lane];
9868 + phy_cfg.dp.lanes = dp->link_train.lane_count;
9870 + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
9874 + ret = phy_configure(dp->phy, &phy_cfg);
9875 + if (ret && ret != -EOPNOTSUPP) {
9876 + dev_err(dp->dev, "%s: phy_configure() failed: %d\n",
9895 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
9898 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
9901 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
9904 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
9921 @@ -669,144 +708,48 @@ void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
9925 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
9930 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
9935 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
9940 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
9951 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
9959 -void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
9960 - u32 level)
9961 -{
9962 - u32 reg;
9963 -
9964 - reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
9965 - reg &= ~PRE_EMPHASIS_SET_MASK;
9966 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
9967 - writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
9968 -}
9969 -
9970 -void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
9971 - u32 level)
9972 -{
9973 - u32 reg;
9974 -
9975 - reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
9976 - reg &= ~PRE_EMPHASIS_SET_MASK;
9977 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
9978 - writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
9979 -}
9980 -
9981 -void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
9982 - u32 level)
9983 -{
9984 - u32 reg;
9985 -
9986 - reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
9987 - reg &= ~PRE_EMPHASIS_SET_MASK;
9988 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
9989 - writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
9990 -}
9991 -
9992 -void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
9993 - u32 level)
9994 -{
9995 - u32 reg;
9996 -
9997 - reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
9998 - reg &= ~PRE_EMPHASIS_SET_MASK;
9999 - reg |= level << PRE_EMPHASIS_SET_SHIFT;
10000 - writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
10001 -}
10002 -
10003 -void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
10004 - u32 training_lane)
10005 -{
10006 - u32 reg;
10007 -
10008 - reg = training_lane;
10009 - writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
10010 -}
10011 -
10012 -void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
10013 - u32 training_lane)
10014 -{
10015 - u32 reg;
10016 -
10017 - reg = training_lane;
10018 - writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
10019 -}
10020 -
10021 -void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
10022 - u32 training_lane)
10023 -{
10024 - u32 reg;
10025 -
10026 - reg = training_lane;
10027 - writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
10028 -}
10029 -
10030 -void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
10031 - u32 training_lane)
10032 -{
10033 - u32 reg;
10034 -
10035 - reg = training_lane;
10036 - writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
10037 -}
10038 -
10039 -u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
10040 -{
10041 - return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
10042 -}
10043 -
10044 -u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
10045 -{
10046 - return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
10047 -}
10048 -
10049 -u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
10050 -{
10051 - return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
10052 -}
10053 -
10054 -u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
10055 -{
10056 - return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
10057 -}
10058 -
10063 - reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
10066 - writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
10073 - writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
10078 @@ -814,19 +757,19 @@ void analogix_dp_init_video(struct analogix_dp_device *dp)
10082 - writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
10086 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10090 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10094 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10098 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
10103 @@ -837,36 +780,36 @@ void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
10104 reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
10105 (dp->video_info.color_depth << IN_BPC_SHIFT) |
10106 (dp->video_info.color_space << IN_COLOR_F_SHIFT);
10107 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
10111 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10114 if (dp->video_info.ycbcr_coeff)
10118 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10126 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10127 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10131 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
10135 dev_dbg(dp->dev, "Input stream clock not detected.\n");
10136 return -EINVAL;
10139 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10140 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10144 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
10146 dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
10149 @@ -884,30 +827,30 @@ void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
10153 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10156 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10159 - writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
10162 - writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
10165 - writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
10169 - writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
10172 - writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
10175 - writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
10178 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10181 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
10184 - writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
10185 - writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
10186 - writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
10193 @@ -916,13 +859,13 @@ void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 typ…
10197 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10200 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10203 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10206 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10211 @@ -931,15 +874,15 @@ void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enab…
10215 - reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10219 - writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10222 - reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10226 - writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10231 @@ -947,19 +890,19 @@ void analogix_dp_start_video(struct analogix_dp_device *dp)
10235 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
10238 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
10246 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10247 - writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10251 - reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
10254 dev_dbg(dp->dev, "Input video stream is not detected.\n");
10255 return -EINVAL;
10256 @@ -972,55 +915,55 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
10260 - reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
10262 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
10268 - writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
10271 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10274 reg |= (dp->video_info.interlaced << 2);
10275 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10278 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10281 reg |= (dp->video_info.v_sync_polarity << 1);
10282 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10285 - reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10288 reg |= (dp->video_info.h_sync_polarity << 0);
10289 - writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
10293 - writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
10301 - reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10304 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10312 - reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10315 - writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
10321 - writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
10326 @@ -1036,6 +979,24 @@ static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
10334 + switch (dp->plat_data->dev_type) {
10351 @@ -1044,44 +1005,47 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
10355 - val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10358 - writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10362 - writel(PSR_FRAME_UP_TYPE_BURST | PSR_CRC_SEL_HARDWARE,
10363 - dp->reg_base + ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL);
10368 - writel(vsc->sdp_header.HB0, dp->reg_base + ANALOGIX_DP_SPD_HB0);
10369 - writel(vsc->sdp_header.HB1, dp->reg_base + ANALOGIX_DP_SPD_HB1);
10370 - writel(vsc->sdp_header.HB2, dp->reg_base + ANALOGIX_DP_SPD_HB2);
10371 - writel(vsc->sdp_header.HB3, dp->reg_base + ANALOGIX_DP_SPD_HB3);
10372 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB0, vsc->sdp_header.HB0);
10373 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB1, vsc->sdp_header.HB1);
10374 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB2, vsc->sdp_header.HB2);
10375 + analogix_dp_write(dp, ANALOGIX_DP_SPD_HB3, vsc->sdp_header.HB3);
10378 - writel(0x00, dp->reg_base + ANALOGIX_DP_SPD_PB0);
10379 - writel(0x16, dp->reg_base + ANALOGIX_DP_SPD_PB1);
10380 - writel(0xCE, dp->reg_base + ANALOGIX_DP_SPD_PB2);
10381 - writel(0x5D, dp->reg_base + ANALOGIX_DP_SPD_PB3);
10388 - writel(vsc->db[0], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB0);
10389 - writel(vsc->db[1], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB1);
10390 + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB0, vsc->db[0]);
10391 + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB1, vsc->db[1]);
10395 + vsc->db[1] ? 0x8d : 0x00);
10399 - val = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10400 - val |= REUSE_SPD_EN;
10401 - writel(val, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
10405 - val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10408 - writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10412 - val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10415 - writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
10420 @@ -1108,11 +1072,46 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
10428 + ret = phy_set_mode(dp->phy, PHY_MODE_DP);
10430 + dev_err(dp->dev, "phy_set_mode failed: %d\n", ret);
10434 + ret = phy_power_on(dp->phy);
10436 + dev_err(dp->dev, "phy_power_on failed: %d\n", ret);
10445 + phy_power_off(dp->phy);
10464 - u32 status_reg;
10465 u8 *buffer = msg->buffer;
10468 @@ -1124,7 +1123,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10472 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
10475 switch (msg->request & ~DP_AUX_I2C_MOT) {
10477 @@ -1152,21 +1151,21 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10480 reg |= AUX_LENGTH(msg->size);
10481 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
10484 /* Select DPCD device address */
10485 reg = AUX_ADDR_7_0(msg->address);
10486 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
10488 reg = AUX_ADDR_15_8(msg->address);
10489 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
10491 reg = AUX_ADDR_19_16(msg->address);
10492 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
10495 if (!(msg->request & DP_AUX_I2C_READ)) {
10496 for (i = 0; i < msg->size; i++) {
10498 - writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
10499 - 4 * i);
10505 @@ -1178,7 +1177,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10506 if (msg->size < 1)
10509 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
10512 ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
10514 @@ -1197,30 +1196,31 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10518 - writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
10521 - /* Clear interrupt source for AUX CH access error */
10522 - reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
10523 - status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
10524 - if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
10525 - writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
10526 -
10527 - dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
10528 - status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
10529 - goto aux_error;
10530 - }
10533 + return -ETIMEDOUT;
10535 if (msg->request & DP_AUX_I2C_READ) {
10541 + if (buf_data_count != msg->size)
10542 + return -EBUSY;
10544 for (i = 0; i < msg->size; i++) {
10545 - reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
10546 - 4 * i);
10555 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
10558 msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
10560 @@ -1232,7 +1232,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10561 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
10562 msg->reply = DP_AUX_NATIVE_REPLY_ACK;
10564 - return num_transferred > 0 ? num_transferred : -EBUSY;
10565 + return (num_transferred == msg->size) ? num_transferred : -EBUSY;
10569 @@ -1240,3 +1240,127 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
10571 return -EREMOTEIO;
10576 + struct video_info *video = &dp->video_info;
10577 + const struct drm_display_mode *mode = &video->mode;
10580 + hsw = mode->hsync_end - mode->hsync_start;
10581 + hfp = mode->hsync_start - mode->hdisplay;
10582 + hbp = mode->htotal - mode->hsync_end;
10583 + vsw = mode->vsync_end - mode->vsync_start;
10584 + vfp = mode->vsync_start - mode->vdisplay;
10585 + vbp = mode->vtotal - mode->vsync_end;
10589 + TOTAL_LINE_CFG_L(mode->vtotal));
10591 + TOTAL_LINE_CFG_H(mode->vtotal >> 8));
10593 + ACTIVE_LINE_CFG_L(mode->vdisplay));
10595 + ACTIVE_LINE_CFG_H(mode->vdisplay >> 8));
10603 + TOTAL_PIXEL_CFG_L(mode->htotal));
10605 + TOTAL_PIXEL_CFG_H(mode->htotal >> 8));
10607 + ACTIVE_PIXEL_CFG_L(mode->hdisplay));
10609 + ACTIVE_PIXEL_CFG_H(mode->hdisplay >> 8));
10697 diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/an…
10699 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
10701 @@ -15,9 +15,27 @@
10729 @@ -27,6 +45,8 @@
10738 @@ -43,6 +63,8 @@
10747 @@ -70,7 +92,7 @@
10751 -
10756 @@ -116,8 +138,9 @@
10760 -
10767 @@ -171,6 +194,11 @@
10779 @@ -181,6 +209,60 @@
10840 @@ -309,6 +391,10 @@
10851 @@ -319,6 +405,7 @@
10859 @@ -406,6 +493,11 @@
10871 @@ -414,4 +506,7 @@
10879 diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c
10881 --- a/drivers/gpu/drm/bridge/display-connector.c
10882 +++ b/drivers/gpu/drm/bridge/display-connector.c
10883 @@ -11,7 +11,9 @@
10893 @@ -20,6 +22,8 @@ struct display_connector {
10902 @@ -84,10 +88,95 @@ static struct edid *display_connector_get_edid(struct drm_bridge *bridge,
10903 return drm_get_edid(connector, conn->bridge.ddc);
10922 + if (!prev_bridge || !prev_bridge->funcs->atomic_get_output_bus_fmts) {
10923 + struct drm_connector *conn = conn_state->connector;
10931 + if (conn->display_info.num_bus_formats &&
10932 + conn->display_info.bus_formats)
10933 + out_bus_fmts[0] = conn->display_info.bus_formats[0];
10940 + prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
10943 + return prev_bridge->funcs->atomic_get_output_bus_fmts(prev_bridge, prev_bridge_state,
10965 + if (!prev_bridge || !prev_bridge->funcs->atomic_get_input_bus_fmts) {
10978 + prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
10981 + return prev_bridge->funcs->atomic_get_input_bus_fmts(prev_bridge, prev_bridge_state,
10998 @@ -172,11 +261,12 @@ static int display_connector_probe(struct platform_device *pdev)
10999 of_property_read_string(pdev->dev.of_node, "label", &label);
11002 - * Get the HPD GPIO for DVI and HDMI connectors. If the GPIO can provide
11007 - type == DRM_MODE_CONNECTOR_HDMIA) {
11010 conn->hpd_gpio = devm_gpiod_get_optional(&pdev->dev, "hpd",
11012 if (IS_ERR(conn->hpd_gpio)) {
11013 @@ -223,6 +313,38 @@ static int display_connector_probe(struct platform_device *pdev)
11021 + conn->dp_pwr = devm_regulator_get_optional(&pdev->dev, "dp-pwr");
11023 + if (IS_ERR(conn->dp_pwr)) {
11024 + ret = PTR_ERR(conn->dp_pwr);
11027 + case -ENODEV:
11028 + conn->dp_pwr = NULL;
11031 + case -EPROBE_DEFER:
11032 + return -EPROBE_DEFER;
11035 + dev_err(&pdev->dev, "failed to get DP PWR regulator: %d\n", ret);
11040 + if (conn->dp_pwr) {
11041 + ret = regulator_enable(conn->dp_pwr);
11043 + dev_err(&pdev->dev, "failed to enable DP PWR regulator: %d\n", ret);
11049 conn->bridge.funcs = &display_connector_bridge_funcs;
11050 conn->bridge.of_node = pdev->dev.of_node;
11052 @@ -251,6 +373,9 @@ static int display_connector_remove(struct platform_device *pdev)
11056 + if (conn->dp_pwr)
11057 + regulator_disable(conn->dp_pwr);
11059 drm_bridge_remove(&conn->bridge);
11061 if (!IS_ERR(conn->bridge.ddc))
11062 @@ -275,6 +400,9 @@ static const struct of_device_id display_connector_match[] = {
11064 .compatible = "vga-connector",
11067 + .compatible = "dp-connector",
11072 diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
11074 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c
11075 +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
11076 @@ -867,14 +867,8 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge,
11080 - struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
11082 - if (!lt9611_mode)
11083 - return MODE_BAD;
11084 - else if (lt9611_mode->intfs > 1 && !lt9611->dsi1)
11085 - return MODE_PANEL;
11086 - else
11087 - return MODE_OK;
11092 diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
11094 --- a/drivers/gpu/drm/bridge/nwl-dsi.c
11095 +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
11096 @@ -196,7 +196,7 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
11097 u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
11099 return DIV64_U64_ROUND_UP(ps * dsi->mode.clock * bpp,
11100 - dsi->lanes * 8ULL * NSEC_PER_SEC);
11101 + dsi->lanes * 8 * NSEC_PER_SEC);
11105 diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
11107 --- a/drivers/gpu/drm/bridge/sii902x.c
11109 @@ -24,10 +24,12 @@
11117 #include <sound/hdmi-codec.h>
11122 @@ -146,6 +148,12 @@
11135 @@ -168,6 +176,7 @@ struct sii902x {
11143 @@ -180,6 +189,14 @@ struct sii902x {
11158 @@ -270,13 +287,56 @@ static const struct drm_connector_funcs sii902x_connector_funcs = {
11163 + /* 4 - 1280x720@60Hz 16:9 */
11168 + /* 16 - 1920x1080@60Hz 16:9 */
11173 + /* 5 - 1920x1080i@60Hz 16:9 */
11179 + /* 31 - 1920x1080@50Hz 16:9 */
11184 + /* 19 - 1280x720@50Hz 16:9 */
11189 + /* 0x10 - 1024x768@60Hz */
11193 + /* 17 - 720x576@50Hz 4:3 */
11198 + /* 2 - 720x480@60Hz 4:3 */
11208 - u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
11211 - int num = 0, ret;
11215 mutex_lock(&sii902x->mutex);
11217 @@ -288,10 +348,24 @@ static int sii902x_get_modes(struct drm_connector *connector)
11226 + mode = drm_mode_duplicate(connector->dev, ptr);
11229 + mode->type = DRM_MODE_TYPE_PREFERRED;
11237 ret = drm_display_info_set_bus_formats(&connector->display_info,
11238 - &bus_format, 1);
11239 + &sii902x->bus_format, 1);
11243 @@ -311,7 +385,10 @@ static int sii902x_get_modes(struct drm_connector *connector)
11247 - /* TODO: check mode */
11248 + if (mode->hdisplay > 1920 || mode->vdisplay > 1080)
11250 + if (mode->clock > 165000)
11255 @@ -349,6 +426,106 @@ static void sii902x_bridge_enable(struct drm_bridge *bridge)
11256 mutex_unlock(&sii902x->mutex);
11281 + if (!sii902x_check_embedded_format(sii902x->bus_format))
11284 + switch (sii902x->bus_format) {
11289 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11296 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11298 + regmap_write(sii902x->regmap,
11300 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11303 + drm_display_mode_to_videomode(&sii902x->mode, &vm);
11312 + regmap_bulk_write(sii902x->regmap, SII902X_TPI_HBIT_TO_HSYNC, data, 8);
11314 + sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
11316 + sii902x_update_bits_unlocked(sii902x->i2c,
11320 + regmap_update_bits(sii902x->regmap,
11330 + switch (sii902x->bus_format) {
11354 + regmap_write(sii902x->regmap, SII902X_TPI_AVI_IN_FORMAT, val);
11362 @@ -358,20 +535,56 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
11365 u16 pixel_clock_10kHz = adj->clock / 10;
11366 - int ret;
11369 + drm_mode_copy(&sii902x->mode, adj);
11373 - buf[2] = drm_mode_vrefresh(adj);
11374 - buf[3] = 0x00;
11375 - buf[4] = adj->hdisplay;
11376 - buf[5] = adj->hdisplay >> 8;
11377 - buf[6] = adj->vdisplay;
11378 - buf[7] = adj->vdisplay >> 8;
11381 + buf[4] = adj->crtc_htotal;
11382 + buf[5] = adj->crtc_htotal >> 8;
11383 + buf[6] = adj->crtc_vtotal;
11384 + buf[7] = adj->crtc_vtotal >> 8;
11387 - buf[9] = SII902X_TPI_AVI_INPUT_RANGE_AUTO |
11388 - SII902X_TPI_AVI_INPUT_COLORSPACE_RGB;
11389 + switch (sii902x->bus_format) {
11405 + switch (sii902x->bus_format) {
11426 mutex_lock(&sii902x->mutex);
11428 @@ -396,7 +609,7 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
11430 buf + HDMI_INFOFRAME_HEADER_SIZE - 1,
11432 -
11435 mutex_unlock(&sii902x->mutex);
11437 @@ -413,6 +626,7 @@ static int sii902x_bridge_attach(struct drm_bridge *bridge,
11438 return -EINVAL;
11441 + sii902x->connector.interlace_allowed = true;
11442 drm_connector_helper_add(&sii902x->connector,
11445 @@ -966,8 +1180,10 @@ static int sii902x_init(struct sii902x *sii902x)
11448 ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0);
11449 - if (ret)
11455 ret = regmap_bulk_read(sii902x->regmap, SII902X_REG_CHIPID(0),
11457 @@ -992,6 +1208,7 @@ static int sii902x_init(struct sii902x *sii902x)
11459 ret = devm_request_threaded_irq(dev, sii902x->i2c->irq, NULL,
11465 @@ -1024,6 +1241,7 @@ static int sii902x_probe(struct i2c_client *client,
11466 struct device *dev = &client->dev;
11471 ret = i2c_check_functionality(client->adapter,
11473 @@ -1049,6 +1267,37 @@ static int sii902x_probe(struct i2c_client *client,
11474 return PTR_ERR(sii902x->reset_gpio);
11477 + sii902x->enable_gpio = devm_gpiod_get_optional(dev, "enable",
11479 + if (IS_ERR(sii902x->enable_gpio)) {
11481 + PTR_ERR(sii902x->enable_gpio));
11482 + return PTR_ERR(sii902x->enable_gpio);
11483 + } else if (sii902x->enable_gpio) {
11484 + gpiod_direction_output(sii902x->enable_gpio, 1);
11488 + ret = of_property_read_u32(dev->of_node, "bus-format", &val);
11490 + sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
11494 + sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
11497 + sii902x->bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
11500 + sii902x->bus_format = MEDIA_BUS_FMT_YUV8_1X24;
11503 + sii902x->bus_format = val;
11508 mutex_init(&sii902x->mutex);
11510 sii902x->supplies[0].supply = "iovcc";
11511 @@ -1067,6 +1316,7 @@ static int sii902x_probe(struct i2c_client *client,
11516 regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
11517 sii902x->supplies);
11519 diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
11521 --- a/drivers/gpu/drm/bridge/synopsys/Makefile
11523 @@ -1,7 +1,8 @@
11524 # SPDX-License-Identifier: GPL-2.0-only
11525 -obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
11526 +obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o dw-hdmi-hdcp.o \
11527 + dw-hdmi-qp.o
11528 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
11529 -obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
11530 -obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
11531 +obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o dw-hdmi-qp-i2s-audio.o
11532 +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o dw-hdmi-qp-cec.o
11534 obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
11535 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdm…
11537 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
11538 +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
11539 @@ -12,6 +12,7 @@
11546 #include <media/cec-notifier.h>
11547 @@ -262,6 +263,8 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)
11548 if (IS_ERR(cec->adap))
11549 return PTR_ERR(cec->adap);
11551 + dw_hdmi_set_cec_adap(cec->hdmi, cec->adap);
11554 cec->adap->owner = THIS_MODULE;
11556 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
11558 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
11559 +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
11560 @@ -9,6 +9,8 @@
11565 +#include <linux/extcon-provider.h>
11569 @@ -18,6 +20,7 @@
11571 #include <linux/dma-mapping.h>
11575 #include <media/cec-notifier.h>
11577 @@ -36,6 +39,7 @@
11579 #include "dw-hdmi-audio.h"
11580 #include "dw-hdmi-cec.h"
11581 +#include "dw-hdmi-hdcp.h"
11582 #include "dw-hdmi.h"
11585 @@ -48,6 +52,11 @@
11597 @@ -62,6 +71,61 @@ enum hdmi_datamap {
11604 + * slow so we pre-compute values we expect to see.
11659 @@ -98,12 +162,47 @@ static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
11664 + /* 4 - 1280x720@60Hz 16:9 */
11669 + /* 16 - 1920x1080@60Hz 16:9 */
11674 + /* 31 - 1920x1080@50Hz 16:9 */
11679 + /* 19 - 1280x720@50Hz 16:9 */
11684 + /* 17 - 720x576@50Hz 4:3 */
11689 + /* 2 - 720x480@60Hz 4:3 */
11707 @@ -112,8 +211,8 @@ struct hdmi_data_info {
11713 - unsigned int hdcp_enable;
11717 @@ -128,6 +227,9 @@ struct dw_hdmi_i2c {
11727 @@ -143,6 +245,8 @@ struct dw_hdmi_phy_data {
11736 @@ -156,8 +260,10 @@ struct dw_hdmi {
11747 @@ -174,6 +280,13 @@ struct dw_hdmi {
11761 @@ -190,10 +303,14 @@ struct dw_hdmi {
11776 @@ -202,10 +319,12 @@ struct dw_hdmi {
11789 @@ -263,6 +382,124 @@ static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
11797 + sink_hdmi = hdmi->sink_is_hdmi;
11799 + if (hdmi->force_output == 1)
11800 + hdmi->sink_is_hdmi = true;
11801 + else if (hdmi->force_output == 2)
11802 + hdmi->sink_is_hdmi = false;
11804 + hdmi->sink_is_hdmi = hdmi->support_hdmi;
11806 + if (sink_hdmi != hdmi->sink_is_hdmi)
11815 + enum drm_connector_status status = hdmi->hpd_state ?
11819 + mutex_lock(&hdmi->mutex);
11821 + hdmi->rxsense = false;
11823 + hdmi->rxsense = true;
11824 + mutex_unlock(&hdmi->mutex);
11826 + if (hdmi->bridge.dev) {
11829 + change = drm_helper_hpd_irq_event(hdmi->bridge.dev);
11830 + if (change && hdmi->cec_adap &&
11831 + hdmi->cec_adap->devnode.registered)
11832 + cec_queue_pin_hpd_event(hdmi->cec_adap,
11833 + hdmi->hpd_state,
11835 + drm_bridge_hpd_notify(&hdmi->bridge, status);
11849 + dev_dbg(hdmi->dev, "dw hdmi plug in\n");
11851 + hdmi->hpd_state = true;
11853 + dev_dbg(hdmi->dev, "dw hdmi plug out\n");
11855 + hdmi->hpd_state = false;
11857 + mod_delayed_work(hdmi->workqueue, &hdmi->work, msecs_to_jiffies(msecs));
11864 + hdmi->workqueue = create_workqueue("hpd_queue");
11865 + INIT_DELAYED_WORK(&hdmi->work, repo_hpd_event);
11874 + /* Standard-mode */
11875 + if (hdmi->i2c->scl_high_ns < 4000)
11878 + high_ns = hdmi->i2c->scl_high_ns;
11880 + if (hdmi->i2c->scl_low_ns < 4700)
11883 + low_ns = hdmi->i2c->scl_low_ns;
11886 + clk_rate_khz = DIV_ROUND_UP(clk_get_rate(hdmi->isfr_clk), 1000);
11914 @@ -276,7 +513,8 @@ static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
11918 - hdmi_writeb(hdmi, 0x00, HDMI_I2CM_DIV);
11924 @@ -290,6 +528,11 @@ static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
11936 @@ -461,6 +704,8 @@ static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
11945 @@ -570,60 +815,117 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
11949 -static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
11954 - unsigned int n = (128 * freq) / 1000;
11955 - unsigned int mult = 1;
11956 + const struct dw_hdmi_plat_data *plat_data = hdmi->plat_data;
11960 + if (plat_data->tmds_n_table) {
11961 + for (i = 0; plat_data->tmds_n_table[i].tmds != 0; i++) {
11962 + if (pixel_clk == plat_data->tmds_n_table[i].tmds) {
11963 + tmds_n = &plat_data->tmds_n_table[i];
11969 - while (freq > 48000) {
11970 - mult *= 2;
11971 - freq /= 2;
11982 + return -ENOENT;
11986 - if (pixel_clk == 25175000)
11987 - n = 4576;
11988 - else if (pixel_clk == 27027000)
11989 - n = 4096;
11990 - else if (pixel_clk == 74176000 || pixel_clk == 148352000)
11991 - n = 11648;
11992 - else
11993 - n = 4096;
11994 - n *= mult;
11995 - break;
11996 -
11997 + return tmds_n->n_32k;
11999 - if (pixel_clk == 25175000)
12000 - n = 7007;
12001 - else if (pixel_clk == 74176000)
12002 - n = 17836;
12003 - else if (pixel_clk == 148352000)
12004 - n = 8918;
12005 - else
12006 - n = 6272;
12007 - n *= mult;
12008 - break;
12009 -
12012 + return (freq / 44100) * tmds_n->n_44k1;
12014 - if (pixel_clk == 25175000)
12015 - n = 6864;
12016 - else if (pixel_clk == 27027000)
12017 - n = 6144;
12018 - else if (pixel_clk == 74176000)
12019 - n = 11648;
12020 - else if (pixel_clk == 148352000)
12021 - n = 5824;
12022 - else
12023 - n = 6144;
12024 - n *= mult;
12025 - break;
12026 -
12029 + return (freq / 48000) * tmds_n->n_48k;
12031 - break;
12032 + return -ENOENT;
12047 + diff = final - (u64)cts * (128 * freq);
12072 + abs(n - ideal_n) < best_n_distance)) {
12075 + best_n_distance = abs(best_n - ideal_n);
12082 + if ((best_diff == 0) && (abs(n - ideal_n) > best_n_distance))
12086 - return n;
12099 + dev_warn(hdmi->dev, "Rate %lu missing; compute N dynamically\n",
12106 @@ -654,7 +956,7 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
12110 - n = hdmi_compute_n(sample_rate, pixel_clk);
12115 @@ -1013,6 +1315,15 @@ static bool is_csc_needed(struct dw_hdmi *hdmi)
12121 + if (hdmi->hdmi_data.quant_range == HDMI_QUANTIZATION_RANGE_LIMITED ||
12122 + (!hdmi->hdmi_data.quant_range && hdmi->hdmi_data.rgb_limited_range))
12131 @@ -1035,7 +1346,7 @@ static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
12135 - hdmi->hdmi_data.rgb_limited_range) {
12140 @@ -1067,7 +1378,7 @@ static void hdmi_video_csc(struct dw_hdmi *hdmi)
12144 - decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
12147 switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) {
12149 @@ -1114,7 +1425,7 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
12151 hdmi->hdmi_data.enc_out_bus_format)) {
12153 - color_depth = 4;
12158 @@ -1152,18 +1463,15 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
12162 - val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
12163 - HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
12164 - ((hdmi_data->pix_repet_factor <<
12165 - HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
12166 - HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
12175 - if (hdmi_data->pix_repet_factor > 1) {
12176 + if (hdmi_data->pix_repet_factor > 0) {
12180 @@ -1175,8 +1483,13 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
12184 - hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
12185 - HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
12186 + if ((color_depth == 5 && hdmi->previous_mode.htotal % 4) ||
12187 + (color_depth == 6 && hdmi->previous_mode.htotal % 2))
12196 @@ -1277,6 +1590,23 @@ static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
12219 * - The Source shall suspend transmission of the TMDS clock and data
12220 @@ -1454,6 +1784,13 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12221 const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg;
12222 const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
12223 const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
12224 + unsigned int tmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
12226 + hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format);
12228 + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) &&
12229 + pdata->mpll_cfg_420)
12230 + mpll_config = pdata->mpll_cfg_420;
12234 @@ -1463,11 +1800,11 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12237 for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++)
12238 - if (mpixelclock <= curr_ctrl->mpixelclock)
12239 + if (tmdsclock <= curr_ctrl->mpixelclock)
12242 for (; phy_config->mpixelclock != ~0UL; phy_config++)
12243 - if (mpixelclock <= phy_config->mpixelclock)
12244 + if (tmdsclock <= phy_config->mpixelclock)
12247 if (mpll_config->mpixelclock == ~0UL ||
12248 @@ -1475,11 +1812,18 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12249 phy_config->mpixelclock == ~0UL)
12250 return -EINVAL;
12252 - dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce,
12253 + if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
12254 + depth = fls(depth - 8);
12258 + depth--;
12260 + dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].cpce,
12262 - dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
12263 + dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].gmp,
12265 - dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
12266 + dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[depth],
12270 @@ -1492,10 +1836,6 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
12271 dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
12274 - /* Override and disable clock termination. */
12275 - dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
12276 - HDMI_3D_TX_PHY_CKCALCTRL);
12277 -
12281 @@ -1597,14 +1937,16 @@ void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
12285 - /* Enable cable hot plug irq. */
12286 - hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
12287 + if (!hdmi->next_bridge) {
12289 + hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
12291 - /* Clear and unmute interrupts. */
12292 - hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
12293 - HDMI_IH_PHY_STAT0);
12294 - hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
12295 - HDMI_IH_MUTE_PHY_STAT0);
12305 @@ -1620,23 +1962,36 @@ static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
12309 -static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
12313 - u8 de;
12314 -
12315 - if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
12316 - de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
12317 - else
12318 - de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
12319 -
12320 - /* disable rx detect */
12321 - hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE,
12322 - HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0);
12323 -
12324 - hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG);
12325 -
12326 - hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE,
12327 - HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
12328 + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
12332 + vsync_pol = mode->flags & DRM_MODE_FLAG_PVSYNC ?
12335 + hsync_pol = mode->flags & DRM_MODE_FLAG_PHSYNC ?
12338 + data_pol = vmode->mdataenablepolarity ?
12348 + hdmi_dvi = hdmi->sink_is_hdmi ? HDMI_A_HDCPCFG0_HDMIDVI_HDMI :
12353 + if (hdmi->hdcp && hdmi->hdcp->hdcp_start)
12354 + hdmi->hdcp->hdcp_start(hdmi->hdcp);
12358 @@ -1650,10 +2005,15 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi,
12361 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
12362 - drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode,
12363 - hdmi->hdmi_data.rgb_limited_range ?
12364 - HDMI_QUANTIZATION_RANGE_LIMITED :
12365 - HDMI_QUANTIZATION_RANGE_FULL);
12367 + if (!hdmi->hdmi_data.quant_range)
12369 + hdmi->hdmi_data.rgb_limited_range ?
12374 + hdmi->hdmi_data.quant_range);
12378 @@ -1688,6 +2048,14 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi,
12383 + if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_BT2020)
12393 @@ -1824,17 +2192,44 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi,
12396 const struct drm_connector_state *conn_state = connector->state;
12404 + if (hdmi->version < 0x211a) {
12409 if (!hdmi->plat_data->use_drm_infoframe)
12415 + if (!hdmi->connector.hdr_sink_metadata.hdmi_type1.eotf) {
12420 + if (!conn_state->hdr_output_metadata) {
12426 + conn_state->hdr_output_metadata->data;
12428 + if (!(hdmi->connector.hdr_sink_metadata.hdmi_type1.eotf &
12429 + BIT(hdr_metadata->hdmi_metadata_type1.eotf))) {
12431 + hdr_metadata->hdmi_metadata_type1.eotf);
12438 @@ -1854,51 +2249,66 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi,
12444 + hdr_metadata->hdmi_metadata_type1.eotf);
12447 -static void hdmi_av_composer(struct dw_hdmi *hdmi,
12448 - const struct drm_display_info *display,
12449 - const struct drm_display_mode *mode)
12453 - u8 inv_val, bytes;
12454 - const struct drm_hdmi_info *hdmi_info = &display->hdmi;
12455 - struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
12456 - int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
12457 - unsigned int vdisplay, hdisplay;
12458 -
12459 - vmode->mpixelclock = mode->clock * 1000;
12460 -
12461 - dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
12462 -
12463 - vmode->mtmdsclock = vmode->mpixelclock;
12466 + hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format);
12468 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) {
12469 - switch (hdmi_bus_fmt_color_depth(
12470 - hdmi->hdmi_data.enc_out_bus_format)) {
12473 - vmode->mtmdsclock = vmode->mpixelclock * 2;
12477 - vmode->mtmdsclock = vmode->mpixelclock * 3 / 2;
12481 - vmode->mtmdsclock = vmode->mpixelclock * 5 / 4;
12497 + const struct drm_hdmi_info *hdmi_info = &display->hdmi;
12498 + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
12502 + vmode->previous_pixelclock = vmode->mpixelclock;
12503 + vmode->mpixelclock = mode->crtc_clock * 1000;
12504 + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) ==
12506 + vmode->mpixelclock *= 2;
12507 + dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
12509 + vmode->previous_tmdsclock = vmode->mtmdsclock;
12510 + vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi, vmode->mpixelclock);
12511 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
12512 vmode->mtmdsclock /= 2;
12513 -
12514 dev_dbg(hdmi->dev, "final tmdsclock = %d\n", vmode->mtmdsclock);
12516 - /* Set up HDMI_FC_INVIDCONF */
12517 - inv_val = (hdmi->hdmi_data.hdcp_enable ||
12518 - (dw_hdmi_support_scdc(hdmi, display) &&
12519 - (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
12520 - hdmi_info->scdc.scrambling.low_rates)) ?
12521 - HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
12522 - HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
12530 inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
12532 @@ -1964,7 +2374,8 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
12535 if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
12536 - hdmi_info->scdc.scrambling.low_rates) {
12537 + (hdmi_info->scdc.scrambling.low_rates &&
12538 + hdmi->scramble_low_rates)) {
12542 @@ -1998,6 +2409,8 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
12544 drm_scdc_set_scrambling(hdmi->ddc, 0);
12551 @@ -2055,6 +2468,12 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
12552 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
12553 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
12556 + if (hdmi->hdmi_data.video_mode.mpixelrepetitioninput) {
12557 + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PREPCLK_DISABLE;
12558 + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
12563 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
12564 @@ -2130,6 +2549,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
12568 + void *data = hdmi->plat_data->phy_data;
12572 @@ -2141,48 +2561,91 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
12573 dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
12576 - if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
12577 - (hdmi->vic == 21) || (hdmi->vic == 22) ||
12578 - (hdmi->vic == 2) || (hdmi->vic == 3) ||
12579 - (hdmi->vic == 17) || (hdmi->vic == 18))
12580 + if (hdmi->plat_data->get_enc_out_encoding)
12581 + hdmi->hdmi_data.enc_out_encoding =
12582 + hdmi->plat_data->get_enc_out_encoding(data);
12583 + else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
12584 + (hdmi->vic == 21) || (hdmi->vic == 22) ||
12585 + (hdmi->vic == 2) || (hdmi->vic == 3) ||
12586 + (hdmi->vic == 17) || (hdmi->vic == 18))
12587 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
12589 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
12591 - hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
12592 - hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
12593 + if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
12594 + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
12595 + hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 1;
12597 + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
12598 + hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
12601 + if (hdmi->plat_data->get_input_bus_format)
12602 + hdmi->hdmi_data.enc_in_bus_format =
12603 + hdmi->plat_data->get_input_bus_format(data);
12604 + else if (hdmi->plat_data->input_bus_format)
12605 + hdmi->hdmi_data.enc_in_bus_format =
12606 + hdmi->plat_data->input_bus_format;
12608 + hdmi->hdmi_data.enc_in_bus_format =
12611 - if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
12612 - hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
12614 + if (hdmi->plat_data->get_output_bus_format)
12615 + hdmi->hdmi_data.enc_out_bus_format =
12616 + hdmi->plat_data->get_output_bus_format(data);
12618 + hdmi->hdmi_data.enc_out_bus_format =
12622 - if (hdmi->plat_data->input_bus_encoding)
12623 + if (hdmi->plat_data->get_enc_in_encoding)
12624 + hdmi->hdmi_data.enc_in_encoding =
12625 + hdmi->plat_data->get_enc_in_encoding(data);
12626 + else if (hdmi->plat_data->input_bus_encoding)
12627 hdmi->hdmi_data.enc_in_encoding =
12628 hdmi->plat_data->input_bus_encoding;
12630 hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
12632 - if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED)
12633 - hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
12635 + if (hdmi->plat_data->get_quant_range)
12636 + hdmi->hdmi_data.quant_range =
12637 + hdmi->plat_data->get_quant_range(data);
12639 hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi &&
12643 - hdmi->hdmi_data.pix_repet_factor = 0;
12644 - hdmi->hdmi_data.hdcp_enable = 0;
12645 + if (!hdmi->sink_is_hdmi)
12646 + hdmi->hdmi_data.quant_range = HDMI_QUANTIZATION_RANGE_FULL;
12649 + * According to the dw-hdmi specification 6.4.2
12654 + hdmi->hdmi_data.pix_repet_factor =
12655 + (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 1 : 0;
12656 hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
12659 hdmi_av_composer(hdmi, &connector->display_info, mode);
12662 - ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
12663 - &connector->display_info,
12664 - &hdmi->previous_mode);
12665 - if (ret)
12666 - return ret;
12667 - hdmi->phy.enabled = true;
12668 + if (!hdmi->phy.enabled ||
12669 + hdmi->hdmi_data.video_mode.previous_pixelclock !=
12670 + hdmi->hdmi_data.video_mode.mpixelclock ||
12671 + hdmi->hdmi_data.video_mode.previous_tmdsclock !=
12672 + hdmi->hdmi_data.video_mode.mtmdsclock) {
12673 + ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
12674 + &connector->display_info,
12675 + &hdmi->previous_mode);
12678 + hdmi->phy.enabled = true;
12683 @@ -2210,7 +2673,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
12687 - hdmi_tx_hdcp_config(hdmi);
12692 @@ -2286,6 +2749,8 @@ static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
12693 hdmi->phy.enabled = false;
12696 + if (hdmi->hdcp && hdmi->hdcp->hdcp_stop)
12697 + hdmi->hdcp->hdcp_stop(hdmi->hdcp);
12698 hdmi->bridge_is_on = false;
12701 @@ -2303,6 +2768,10 @@ static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
12705 + if (hdmi->initialized) {
12706 + hdmi->initialized = false;
12707 + hdmi->disabled = true;
12709 if (hdmi->bridge_is_on)
12712 @@ -2335,8 +2804,15 @@ static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
12716 - result = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
12717 + if (!hdmi->force_logo) {
12718 + mutex_lock(&hdmi->mutex);
12719 + hdmi->force = DRM_FORCE_UNSPECIFIED;
12722 + mutex_unlock(&hdmi->mutex);
12725 + result = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
12726 mutex_lock(&hdmi->mutex);
12727 if (result != hdmi->last_connector_result) {
12728 dev_dbg(hdmi->dev, "read_hpd result: %d", result);
12729 @@ -2346,6 +2822,11 @@ static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
12731 mutex_unlock(&hdmi->mutex);
12734 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, true);
12736 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false);
12741 @@ -2366,7 +2847,7 @@ static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi,
12742 dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
12743 edid->width_cm, edid->height_cm);
12745 - hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
12746 + hdmi->support_hdmi = drm_detect_hdmi_monitor(edid);
12747 hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
12750 @@ -2384,21 +2865,105 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
12757 + struct drm_device *dev = connector->dev;
12760 + void *data = hdmi->plat_data->phy_data;
12762 + &connector->hdr_sink_metadata.hdmi_type1;
12768 + if (hdmi->plat_data->get_hdr_property)
12769 + property = hdmi->plat_data->get_hdr_property(data);
12771 + return -EINVAL;
12773 + if (hdmi->plat_data->get_hdr_blob)
12774 + blob = hdmi->plat_data->get_hdr_blob(data);
12776 + return -EINVAL;
12779 + &connector->base, property);
12788 + &connector->hdr_sink_metadata.hdmi_type1;
12790 - int ret;
12792 + struct drm_display_info *info = &connector->display_info;
12797 - if (!edid)
12798 - return 0;
12800 + dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
12801 + edid->width_cm, edid->height_cm);
12803 + cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
12805 + if (hdmi->plat_data->get_color_changed)
12806 + hdmi->plat_data->get_yuv422_format(connector, edid);
12810 + hdmi->support_hdmi = true;
12811 + hdmi->sink_has_audio = true;
12816 + mode = drm_mode_duplicate(connector->dev, ptr);
12819 + mode->type = DRM_MODE_TYPE_PREFERRED;
12820 + mode->picture_aspect_ratio =
12827 + info->edid_hdmi_dc_modes = 0;
12828 + info->hdmi.y420_dc_modes = 0;
12829 + info->color_formats = 0;
12831 + dev_info(hdmi->dev, "failed to get edid\n");
12844 + return hdmi->bridge.encoder;
12847 - drm_connector_update_edid_property(connector, edid);
12848 - cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
12849 - ret = drm_add_edid_modes(connector, edid);
12850 - kfree(edid);
12855 + void *data = hdmi->plat_data->phy_data;
12858 + if (hdmi->plat_data->get_color_changed)
12859 + ret = hdmi->plat_data->get_color_changed(data);
12863 @@ -2427,11 +2992,54 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
12865 struct drm_crtc *crtc = new_state->crtc;
12870 + void *data = hdmi->plat_data->phy_data;
12871 + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
12872 + unsigned int in_bus_format = hdmi->hdmi_data.enc_in_bus_format;
12873 + unsigned int out_bus_format = hdmi->hdmi_data.enc_out_bus_format;
12879 - if (!hdr_metadata_equal(old_state, new_state)) {
12884 + if (!vmode->mpixelclock) {
12886 + if (hdmi->plat_data->get_enc_in_encoding)
12887 + hdmi->hdmi_data.enc_in_encoding =
12888 + hdmi->plat_data->get_enc_in_encoding(data);
12889 + if (hdmi->plat_data->get_enc_out_encoding)
12890 + hdmi->hdmi_data.enc_out_encoding =
12891 + hdmi->plat_data->get_enc_out_encoding(data);
12892 + if (hdmi->plat_data->get_input_bus_format)
12893 + hdmi->hdmi_data.enc_in_bus_format =
12894 + hdmi->plat_data->get_input_bus_format(data);
12895 + if (hdmi->plat_data->get_output_bus_format)
12896 + hdmi->hdmi_data.enc_out_bus_format =
12897 + hdmi->plat_data->get_output_bus_format(data);
12899 + mode = &crtc_state->mode;
12900 + memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
12901 + vmode->mpixelclock = mode->crtc_clock * 1000;
12902 + vmode->previous_pixelclock = mode->clock;
12903 + vmode->previous_tmdsclock = mode->clock;
12904 + vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi,
12905 + vmode->mpixelclock);
12906 + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
12907 + vmode->mtmdsclock /= 2;
12909 + if (in_bus_format != hdmi->hdmi_data.enc_in_bus_format ||
12910 + out_bus_format != hdmi->hdmi_data.enc_out_bus_format)
12919 @@ -2442,12 +3050,105 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
12932 + hdmi->plat_data->property_ops;
12934 + if (ops && ops->set_property)
12935 + return ops->set_property(connector, state, property,
12936 + val, hdmi->plat_data->phy_data);
12938 + return -EINVAL;
12950 + hdmi->plat_data->property_ops;
12952 + if (ops && ops->get_property)
12953 + return ops->get_property(connector, state, property,
12954 + val, hdmi->plat_data->phy_data);
12956 + return -EINVAL;
12969 + if (!hdmi->bridge_is_on)
12973 + dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
12980 + hdmi->force_output = val;
12985 + if (!hdmi->bridge_is_on)
12989 + dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
12996 + return hdmi->sink_is_hdmi;
13002 + return hdmi->support_hdmi;
13011 mutex_lock(&hdmi->mutex);
13013 + if (hdmi->force != connector->force) {
13014 + if (!hdmi->disabled && connector->force == DRM_FORCE_OFF)
13015 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI,
13017 + else if (hdmi->disabled && connector->force == DRM_FORCE_ON)
13018 + extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI,
13022 hdmi->force = connector->force;
13025 @@ -2460,15 +3161,98 @@ static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
13047 + hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
13049 + hdmi->plat_data->property_ops;
13087 + dev_err(hdmi->dev, "unexpected mapping: 0x%x\n",
13091 + hdmi->hdmi_data.enc_in_bus_format = color;
13092 + hdmi->hdmi_data.enc_out_bus_format = color;
13098 + hdmi->hdmi_data.enc_in_bus_format =
13101 + hdmi->hdmi_data.enc_in_bus_format =
13105 + if (ops && ops->attach_properties)
13106 + return ops->attach_properties(&hdmi->connector,
13107 + color, hdmi->version,
13108 + hdmi->plat_data->phy_data);
13114 + hdmi->plat_data->property_ops;
13116 + if (ops && ops->destroy_properties)
13117 + return ops->destroy_properties(&hdmi->connector,
13118 + hdmi->plat_data->phy_data);
13123 struct drm_connector *connector = &hdmi->connector;
13124 @@ -2505,6 +3289,8 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi)
13126 drm_connector_attach_encoder(connector, hdmi->bridge.encoder);
13132 notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
13133 @@ -2780,16 +3566,36 @@ static int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
13136 struct dw_hdmi *hdmi = bridge->driver_private;
13137 + void *data = hdmi->plat_data->phy_data;
13139 - hdmi->hdmi_data.enc_out_bus_format =
13140 - bridge_state->output_bus_cfg.format;
13141 + if (bridge_state->output_bus_cfg.format == MEDIA_BUS_FMT_FIXED) {
13142 + if (hdmi->plat_data->get_output_bus_format)
13143 + hdmi->hdmi_data.enc_out_bus_format =
13144 + hdmi->plat_data->get_output_bus_format(data);
13146 + hdmi->hdmi_data.enc_out_bus_format =
13149 + if (hdmi->plat_data->get_input_bus_format)
13150 + hdmi->hdmi_data.enc_in_bus_format =
13151 + hdmi->plat_data->get_input_bus_format(data);
13152 + else if (hdmi->plat_data->input_bus_format)
13153 + hdmi->hdmi_data.enc_in_bus_format =
13154 + hdmi->plat_data->input_bus_format;
13156 + hdmi->hdmi_data.enc_in_bus_format =
13159 + hdmi->hdmi_data.enc_out_bus_format =
13160 + bridge_state->output_bus_cfg.format;
13162 - hdmi->hdmi_data.enc_in_bus_format =
13163 - bridge_state->input_bus_cfg.format;
13164 + hdmi->hdmi_data.enc_in_bus_format =
13165 + bridge_state->input_bus_cfg.format;
13167 - dev_dbg(hdmi->dev, "input format 0x%04x, output format 0x%04x\n",
13168 - bridge_state->input_bus_cfg.format,
13169 - bridge_state->output_bus_cfg.format);
13170 + dev_dbg(hdmi->dev, "input format 0x%04x, output format 0x%04x\n",
13171 + bridge_state->input_bus_cfg.format,
13172 + bridge_state->output_bus_cfg.format);
13177 @@ -2798,10 +3604,22 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
13180 struct dw_hdmi *hdmi = bridge->driver_private;
13186 + if (hdmi->next_bridge) {
13187 + hdmi->next_bridge->encoder = bridge->encoder;
13188 + ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge, bridge, flags);
13190 + DRM_ERROR("Failed to attach bridge with dw-hdmi\n");
13200 @@ -2821,17 +3639,16 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
13203 struct dw_hdmi *hdmi = bridge->driver_private;
13204 + struct drm_connector *connector = &hdmi->connector;
13205 const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
13208 - /* We don't support double-clocked modes */
13209 - if (mode->flags & DRM_MODE_FLAG_DBLCLK)
13210 - return MODE_BAD;
13211 + if (hdmi->next_bridge)
13214 if (pdata->mode_valid)
13215 - mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info,
13216 - mode);
13217 -
13218 + mode_status = pdata->mode_valid(connector, pdata->priv_data,
13223 @@ -2912,6 +3729,12 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
13229 + hdmi->cec_adap = adap;
13233 /* -----------------------------------------------------------------------------
13236 @@ -2937,7 +3760,7 @@ static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
13240 - u8 intr_stat;
13244 if (hdmi->i2c)
13245 @@ -2949,6 +3772,13 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
13251 + dev_dbg(hdmi->dev, "HDCP irq %#x\n", hdcp_stat);
13259 @@ -2956,7 +3786,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
13261 mutex_lock(&hdmi->mutex);
13263 - if (!hdmi->force) {
13264 + if (!hdmi->force && !hdmi->force_logo) {
13268 @@ -2983,7 +3813,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
13272 - u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat;
13277 @@ -3030,22 +3860,21 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
13281 -
13282 - if (status != connector_status_unknown) {
13283 - dev_dbg(hdmi->dev, "EVENT=%s\n",
13284 - status == connector_status_connected ?
13285 - "plugin" : "plugout");
13286 -
13287 - if (hdmi->bridge.dev) {
13288 - drm_helper_hpd_irq_event(hdmi->bridge.dev);
13289 - drm_bridge_hpd_notify(&hdmi->bridge, status);
13290 - }
13291 - }
13295 - hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
13296 - HDMI_IH_MUTE_PHY_STAT0);
13297 -
13298 + if (!hdmi->next_bridge)
13305 + if (hdmi->hdcp)
13306 + hdmi->hdcp->hdcp_isr(hdmi->hdcp, hdcp_stat);
13313 @@ -3179,12 +4008,363 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
13317 - dw_hdmi_i2c_init(hdmi);
13318 + if (hdmi->i2c)
13321 if (hdmi->phy.ops->setup_hpd)
13322 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
13327 + struct dw_hdmi *hdmi = s->private;
13331 + if (!hdmi->phy.enabled) {
13336 + if (hdmi->sink_is_hdmi)
13340 + if (hdmi->hdmi_data.video_mode.mtmdsclock > 340000000)
13341 + val = hdmi->hdmi_data.video_mode.mtmdsclock / 4;
13343 + val = hdmi->hdmi_data.video_mode.mtmdsclock;
13345 + hdmi->hdmi_data.video_mode.mpixelclock, val);
13347 + if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format))
13349 + else if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
13351 + else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
13353 + else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
13357 + val = hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format);
13360 + switch (hdmi->hdmi_data.enc_out_encoding) {
13377 + if (hdmi->version < 0x211a) {
13447 + return single_open(file, dw_hdmi_status_show, inode->i_private);
13487 + struct dw_hdmi *hdmi = s->private;
13493 + seq_puts(s, "\n---------------------------------------------------");
13499 + if ((j - hdmi_reg_table[i].reg_base) % 16 == 0)
13504 + seq_puts(s, "\n---------------------------------------------------\n");
13511 + return single_open(file, dw_hdmi_ctrl_show, inode->i_private);
13519 + ((struct seq_file *)file->private_data)->private;
13524 + return -EFAULT;
13525 + if (sscanf(kbuf, "%x%x", &reg, &val) == -1)
13526 + return -EFAULT;
13528 + dev_err(hdmi->dev, "it is no a hdmi register\n");
13531 + dev_info(hdmi->dev, "/**********hdmi register config******/");
13532 + dev_info(hdmi->dev, "\n reg=%x val=%x\n", reg, val);
13548 + struct dw_hdmi *hdmi = s->private;
13560 + return single_open(file, dw_hdmi_phy_show, inode->i_private);
13568 + ((struct seq_file *)file->private_data)->private;
13573 + return -EFAULT;
13574 + if (sscanf(kbuf, "%x%x", &reg, &val) == -1)
13575 + return -EFAULT;
13577 + dev_err(hdmi->dev, "it is not a hdmi phy register\n");
13580 + dev_info(hdmi->dev, "/*******hdmi phy register config******/");
13581 + dev_info(hdmi->dev, "\n reg=%x val=%x\n", reg, val);
13597 + hdmi->debugfs_dir = debugfs_create_dir("dw-hdmi", NULL);
13598 + if (IS_ERR(hdmi->debugfs_dir)) {
13602 + debugfs_create_file("status", 0400, hdmi->debugfs_dir,
13604 + debugfs_create_file("ctrl", 0400, hdmi->debugfs_dir,
13606 + debugfs_create_file("phy", 0400, hdmi->debugfs_dir,
13617 + .regs = hdmi->regs,
13632 + hdmi->hdcp_dev = platform_device_register_full(&hdcp_device_info);
13633 + if (IS_ERR(hdmi->hdcp_dev))
13636 + hdmi->hdcp = hdmi->hdcp_dev->dev.platform_data;
13645 + dss = of_find_node_by_name(NULL, "display-subsystem");
13647 + dev_err(hdmi->dev, "can't find display-subsystem\n");
13648 + return -ENODEV;
13653 + dev_err(hdmi->dev, "can't find route\n");
13655 + return -ENODEV;
13659 + route_hdmi = of_find_node_by_name(route, "route-hdmi");
13661 + dev_err(hdmi->dev, "can't find route-hdmi\n");
13663 + return -ENODEV;
13667 + hdmi->force_logo =
13668 + of_property_read_bool(route_hdmi, "force-output");
13675 /* -----------------------------------------------------------------------------
13678 @@ -3193,6 +4373,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13680 struct device *dev = &pdev->dev;
13681 struct device_node *np = dev->of_node;
13686 @@ -3205,11 +4386,13 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13694 return ERR_PTR(-ENOMEM);
13696 + hdmi->connector.stereo_allowed = 1;
13697 hdmi->plat_data = plat_data;
13698 hdmi->dev = dev;
13699 hdmi->sample_rate = 48000;
13700 @@ -3340,7 +4523,24 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13702 hdmi->phy.name);
13704 - dw_hdmi_init_hw(hdmi);
13709 + hdmi->initialized = false;
13712 + hdmi_readb(hdmi, HDMI_FC_EXCTRLDUR)) || hdmi->force_logo) {
13713 + hdmi->mc_clkdis = hdmi_readb(hdmi, HDMI_MC_CLKDIS);
13714 + hdmi->disabled = false;
13715 + hdmi->bridge_is_on = true;
13716 + hdmi->phy.enabled = true;
13717 + hdmi->initialized = true;
13719 + hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
13726 @@ -3348,6 +4548,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13730 + hdmi->irq = irq;
13734 @@ -3383,8 +4584,20 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13735 hdmi->ddc = dw_hdmi_i2c_adapter(hdmi);
13736 if (IS_ERR(hdmi->ddc))
13737 hdmi->ddc = NULL;
13742 + if (of_property_read_u32(np, "ddc-i2c-scl-high-time-ns",
13743 + &hdmi->i2c->scl_high_ns))
13744 + hdmi->i2c->scl_high_ns = 4708;
13745 + if (of_property_read_u32(np, "ddc-i2c-scl-low-time-ns",
13746 + &hdmi->i2c->scl_low_ns))
13747 + hdmi->i2c->scl_low_ns = 4916;
13752 hdmi->bridge.driver_private = hdmi;
13753 hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
13754 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
13755 @@ -3393,6 +4606,30 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13756 hdmi->bridge.of_node = pdev->dev.of_node;
13759 + endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node, 1, -1);
13767 + ret = -ENODEV;
13771 + hdmi->next_bridge = of_drm_find_bridge(remote);
13773 + if (!hdmi->next_bridge) {
13774 + dev_err(hdmi->dev, "can't find next bridge\n");
13775 + ret = -EPROBE_DEFER;
13779 + hdmi->sink_is_hdmi = true;
13780 + hdmi->sink_has_audio = true;
13786 @@ -3446,8 +4683,40 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13787 hdmi->cec = platform_device_register_full(&pdevinfo);
13790 + hdmi->extcon = devm_extcon_dev_allocate(hdmi->dev, dw_hdmi_cable);
13791 + if (IS_ERR(hdmi->extcon)) {
13792 + ret = PTR_ERR(hdmi->extcon);
13793 + dev_err(hdmi->dev, "allocate extcon failed: %d\n", ret);
13797 + ret = devm_extcon_dev_register(hdmi->dev, hdmi->extcon);
13799 + dev_err(hdmi->dev, "failed to register extcon: %d\n",
13804 + ret = extcon_set_property_capability(hdmi->extcon, EXTCON_DISP_HDMI,
13807 + dev_err(hdmi->dev,
13813 drm_bridge_add(&hdmi->bridge);
13817 + if (of_property_read_bool(np, "scramble-low-rates"))
13818 + hdmi->scramble_low_rates = true;
13820 + if (of_property_read_bool(np, "hdcp1x-enable"))
13827 @@ -3457,7 +4726,10 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
13829 clk_disable_unprepare(hdmi->isfr_clk);
13831 - i2c_put_adapter(hdmi->ddc);
13832 + if (hdmi->i2c)
13833 + i2c_del_adapter(&hdmi->i2c->adap);
13835 + i2c_put_adapter(hdmi->ddc);
13839 @@ -3465,16 +4737,35 @@ EXPORT_SYMBOL_GPL(dw_hdmi_probe);
13843 + if (hdmi->irq)
13844 + disable_irq(hdmi->irq);
13846 + cancel_delayed_work(&hdmi->work);
13847 + flush_workqueue(hdmi->workqueue);
13848 + destroy_workqueue(hdmi->workqueue);
13850 + debugfs_remove_recursive(hdmi->debugfs_dir);
13852 drm_bridge_remove(&hdmi->bridge);
13854 if (hdmi->audio && !IS_ERR(hdmi->audio))
13855 platform_device_unregister(hdmi->audio);
13856 + if (hdmi->hdcp_dev && !IS_ERR(hdmi->hdcp_dev))
13857 + platform_device_unregister(hdmi->hdcp_dev);
13858 if (!IS_ERR(hdmi->cec))
13859 platform_device_unregister(hdmi->cec);
13864 + if (!hdmi->next_bridge) {
13866 + hdmi->connector.funcs->destroy(&hdmi->connector);
13869 + if (hdmi->bridge.encoder)
13870 + hdmi->bridge.encoder->funcs->destroy(hdmi->bridge.encoder);
13872 clk_disable_unprepare(hdmi->iahb_clk);
13873 clk_disable_unprepare(hdmi->isfr_clk);
13874 if (hdmi->cec_clk)
13875 @@ -3492,7 +4783,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
13879 - const struct dw_hdmi_plat_data *plat_data)
13884 @@ -3508,6 +4799,9 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
13888 + if (!hdmi->next_bridge)
13889 + plat_data->connector = &hdmi->connector;
13894 @@ -3518,9 +4812,87 @@ void dw_hdmi_unbind(struct dw_hdmi *hdmi)
13912 + if (!hdmi->next_bridge) {
13915 + hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
13928 + mutex_lock(&hdmi->mutex);
13936 + if (!hdmi->disabled) {
13937 + hdmi->disabled = true;
13941 + mutex_unlock(&hdmi->mutex);
13943 + if (hdmi->irq)
13944 + disable_irq(hdmi->irq);
13945 + cancel_delayed_work(&hdmi->work);
13946 + flush_workqueue(hdmi->workqueue);
13947 + pinctrl_pm_select_sleep_state(hdmi->dev);
13953 - dw_hdmi_init_hw(hdmi);
13957 + pinctrl_pm_select_default_state(hdmi->dev);
13958 + mutex_lock(&hdmi->mutex);
13960 + if (hdmi->i2c)
13962 + if (hdmi->irq)
13963 + enable_irq(hdmi->irq);
13966 + * HDMI plug in -> system sleep -> HDMI plug out -> system wake up.
13967 + * At this time, cat /sys/class/drm/card 0-HDMI-A-1/status is connected.
13971 + if (hdmi->connector.status == connector_status_connected) {
13972 + if (hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data) ==
13974 + hdmi->hpd_state = false;
13975 + mod_delayed_work(hdmi->workqueue, &hdmi->work,
13979 + mutex_unlock(&hdmi->mutex);
13983 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
13985 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
13986 +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
13987 @@ -509,6 +509,51 @@
14036 /* I2C Master Registers (E-DDC) */
14039 @@ -529,6 +574,7 @@
14047 @@ -842,6 +888,10 @@ enum {
14058 @@ -1085,6 +1135,11 @@ enum {
14070 diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mip…
14072 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
14073 +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
14074 @@ -244,7 +244,7 @@ struct dw_mipi_dsi {
14078 - struct clk *pclk;
14083 @@ -316,15 +316,10 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
14084 const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
14087 + int max_data_lanes = dsi->plat_data->max_data_lanes;
14090 - if (device->lanes > dsi->plat_data->max_data_lanes) {
14091 - dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
14092 - device->lanes);
14093 - return -EINVAL;
14094 - }
14095 -
14096 - dsi->lanes = device->lanes;
14097 + dsi->lanes = (device->lanes > max_data_lanes) ? device->lanes / 2 : device->lanes;
14098 dsi->channel = device->channel;
14099 dsi->format = device->format;
14100 dsi->mode_flags = device->mode_flags;
14101 @@ -599,8 +594,14 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
14105 + const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
14107 + if (phy_ops->power_off)
14108 + phy_ops->power_off(dsi->plat_data->priv_data);
14112 + pm_runtime_put(dsi->dev);
14116 @@ -715,16 +716,16 @@ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
14120 - u32 frac, lbcc;
14123 lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8;
14125 - frac = lbcc % mode->clock;
14126 - lbcc = lbcc / mode->clock;
14127 - if (frac)
14128 - lbcc++;
14129 + if (mode->clock == 0) {
14134 - return lbcc;
14135 + return DIV_ROUND_CLOSEST_ULL(lbcc, mode->clock);
14139 @@ -837,13 +838,13 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
14140 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
14143 - DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
14146 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
14150 - DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
14155 @@ -857,7 +858,6 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
14159 - const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
14162 * Switch to command mode before panel-bridge post_disable &
14163 @@ -866,6 +866,8 @@ static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
14167 + if (dsi->slave)
14168 + dw_mipi_dsi_set_mode(dsi->slave, 0);
14171 * TODO Only way found to call panel-bridge post_disable &
14172 @@ -876,18 +878,10 @@ static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
14173 if (dsi->panel_bridge->funcs->post_disable)
14174 dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
14176 - if (phy_ops->power_off)
14177 - phy_ops->power_off(dsi->plat_data->priv_data);
14178 -
14179 - if (dsi->slave) {
14180 + if (dsi->slave)
14181 dw_mipi_dsi_disable(dsi->slave);
14182 - clk_disable_unprepare(dsi->slave->pclk);
14183 - pm_runtime_put(dsi->slave->dev);
14184 - }
14185 - dw_mipi_dsi_disable(dsi);
14187 - clk_disable_unprepare(dsi->pclk);
14188 - pm_runtime_put(dsi->dev);
14193 @@ -912,7 +906,11 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
14197 - clk_prepare_enable(dsi->pclk);
14198 + if (dsi->apb_rst) {
14199 + reset_control_assert(dsi->apb_rst);
14201 + reset_control_deassert(dsi->apb_rst);
14204 ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi->mode_flags,
14205 lanes, dsi->format, &dsi->lane_mbps);
14206 @@ -939,15 +937,15 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
14210 + if (phy_ops->power_on)
14211 + phy_ops->power_on(dsi->plat_data->priv_data);
14217 /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */
14219 -
14220 - if (phy_ops->power_on)
14221 - phy_ops->power_on(dsi->plat_data->priv_data);
14225 @@ -959,16 +957,25 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
14227 if (dsi->slave)
14228 dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode);
14230 + DRM_DEV_INFO(dsi->dev, "final DSI-Link bandwidth: %u x %d Mbps\n",
14231 + dsi->lane_mbps, dsi->slave ? dsi->lanes * 2 : dsi->lanes);
14238 - /* Switch to video mode for panel-bridge enable & panel enable */
14239 - dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO);
14240 - if (dsi->slave)
14241 - dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO);
14242 + /* Switch to video/cmd mode for panel-bridge enable & panel enable */
14243 + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
14245 + if (dsi->slave)
14246 + dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO);
14249 + if (dsi->slave)
14250 + dw_mipi_dsi_set_mode(dsi->slave, 0);
14255 @@ -1103,7 +1110,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
14258 struct device *dev = &pdev->dev;
14259 - struct reset_control *apb_rst;
14263 @@ -1129,20 +1135,13 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
14264 dsi->base = plat_data->base;
14267 - dsi->pclk = devm_clk_get(dev, "pclk");
14268 - if (IS_ERR(dsi->pclk)) {
14269 - ret = PTR_ERR(dsi->pclk);
14270 - dev_err(dev, "Unable to get pclk: %d\n", ret);
14271 - return ERR_PTR(ret);
14272 - }
14273 -
14278 - apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
14279 - if (IS_ERR(apb_rst)) {
14280 - ret = PTR_ERR(apb_rst);
14281 + dsi->apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
14282 + if (IS_ERR(dsi->apb_rst)) {
14283 + ret = PTR_ERR(dsi->apb_rst);
14285 if (ret != -EPROBE_DEFER)
14287 @@ -1150,20 +1149,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
14291 - if (apb_rst) {
14292 - ret = clk_prepare_enable(dsi->pclk);
14293 - if (ret) {
14294 - dev_err(dev, "%s: Failed to enable pclk\n", __func__);
14295 - return ERR_PTR(ret);
14296 - }
14297 -
14298 - reset_control_assert(apb_rst);
14299 - usleep_range(10, 20);
14300 - reset_control_deassert(apb_rst);
14301 -
14302 - clk_disable_unprepare(dsi->pclk);
14303 - }
14304 -
14308 @@ -1247,6 +1232,12 @@ void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi)
14314 + return drm_panel_bridge_connector(dsi->panel_bridge);
14318 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
14321 diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
14323 --- a/drivers/gpu/drm/drm_atomic_helper.c
14325 @@ -296,12 +296,14 @@ update_connector_routing(struct drm_atomic_state *state,
14326 if (old_connector_state->crtc != new_connector_state->crtc) {
14327 if (old_connector_state->crtc) {
14328 crtc_state = drm_atomic_get_new_crtc_state(state, old_connector_state->crtc);
14329 - crtc_state->connectors_changed = true;
14330 + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
14331 + crtc_state->connectors_changed = true;
14334 if (new_connector_state->crtc) {
14335 crtc_state = drm_atomic_get_new_crtc_state(state, new_connector_state->crtc);
14336 - crtc_state->connectors_changed = true;
14337 + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
14338 + crtc_state->connectors_changed = true;
14342 @@ -386,7 +388,8 @@ update_connector_routing(struct drm_atomic_state *state,
14346 - crtc_state->connectors_changed = true;
14347 + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
14348 + crtc_state->connectors_changed = true;
14351 connector->base.id,
14352 @@ -3554,6 +3557,9 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
14353 replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
14354 replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
14355 replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
14357 + replaced |= drm_property_replace_blob(&crtc_state->cubic_lut, NULL);
14359 crtc_state->color_mgmt_changed |= replaced;
14362 diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
14364 --- a/drivers/gpu/drm/drm_atomic_state_helper.c
14366 @@ -141,6 +141,10 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
14367 drm_property_blob_get(state->ctm);
14368 if (state->gamma_lut)
14369 drm_property_blob_get(state->gamma_lut);
14371 + if (state->cubic_lut)
14372 + drm_property_blob_get(state->cubic_lut);
14374 state->mode_changed = false;
14375 state->active_changed = false;
14376 state->planes_changed = false;
14377 @@ -213,6 +217,9 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
14378 drm_property_blob_put(state->degamma_lut);
14379 drm_property_blob_put(state->ctm);
14380 drm_property_blob_put(state->gamma_lut);
14382 + drm_property_blob_put(state->cubic_lut);
14387 diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
14389 --- a/drivers/gpu/drm/drm_atomic_uapi.c
14391 @@ -459,6 +459,16 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
14393 state->color_mgmt_changed |= replaced;
14396 + } else if (property == config->cubic_lut_property) {
14398 + &state->cubic_lut,
14400 + -1, sizeof(struct drm_color_lut),
14402 + state->color_mgmt_changed |= replaced;
14405 } else if (property == config->prop_out_fence_ptr) {
14408 @@ -501,6 +511,10 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
14409 *val = (state->ctm) ? state->ctm->base.id : 0;
14410 else if (property == config->gamma_lut_property)
14411 *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
14413 + else if (property == config->cubic_lut_property)
14414 + *val = (state->cubic_lut) ? state->cubic_lut->base.id : 0;
14416 else if (property == config->prop_out_fence_ptr)
14418 else if (crtc->funcs->atomic_get_property)
14419 diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
14421 --- a/drivers/gpu/drm/drm_auth.c
14423 @@ -135,18 +135,16 @@ static void drm_set_master(struct drm_device *dev, struct drm_file *fpriv,
14427 - struct drm_master *new_master;
14429 lockdep_assert_held_once(&dev->master_mutex);
14431 WARN_ON(fpriv->is_master);
14432 old_master = fpriv->master;
14433 - new_master = drm_master_create(dev);
14434 - if (!new_master)
14435 + fpriv->master = drm_master_create(dev);
14436 + if (!fpriv->master) {
14437 + fpriv->master = old_master;
14438 return -ENOMEM;
14439 - spin_lock(&fpriv->master_lookup_lock);
14440 - fpriv->master = new_master;
14441 - spin_unlock(&fpriv->master_lookup_lock);
14444 fpriv->is_master = 1;
14445 fpriv->authenticated = 1;
14446 @@ -304,13 +302,10 @@ int drm_master_open(struct drm_file *file_priv)
14449 mutex_lock(&dev->master_mutex);
14450 - if (!dev->master) {
14451 + if (!dev->master)
14453 - } else {
14454 - spin_lock(&file_priv->master_lookup_lock);
14456 file_priv->master = drm_master_get(dev->master);
14457 - spin_unlock(&file_priv->master_lookup_lock);
14458 - }
14459 mutex_unlock(&dev->master_mutex);
14462 @@ -376,31 +371,6 @@ struct drm_master *drm_master_get(struct drm_master *master)
14466 -/**
14467 - * drm_file_get_master - reference &drm_file.master of @file_priv
14468 - * @file_priv: DRM file private
14469 - *
14470 - * Increments the reference count of @file_priv's &drm_file.master and returns
14471 - * the &drm_file.master. If @file_priv has no &drm_file.master, returns NULL.
14472 - *
14473 - * Master pointers returned from this function should be unreferenced using
14474 - * drm_master_put().
14475 - */
14476 -struct drm_master *drm_file_get_master(struct drm_file *file_priv)
14477 -{
14478 - struct drm_master *master = NULL;
14479 -
14480 - spin_lock(&file_priv->master_lookup_lock);
14481 - if (!file_priv->master)
14482 - goto unlock;
14483 - master = drm_master_get(file_priv->master);
14484 -
14485 -unlock:
14486 - spin_unlock(&file_priv->master_lookup_lock);
14487 - return master;
14488 -}
14489 -EXPORT_SYMBOL(drm_file_get_master);
14490 -
14494 diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
14496 --- a/drivers/gpu/drm/drm_color_mgmt.c
14498 @@ -33,7 +33,7 @@
14502 - * Color management or color space adjustments is supported through a set of 5
14507 @@ -60,7 +60,7 @@
14511 - * lookup through the gamma LUT. The data is interpreted as a struct
14516 @@ -68,13 +68,40 @@
14517 * boot-up state too. Drivers can access the blob for the color conversion
14526 + * as a 3D coordinate. The LUT is subsampled as 8-bit (or more) precision
14538 + * boot-up state too. Drivers can access this blob through
14545 + * largest size, and sub-sample smaller sized LUTs appropriately.
14549 - * after the transformation matrix to data sent to the connector. The
14550 - * data is interpreted as an array of &struct drm_color_lut elements.
14551 - * Hardware might choose not to use the full precision of the LUT elements
14552 - * nor use all the elements of the LUT (for example the hardware might
14553 - * choose to interpolate between LUT[0] and LUT[4]).
14561 * linear/pass-thru gamma table should be used. This is generally the
14562 diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
14564 --- a/drivers/gpu/drm/drm_crtc_internal.h
14566 @@ -276,7 +276,29 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
14596 diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
14598 --- a/drivers/gpu/drm/drm_debugfs.c
14600 @@ -91,7 +91,6 @@ static int drm_clients_info(struct seq_file *m, void *data)
14601 mutex_lock(&dev->filelist_mutex);
14602 list_for_each_entry_reverse(priv, &dev->filelist, lhead) {
14604 - bool is_current_master = drm_is_current_master(priv);
14606 rcu_read_lock(); /* locks pid_task()->comm */
14607 task = pid_task(priv->pid, PIDTYPE_PID);
14608 @@ -100,7 +99,7 @@ static int drm_clients_info(struct seq_file *m, void *data)
14609 task ? task->comm : "<unknown>",
14610 pid_vnr(priv->pid),
14611 priv->minor->index,
14612 - is_current_master ? 'y' : 'n',
14614 priv->authenticated ? 'y' : 'n',
14616 priv->magic);
14617 diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
14619 --- a/drivers/gpu/drm/drm_edid.c
14621 @@ -1835,20 +1835,11 @@ static void connector_bad_edid(struct drm_connector *connector,
14625 - u8 last_block;
14626 -
14627 - /*
14628 - * 0x7e in the EDID is the number of extension blocks. The EDID
14629 - * is 1 (base block) + num_ext_blocks big. That means we can think
14630 - * of 0x7e in the EDID of the _index_ of the last block in the
14631 - * combined chunk of memory.
14632 - */
14633 - last_block = edid[0x7e];
14637 - if (last_block < num_blocks)
14638 - connector->real_edid_checksum =
14639 - drm_edid_block_checksum(edid + last_block * EDID_LENGTH);
14640 + connector->real_edid_checksum =
14643 if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
14645 @@ -4861,6 +4852,43 @@ static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
14646 info->rgb_quant_range_selectable = true;
14689 @@ -4914,6 +4942,76 @@ static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
14698 + struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
14702 + drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
14703 + &hdmi->max_frl_rate_per_lane);
14704 + hdmi_dsc->v_1p2 = hf_vsdb[11] & DRM_EDID_DSC_1P2;
14706 + if (hdmi_dsc->v_1p2) {
14707 + hdmi_dsc->native_420 = hf_vsdb[11] & DRM_EDID_DSC_NATIVE_420;
14708 + hdmi_dsc->all_bpp = hf_vsdb[11] & DRM_EDID_DSC_ALL_BPP;
14711 + hdmi_dsc->bpc_supported = 16;
14713 + hdmi_dsc->bpc_supported = 12;
14715 + hdmi_dsc->bpc_supported = 10;
14717 + hdmi_dsc->bpc_supported = 0;
14720 + drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
14721 + &hdmi_dsc->max_frl_rate_per_lane);
14722 + hdmi_dsc->total_chunk_kbytes = hf_vsdb[13] & DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
14727 + hdmi_dsc->max_slices = 1;
14728 + hdmi_dsc->clk_per_slice = 340;
14731 + hdmi_dsc->max_slices = 2;
14732 + hdmi_dsc->clk_per_slice = 340;
14735 + hdmi_dsc->max_slices = 4;
14736 + hdmi_dsc->clk_per_slice = 340;
14739 + hdmi_dsc->max_slices = 8;
14740 + hdmi_dsc->clk_per_slice = 340;
14743 + hdmi_dsc->max_slices = 8;
14744 + hdmi_dsc->clk_per_slice = 400;
14747 + hdmi_dsc->max_slices = 12;
14748 + hdmi_dsc->clk_per_slice = 400;
14751 + hdmi_dsc->max_slices = 16;
14752 + hdmi_dsc->clk_per_slice = 400;
14756 + hdmi_dsc->max_slices = 0;
14757 + hdmi_dsc->clk_per_slice = 0;
14766 diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
14768 --- a/drivers/gpu/drm/drm_file.c
14770 @@ -177,7 +177,6 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
14771 init_waitqueue_head(&file->event_wait);
14772 file->event_space = 4096; /* set aside 4k for event buffer */
14774 - spin_lock_init(&file->master_lookup_lock);
14775 mutex_init(&file->event_read_lock);
14778 @@ -776,20 +775,19 @@ void drm_event_cancel_free(struct drm_device *dev,
14782 - * drm_send_event_locked - send DRM event to file descriptor
14783 + * drm_send_event_helper - send DRM event to file descriptor
14789 - * This function sends the event @e, initialized with drm_event_reserve_init(),
14790 - * to its associated userspace DRM file. Callers must already hold
14791 - * &drm_device.event_lock, see drm_send_event() for the unlocked version.
14792 - *
14793 - * Note that the core will take care of unlinking and disarming events when the
14794 - * corresponding DRM file is closed. Drivers need not worry about whether the
14795 - * DRM file for this event still exists and can call this function upon
14796 - * completion of the asynchronous work unconditionally.
14802 -void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
14806 assert_spin_locked(&dev->event_lock);
14808 @@ -800,7 +798,10 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
14811 if (e->fence) {
14812 - dma_fence_signal(e->fence);
14814 + dma_fence_signal_timestamp(e->fence, timestamp);
14816 + dma_fence_signal(e->fence);
14817 dma_fence_put(e->fence);
14820 @@ -815,6 +816,48 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
14821 wake_up_interruptible_poll(&e->file_priv->event_wait,
14826 + * drm_send_event_timestamp_locked - send DRM event to file descriptor
14849 + * drm_send_event_locked - send DRM event to file descriptor
14869 @@ -837,7 +880,7 @@ void drm_send_event(struct drm_device *dev, struct drm_pending_event *e)
14872 spin_lock_irqsave(&dev->event_lock, irqflags);
14873 - drm_send_event_locked(dev, e);
14875 spin_unlock_irqrestore(&dev->event_lock, irqflags);
14878 diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
14880 --- a/drivers/gpu/drm/drm_fourcc.c
14882 @@ -278,6 +278,16 @@ const struct drm_format_info *__drm_format_info(u32 format)
14899 diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
14901 --- a/drivers/gpu/drm/drm_ioctl.c
14903 @@ -537,6 +537,7 @@ int drm_version(struct drm_device *dev, void *data,
14910 return -EACCES;
14911 @@ -555,6 +556,7 @@ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
14914 return -EACCES;
14919 @@ -678,9 +680,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
14923 - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0),
14924 - DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, 0),
14925 - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, 0),
14932 diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
14934 --- a/drivers/gpu/drm/drm_lease.c
14936 @@ -107,19 +107,10 @@ static bool _drm_has_leased(struct drm_master *master, int id)
14940 - bool ret;
14941 - struct drm_master *master;
14942 -
14943 - if (!file_priv)
14944 + if (!file_priv || !file_priv->master)
14947 - master = drm_file_get_master(file_priv);
14948 - if (!master)
14949 - return true;
14950 - ret = _drm_lease_held_master(master, id);
14951 - drm_master_put(&master);
14952 -
14953 - return ret;
14954 + return _drm_lease_held_master(file_priv->master, id);
14958 @@ -138,22 +129,13 @@ bool drm_lease_held(struct drm_file *file_priv, int id)
14962 - if (!file_priv)
14963 + if (!file_priv || !file_priv->master || !file_priv->master->lessor)
14966 - master = drm_file_get_master(file_priv);
14967 - if (!master)
14968 - return true;
14969 - if (!master->lessor) {
14970 - ret = true;
14971 - goto out;
14972 - }
14973 + master = file_priv->master;
14974 mutex_lock(&master->dev->mode_config.idr_mutex);
14976 mutex_unlock(&master->dev->mode_config.idr_mutex);
14977 -
14978 -out:
14979 - drm_master_put(&master);
14983 @@ -173,16 +155,10 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
14987 - if (!file_priv)
14988 + if (!file_priv || !file_priv->master || !file_priv->master->lessor)
14991 - master = drm_file_get_master(file_priv);
14992 - if (!master)
14993 - return crtcs_in;
14994 - if (!master->lessor) {
14995 - crtcs_out = crtcs_in;
14996 - goto out;
14997 - }
14998 + master = file_priv->master;
14999 dev = master->dev;
15002 @@ -201,9 +177,6 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
15005 mutex_unlock(&master->dev->mode_config.idr_mutex);
15006 -
15007 -out:
15008 - drm_master_put(&master);
15012 @@ -517,7 +490,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15016 - struct drm_master *lessor;
15017 + struct drm_master *lessor = lessor_priv->master;
15020 struct file *lessor_file = lessor_priv->filp;
15021 @@ -529,6 +502,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15023 return -EOPNOTSUPP;
15025 + /* Do not allow sub-leases */
15026 + if (lessor->lessor) {
15028 + return -EINVAL;
15032 if (cl->object_count == 0) {
15034 @@ -540,22 +519,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15035 return -EINVAL;
15038 - lessor = drm_file_get_master(lessor_priv);
15039 - /* Do not allow sub-leases */
15040 - if (lessor->lessor) {
15041 - DRM_DEBUG_LEASE("recursive leasing not allowed\n");
15042 - ret = -EINVAL;
15043 - goto out_lessor;
15044 - }
15045 -
15046 object_count = cl->object_count;
15048 object_ids = memdup_user(u64_to_user_ptr(cl->object_ids),
15050 - if (IS_ERR(object_ids)) {
15051 - ret = PTR_ERR(object_ids);
15052 - goto out_lessor;
15053 - }
15059 @@ -566,15 +535,14 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15063 - goto out_lessor;
15068 fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
15071 - ret = fd;
15072 - goto out_lessor;
15077 @@ -610,7 +578,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15081 - drm_master_put(&lessor);
15085 @@ -620,8 +587,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
15089 -out_lessor:
15090 - drm_master_put(&lessor);
15094 @@ -644,7 +609,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
15096 __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
15097 __u32 count_lessees = arg->count_lessees;
15098 - struct drm_master *lessor, *lessee;
15099 + struct drm_master *lessor = lessor_priv->master, *lessee;
15103 @@ -655,7 +620,6 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
15105 return -EOPNOTSUPP;
15107 - lessor = drm_file_get_master(lessor_priv);
15108 DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
15110 mutex_lock(&dev->mode_config.idr_mutex);
15111 @@ -679,7 +643,6 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
15112 arg->count_lessees = count;
15114 mutex_unlock(&dev->mode_config.idr_mutex);
15115 - drm_master_put(&lessor);
15119 @@ -699,7 +662,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
15121 __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
15122 __u32 count_objects = arg->count_objects;
15123 - struct drm_master *lessee;
15124 + struct drm_master *lessee = lessee_priv->master;
15128 @@ -713,7 +676,6 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
15130 return -EOPNOTSUPP;
15132 - lessee = drm_file_get_master(lessee_priv);
15133 DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
15135 mutex_lock(&dev->mode_config.idr_mutex);
15136 @@ -741,7 +703,6 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
15137 arg->count_objects = count;
15139 mutex_unlock(&dev->mode_config.idr_mutex);
15140 - drm_master_put(&lessee);
15144 @@ -760,7 +721,7 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
15148 - struct drm_master *lessor;
15149 + struct drm_master *lessor = lessor_priv->master;
15153 @@ -770,7 +731,6 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
15155 return -EOPNOTSUPP;
15157 - lessor = drm_file_get_master(lessor_priv);
15158 mutex_lock(&dev->mode_config.idr_mutex);
15160 lessee = _drm_find_lessee(lessor, arg->lessee_id);
15161 @@ -791,7 +751,6 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
15164 mutex_unlock(&dev->mode_config.idr_mutex);
15165 - drm_master_put(&lessor);
15169 diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
15171 --- a/drivers/gpu/drm/drm_mipi_dsi.c
15173 @@ -355,6 +355,7 @@ static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
15175 if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
15176 msg->flags |= MIPI_DSI_MSG_USE_LPM;
15177 + msg->flags |= MIPI_DSI_MSG_LASTCOMMAND;
15179 return ops->transfer(dsi->host, msg);
15181 diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
15183 --- a/drivers/gpu/drm/drm_mode_config.c
15185 @@ -364,6 +364,22 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
15186 return -ENOMEM;
15187 dev->mode_config.gamma_lut_size_property = prop;
15194 + return -ENOMEM;
15195 + dev->mode_config.cubic_lut_property = prop;
15201 + return -ENOMEM;
15202 + dev->mode_config.cubic_lut_size_property = prop;
15208 diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
15210 --- a/drivers/gpu/drm/drm_modes.c
15212 @@ -1940,6 +1940,7 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
15213 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
15214 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
15219 * drm_crtc_convert_umode - convert a modeinfo into a drm_display_mode
15220 @@ -2016,6 +2017,7 @@ int drm_mode_convert_umode(struct drm_device *dev,
15227 * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
15228 diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
15230 --- a/drivers/gpu/drm/drm_prime.c
15232 @@ -784,6 +784,28 @@ int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
15237 + * drm_gem_dmabuf_get_uuid - dma_buf get_uuid implementation for GEM
15248 + struct drm_gem_object *obj = dma_buf->priv;
15249 + struct drm_device *dev = obj->dev;
15251 + if (!dev->driver->gem_prime_get_uuid)
15252 + return -ENODEV;
15254 + return dev->driver->gem_prime_get_uuid(obj, uuid);
15261 @@ -794,6 +816,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
15269 diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
15271 --- a/drivers/gpu/drm/drm_vblank.c
15273 @@ -1000,7 +1000,14 @@ static void send_vblank_event(struct drm_device *dev,
15276 trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq);
15277 - drm_send_event_locked(dev, &e->base);
15282 + * retire-fence timestamp to match exactly with HW vsync as it uses it
15285 + drm_send_event_timestamp_locked(dev, &e->base, now);
15289 diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h b/drivers/gpu/drm/hisilicon/kirin/kiri…
15291 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h
15293 @@ -1,7 +1,7 @@
15294 /* SPDX-License-Identifier: GPL-2.0-only */
15296 - * Copyright (c) 2016 Linaro Limited.
15297 - * Copyright (c) 2014-2016 Hisilicon Limited.
15299 + * Copyright (c) 2014-2016,2019 Hisilicon Limited.
15303 diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
15305 --- a/drivers/gpu/drm/panel/Kconfig
15307 @@ -233,7 +233,6 @@ config DRM_PANEL_OLIMEX_LCD_OLINUXINO
15311 - select CRC32
15315 diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
15317 --- a/drivers/gpu/drm/panel/Makefile
15319 @@ -53,3 +53,5 @@ obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
15320 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
15321 obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o
15322 obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
15324 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/gpu/drm/panel
15325 diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
15327 --- a/drivers/gpu/drm/panel/panel-simple.c
15328 +++ b/drivers/gpu/drm/panel/panel-simple.c
15329 @@ -30,6 +30,7 @@
15337 @@ -37,6 +38,25 @@
15343 +#include "panel-simple.h"
15363 @@ -83,6 +103,10 @@ struct panel_desc {
15374 @@ -90,17 +114,24 @@ struct panel_desc {
15399 @@ -109,10 +140,12 @@ struct panel_simple {
15412 @@ -121,6 +154,124 @@ static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
15426 + return -EINVAL;
15430 + return -ENOMEM;
15439 + len -= sizeof(*header);
15441 + if (header->payload_length > len)
15442 + return -EINVAL;
15444 + d += header->payload_length;
15445 + len -= header->payload_length;
15450 + return -EINVAL;
15452 + seq->cmd_cnt = cnt;
15453 + seq->cmds = devm_kcalloc(dev, cnt, sizeof(*desc), GFP_KERNEL);
15454 + if (!seq->cmds)
15455 + return -ENOMEM;
15461 + len -= sizeof(*header);
15464 + desc = &seq->cmds[i];
15465 + desc->header = *header;
15466 + desc->payload = d;
15468 + d += header->payload_length;
15469 + len -= header->payload_length;
15478 + struct device *dev = panel->base.dev;
15479 + struct mipi_dsi_device *dsi = panel->dsi;
15484 + return -EINVAL;
15486 + return -EINVAL;
15488 + for (i = 0; i < seq->cmd_cnt; i++) {
15489 + struct panel_cmd_desc *cmd = &seq->cmds[i];
15491 + switch (cmd->header.data_type) {
15493 + err = mipi_dsi_compression_mode(dsi, cmd->payload[0]);
15499 + err = mipi_dsi_generic_write(dsi, cmd->payload,
15500 + cmd->header.payload_length);
15505 + err = mipi_dsi_dcs_write_buffer(dsi, cmd->payload,
15506 + cmd->header.payload_length);
15509 + if (!panel->pps) {
15510 + panel->pps = devm_kzalloc(dev, sizeof(*panel->pps),
15512 + if (!panel->pps)
15513 + return -ENOMEM;
15515 + memcpy(panel->pps, cmd->payload, cmd->header.payload_length);
15518 + err = mipi_dsi_picture_parameter_set(dsi, panel->pps);
15521 + return -EINVAL;
15527 + if (cmd->header.delay)
15528 + msleep(cmd->header.delay);
15537 @@ -219,17 +370,72 @@ static int panel_simple_get_non_edid_modes(struct panel_simple *panel,
15541 - connector->display_info.bpc = panel->desc->bpc;
15542 - connector->display_info.width_mm = panel->desc->size.width;
15543 - connector->display_info.height_mm = panel->desc->size.height;
15544 + if (panel->desc->bpc)
15545 + connector->display_info.bpc = panel->desc->bpc;
15546 + if (panel->desc->size.width)
15547 + connector->display_info.width_mm = panel->desc->size.width;
15548 + if (panel->desc->size.height)
15549 + connector->display_info.height_mm = panel->desc->size.height;
15550 if (panel->desc->bus_format)
15551 drm_display_info_set_bus_formats(&connector->display_info,
15552 &panel->desc->bus_format, 1);
15553 - connector->display_info.bus_flags = panel->desc->bus_flags;
15554 + if (panel->desc->bus_flags)
15555 + connector->display_info.bus_flags = panel->desc->bus_flags;
15564 + if (p->power_invert) {
15565 + if (regulator_is_enabled(p->supply) > 0)
15566 + regulator_disable(p->supply);
15568 + err = regulator_enable(p->supply);
15580 + if (p->power_invert) {
15581 + if (!regulator_is_enabled(p->supply)) {
15582 + err = regulator_enable(p->supply);
15587 + regulator_disable(p->supply);
15600 + dev_err(panel->dev, "failed to enable supply: %d\n", err);
15604 + p->prepared = true;
15605 + p->enabled = true;
15614 @@ -252,9 +458,14 @@ static int panel_simple_unprepare(struct drm_panel *panel)
15615 if (!p->prepared)
15618 - gpiod_set_value_cansleep(p->enable_gpio, 0);
15619 + if (p->desc->exit_seq)
15620 + if (p->dsi)
15621 + panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq);
15623 + gpiod_direction_output(p->reset_gpio, 1);
15624 + gpiod_direction_output(p->enable_gpio, 0);
15626 - regulator_disable(p->supply);
15629 if (p->desc->delay.unprepare)
15630 msleep(p->desc->delay.unprepare);
15631 @@ -299,13 +510,23 @@ static int panel_simple_prepare(struct drm_panel *panel)
15632 if (p->prepared)
15635 - err = regulator_enable(p->supply);
15638 dev_err(panel->dev, "failed to enable supply: %d\n", err);
15642 - gpiod_set_value_cansleep(p->enable_gpio, 1);
15643 + gpiod_direction_output(p->enable_gpio, 1);
15645 + if (p->desc->delay.reset)
15646 + msleep(p->desc->delay.prepare);
15648 + gpiod_direction_output(p->reset_gpio, 1);
15650 + if (p->desc->delay.reset)
15651 + msleep(p->desc->delay.reset);
15653 + gpiod_direction_output(p->reset_gpio, 0);
15655 delay = p->desc->delay.prepare;
15656 if (p->no_hpd)
15657 @@ -333,6 +554,13 @@ static int panel_simple_prepare(struct drm_panel *panel)
15661 + if (p->desc->init_seq)
15662 + if (p->dsi)
15663 + panel_simple_xfer_dsi_cmd_seq(p, p->desc->init_seq);
15665 + if (p->desc->delay.init)
15666 + msleep(p->desc->delay.init);
15668 p->prepared = true;
15671 @@ -500,6 +728,52 @@ static void panel_simple_parse_panel_timing_node(struct device *dev,
15678 + struct mipi_dsi_device *dsi = p->dsi;
15681 + if (!p->prepared)
15684 + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
15686 + ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness);
15690 + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
15698 + struct mipi_dsi_device *dsi = p->dsi;
15699 + u16 brightness = bl->props.brightness;
15702 + if (!p->prepared)
15705 + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
15711 + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
15724 @@ -525,15 +799,25 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *de…
15727 panel->supply = devm_regulator_get(dev, "power");
15728 - if (IS_ERR(panel->supply))
15729 - return PTR_ERR(panel->supply);
15730 + if (IS_ERR(panel->supply)) {
15731 + err = PTR_ERR(panel->supply);
15736 - panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
15737 - GPIOD_OUT_LOW);
15738 + panel->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_ASIS);
15739 if (IS_ERR(panel->enable_gpio)) {
15740 err = PTR_ERR(panel->enable_gpio);
15741 if (err != -EPROBE_DEFER)
15742 - dev_err(dev, "failed to request GPIO: %d\n", err);
15747 + panel->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
15748 + if (IS_ERR(panel->reset_gpio)) {
15749 + err = PTR_ERR(panel->reset_gpio);
15750 + if (err != -EPROBE_DEFER)
15755 @@ -543,13 +827,18 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *de…
15759 + panel->power_invert = of_property_read_bool(dev->of_node, "power-invert");
15761 ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
15763 panel->ddc = of_find_i2c_adapter_by_node(ddc);
15766 - if (!panel->ddc)
15767 - return -EPROBE_DEFER;
15768 + if (!panel->ddc) {
15769 + err = -EPROBE_DEFER;
15770 + dev_err(dev, "failed to find ddc-i2c-bus: %d\n", err);
15776 @@ -567,7 +856,7 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
15780 - dev_warn(dev, "Specify missing connector_type\n");
15785 @@ -622,8 +911,10 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *des…
15786 drm_panel_init(&panel->base, dev, &panel_simple_funcs, connector_type);
15788 err = drm_panel_of_backlight(&panel->base);
15789 - if (err)
15795 drm_panel_add(&panel->base);
15797 @@ -3904,6 +4195,9 @@ static const struct panel_desc arm_rtsm = {
15801 + .compatible = "simple-panel",
15804 .compatible = "ampire,am-1280800n3tzqw-t00h",
15807 @@ -4312,15 +4606,132 @@ static const struct of_device_id platform_of_match[] = {
15825 + struct device_node *np = dev->of_node;
15831 + if (of_child_node_is_present(np, "display-timings")) {
15836 + return -ENOMEM;
15840 + desc->modes = mode;
15841 + desc->num_modes = 1;
15842 + desc->bus_flags = bus_flags;
15844 + } else if (of_child_node_is_present(np, "panel-timing")) {
15850 + return -ENOMEM;
15852 + if (!of_get_display_timing(np, "panel-timing", timing)) {
15853 + desc->timings = timing;
15854 + desc->num_timings = 1;
15857 + vm.flags = timing->flags;
15859 + desc->bus_flags = bus_flags;
15863 + if (desc->num_modes || desc->num_timings) {
15864 + of_property_read_u32(np, "bpc", &desc->bpc);
15865 + of_property_read_u32(np, "bus-format", &desc->bus_format);
15866 + of_property_read_u32(np, "width-mm", &desc->size.width);
15867 + of_property_read_u32(np, "height-mm", &desc->size.height);
15870 + of_property_read_u32(np, "prepare-delay-ms", &desc->delay.prepare);
15871 + of_property_read_u32(np, "enable-delay-ms", &desc->delay.enable);
15872 + of_property_read_u32(np, "disable-delay-ms", &desc->delay.disable);
15873 + of_property_read_u32(np, "unprepare-delay-ms", &desc->delay.unprepare);
15874 + of_property_read_u32(np, "reset-delay-ms", &desc->delay.reset);
15875 + of_property_read_u32(np, "init-delay-ms", &desc->delay.init);
15877 + data = of_get_property(np, "panel-init-sequence", &len);
15879 + desc->init_seq = devm_kzalloc(dev, sizeof(*desc->init_seq),
15881 + if (!desc->init_seq)
15882 + return -ENOMEM;
15885 + desc->init_seq);
15892 + data = of_get_property(np, "panel-exit-sequence", &len);
15894 + desc->exit_seq = devm_kzalloc(dev, sizeof(*desc->exit_seq),
15896 + if (!desc->exit_seq)
15897 + return -ENOMEM;
15900 + desc->exit_seq);
15912 + struct device *dev = &pdev->dev;
15918 id = of_match_node(platform_of_match, pdev->dev.of_node);
15920 return -ENODEV;
15922 - return panel_simple_probe(&pdev->dev, id->data);
15923 + if (!id->data) {
15926 + return -ENOMEM;
15935 + desc = id->data ? id->data : d;
15937 + return panel_simple_probe(&pdev->dev, desc);
15941 @@ -4555,6 +4966,9 @@ static const struct panel_desc_dsi osd101t2045_53ts = {
15945 + .compatible = "simple-panel-dsi",
15951 @@ -4581,9 +4995,33 @@ static const struct of_device_id dsi_of_match[] = {
15958 + struct device_node *np = dev->of_node;
15962 + err = panel_simple_of_get_desc_data(dev, &desc->desc);
15967 + desc->flags = val;
15969 + desc->format = val;
15971 + desc->lanes = val;
15979 + struct device *dev = &dsi->dev;
15985 @@ -4591,12 +5029,47 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
15987 return -ENODEV;
15989 - desc = id->data;
15990 + if (!id->data) {
15993 + return -ENOMEM;
16002 + desc = id->data ? id->data : d;
16004 err = panel_simple_probe(&dsi->dev, &desc->desc);
16009 + panel->dsi = dsi;
16011 + if (!panel->base.backlight) {
16019 + panel->base.backlight =
16020 + devm_backlight_device_register(dev, "dcs-backlight",
16023 + if (IS_ERR(panel->base.backlight)) {
16024 + err = PTR_ERR(panel->base.backlight);
16031 dsi->mode_flags = desc->flags;
16032 dsi->format = desc->format;
16033 dsi->lanes = desc->lanes;
16034 diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
16036 --- a/drivers/gpu/drm/panfrost/panfrost_device.h
16038 @@ -120,12 +120,8 @@ struct panfrost_device {
16042 - struct panfrost_device *pfdev;
16043 - struct kref refcount;
16046 - struct drm_mm mm;
16047 - spinlock_t mm_lock;
16051 @@ -136,7 +132,9 @@ struct panfrost_file_priv {
16055 - struct panfrost_mmu *mmu;
16062 diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
16064 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
16066 @@ -417,7 +417,7 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
16069 if (!list_is_singular(&bo->mappings.list) ||
16070 - WARN_ON_ONCE(first->mmu != priv->mmu)) {
16071 + WARN_ON_ONCE(first->mmu != &priv->mmu)) {
16072 ret = -EINVAL;
16075 @@ -449,6 +449,32 @@ int panfrost_unstable_ioctl_check(void)
16080 +#define PFN_4G_MASK (PFN_4G - 1)
16095 + (*end)--;
16098 + if (next_seg - *start <= PFN_16M)
16101 + *end = min(*end, ALIGN(*start, PFN_4G) - 1);
16108 @@ -463,11 +489,15 @@ panfrost_open(struct drm_device *dev, struct drm_file *file)
16109 panfrost_priv->pfdev = pfdev;
16110 file->driver_priv = panfrost_priv;
16112 - panfrost_priv->mmu = panfrost_mmu_ctx_create(pfdev);
16113 - if (IS_ERR(panfrost_priv->mmu)) {
16114 - ret = PTR_ERR(panfrost_priv->mmu);
16115 - goto err_free;
16116 - }
16117 + spin_lock_init(&panfrost_priv->mm_lock);
16119 + /* 4G enough for now. can be 48-bit */
16120 + drm_mm_init(&panfrost_priv->mm, SZ_32M >> PAGE_SHIFT, (SZ_4G - SZ_32M) >> PAGE_SHIFT);
16121 + panfrost_priv->mm.color_adjust = panfrost_drm_mm_color_adjust;
16129 @@ -476,8 +506,9 @@ panfrost_open(struct drm_device *dev, struct drm_file *file)
16133 - panfrost_mmu_ctx_put(panfrost_priv->mmu);
16134 -err_free:
16137 + drm_mm_takedown(&panfrost_priv->mm);
16141 @@ -490,7 +521,8 @@ panfrost_postclose(struct drm_device *dev, struct drm_file *file)
16145 - panfrost_mmu_ctx_put(panfrost_priv->mmu);
16147 + drm_mm_takedown(&panfrost_priv->mm);
16151 diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
16153 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c
16155 @@ -60,7 +60,7 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo,
16157 mutex_lock(&bo->mappings.lock);
16158 list_for_each_entry(iter, &bo->mappings.list, node) {
16159 - if (iter->mmu == priv->mmu) {
16160 + if (iter->mmu == &priv->mmu) {
16161 kref_get(&iter->refcount);
16164 @@ -74,13 +74,16 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo,
16170 if (mapping->active)
16173 - spin_lock(&mapping->mmu->mm_lock);
16174 + priv = container_of(mapping->mmu, struct panfrost_file_priv, mmu);
16175 + spin_lock(&priv->mm_lock);
16176 if (drm_mm_node_allocated(&mapping->mmnode))
16177 drm_mm_remove_node(&mapping->mmnode);
16178 - spin_unlock(&mapping->mmu->mm_lock);
16179 + spin_unlock(&priv->mm_lock);
16183 @@ -91,7 +94,6 @@ static void panfrost_gem_mapping_release(struct kref *kref)
16186 drm_gem_object_put(&mapping->obj->base.base);
16187 - panfrost_mmu_ctx_put(mapping->mmu);
16191 @@ -141,11 +143,11 @@ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)
16195 - mapping->mmu = panfrost_mmu_ctx_get(priv->mmu);
16196 - spin_lock(&mapping->mmu->mm_lock);
16197 - ret = drm_mm_insert_node_generic(&mapping->mmu->mm, &mapping->mmnode,
16198 + mapping->mmu = &priv->mmu;
16199 + spin_lock(&priv->mm_lock);
16200 + ret = drm_mm_insert_node_generic(&priv->mm, &mapping->mmnode,
16202 - spin_unlock(&mapping->mmu->mm_lock);
16203 + spin_unlock(&priv->mm_lock);
16207 @@ -174,7 +176,7 @@ void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
16209 mutex_lock(&bo->mappings.lock);
16210 list_for_each_entry(iter, &bo->mappings.list, node) {
16211 - if (iter->mmu == priv->mmu) {
16212 + if (iter->mmu == &priv->mmu) {
16214 list_del(&iter->node);
16216 diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
16218 --- a/drivers/gpu/drm/panfrost/panfrost_job.c
16220 @@ -165,7 +165,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
16224 - cfg = panfrost_mmu_as_get(pfdev, job->file_priv->mmu);
16225 + cfg = panfrost_mmu_as_get(pfdev, &job->file_priv->mmu);
16229 @@ -524,7 +524,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void *data)
16231 pfdev->jobs[j] = NULL;
16233 - panfrost_mmu_as_put(pfdev, job->file_priv->mmu);
16234 + panfrost_mmu_as_put(pfdev, &job->file_priv->mmu);
16235 panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
16237 dma_fence_signal_locked(job->done_fence);
16238 diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
16240 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
16242 @@ -1,8 +1,5 @@
16243 // SPDX-License-Identifier: GPL-2.0
16245 -
16246 -#include <drm/panfrost_drm.h>
16247 -
16251 @@ -55,16 +52,25 @@ static int write_cmd(struct panfrost_device *pfdev, u32 as_nr, u32 cmd)
16255 - u64 iova, u64 size)
16260 -
16261 - /* The size is encoded as ceil(log2) minus(1), which may be calculated
16262 - * with fls. The size must be clamped to hardware bounds.
16270 - size = max_t(u64, size, AS_LOCK_REGION_MIN_SIZE);
16271 - region_width = fls64(size - 1) - 1;
16276 + if ((size >> PAGE_SHIFT) != (1ul << (region_width - 11))) {
16283 @@ -75,7 +81,7 @@ static void lock_region(struct panfrost_device *pfdev, u32 as_nr,
16287 - u64 iova, u64 size, u32 op)
16292 @@ -92,7 +98,7 @@ static int mmu_hw_do_operation_locked(struct panfrost_device *pfdev, int as_nr,
16296 - u64 iova, u64 size, u32 op)
16301 @@ -109,7 +115,7 @@ static void panfrost_mmu_enable(struct panfrost_device *pfdev, struct panfrost_m
16302 u64 transtab = cfg->arm_mali_lpae_cfg.transtab;
16303 u64 memattr = cfg->arm_mali_lpae_cfg.memattr;
16305 - mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
16310 @@ -125,7 +131,7 @@ static void panfrost_mmu_enable(struct panfrost_device *pfdev, struct panfrost_m
16314 - mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
16319 @@ -225,7 +231,7 @@ static size_t get_pgsize(u64 addr, size_t size)
16323 - u64 iova, u64 size)
16326 if (mmu->as < 0)
16328 @@ -331,7 +337,7 @@ static void mmu_tlb_inv_context_s1(void *cookie)
16332 - //struct panfrost_mmu *mmu = cookie;
16337 @@ -341,22 +347,62 @@ static void mmu_tlb_flush_walk(unsigned long iova, size_t size, size_t granul…
16341 -static void mmu_tlb_flush_leaf(unsigned long iova, size_t size, size_t granule,
16342 - void *cookie)
16343 -{
16344 - mmu_tlb_sync_context(cookie);
16345 -}
16346 -
16350 - .tlb_flush_leaf = mmu_tlb_flush_leaf,
16355 + struct panfrost_mmu *mmu = &priv->mmu;
16356 + struct panfrost_device *pfdev = priv->pfdev;
16358 + INIT_LIST_HEAD(&mmu->list);
16359 + mmu->as = -1;
16361 + mmu->pgtbl_cfg = (struct io_pgtable_cfg) {
16363 + .ias = FIELD_GET(0xff, pfdev->features.mmu_features),
16364 + .oas = FIELD_GET(0xff00, pfdev->features.mmu_features),
16365 + .coherent_walk = pfdev->coherent,
16367 + .iommu_dev = pfdev->dev,
16370 + mmu->pgtbl_ops = alloc_io_pgtable_ops(ARM_MALI_LPAE, &mmu->pgtbl_cfg,
16372 + if (!mmu->pgtbl_ops)
16373 + return -EINVAL;
16380 + struct panfrost_device *pfdev = priv->pfdev;
16381 + struct panfrost_mmu *mmu = &priv->mmu;
16383 + spin_lock(&pfdev->as_lock);
16384 + if (mmu->as >= 0) {
16385 + pm_runtime_get_noresume(pfdev->dev);
16386 + if (pm_runtime_active(pfdev->dev))
16387 + panfrost_mmu_disable(pfdev, mmu->as);
16388 + pm_runtime_put_autosuspend(pfdev->dev);
16390 + clear_bit(mmu->as, &pfdev->as_alloc_mask);
16391 + clear_bit(mmu->as, &pfdev->as_in_use_mask);
16392 + list_del(&mmu->list);
16394 + spin_unlock(&pfdev->as_lock);
16396 + free_io_pgtable_ops(mmu->pgtbl_ops);
16407 @@ -369,10 +415,11 @@ addr_to_mapping(struct panfrost_device *pfdev, int as, u64 addr)
16413 - spin_lock(&mmu->mm_lock);
16414 + spin_lock(&priv->mm_lock);
16416 - drm_mm_for_each_node(node, &mmu->mm) {
16417 + drm_mm_for_each_node(node, &priv->mm) {
16418 if (offset >= node->start &&
16419 offset < (node->start + node->size)) {
16421 @@ -382,7 +429,7 @@ addr_to_mapping(struct panfrost_device *pfdev, int as, u64 addr)
16425 - spin_unlock(&mmu->mm_lock);
16426 + spin_unlock(&priv->mm_lock);
16428 spin_unlock(&pfdev->as_lock);
16430 @@ -495,107 +542,6 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
16434 -static void panfrost_mmu_release_ctx(struct kref *kref)
16435 -{
16436 - struct panfrost_mmu *mmu = container_of(kref, struct panfrost_mmu,
16437 - refcount);
16438 - struct panfrost_device *pfdev = mmu->pfdev;
16439 -
16440 - spin_lock(&pfdev->as_lock);
16441 - if (mmu->as >= 0) {
16442 - pm_runtime_get_noresume(pfdev->dev);
16443 - if (pm_runtime_active(pfdev->dev))
16444 - panfrost_mmu_disable(pfdev, mmu->as);
16445 - pm_runtime_put_autosuspend(pfdev->dev);
16446 -
16447 - clear_bit(mmu->as, &pfdev->as_alloc_mask);
16448 - clear_bit(mmu->as, &pfdev->as_in_use_mask);
16449 - list_del(&mmu->list);
16450 - }
16451 - spin_unlock(&pfdev->as_lock);
16452 -
16453 - free_io_pgtable_ops(mmu->pgtbl_ops);
16454 - drm_mm_takedown(&mmu->mm);
16455 - kfree(mmu);
16456 -}
16457 -
16458 -void panfrost_mmu_ctx_put(struct panfrost_mmu *mmu)
16459 -{
16460 - kref_put(&mmu->refcount, panfrost_mmu_release_ctx);
16461 -}
16462 -
16463 -struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu)
16464 -{
16465 - kref_get(&mmu->refcount);
16466 -
16467 - return mmu;
16468 -}
16469 -
16470 -#define PFN_4G (SZ_4G >> PAGE_SHIFT)
16471 -#define PFN_4G_MASK (PFN_4G - 1)
16472 -#define PFN_16M (SZ_16M >> PAGE_SHIFT)
16473 -
16474 -static void panfrost_drm_mm_color_adjust(const struct drm_mm_node *node,
16475 - unsigned long color,
16476 - u64 *start, u64 *end)
16477 -{
16478 - /* Executable buffers can't start or end on a 4GB boundary */
16479 - if (!(color & PANFROST_BO_NOEXEC)) {
16480 - u64 next_seg;
16481 -
16482 - if ((*start & PFN_4G_MASK) == 0)
16483 - (*start)++;
16484 -
16485 - if ((*end & PFN_4G_MASK) == 0)
16486 - (*end)--;
16487 -
16488 - next_seg = ALIGN(*start, PFN_4G);
16489 - if (next_seg - *start <= PFN_16M)
16490 - *start = next_seg + 1;
16491 -
16492 - *end = min(*end, ALIGN(*start, PFN_4G) - 1);
16493 - }
16494 -}
16495 -
16496 -struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev)
16497 -{
16498 - struct panfrost_mmu *mmu;
16499 -
16500 - mmu = kzalloc(sizeof(*mmu), GFP_KERNEL);
16501 - if (!mmu)
16502 - return ERR_PTR(-ENOMEM);
16503 -
16504 - mmu->pfdev = pfdev;
16505 - spin_lock_init(&mmu->mm_lock);
16506 -
16507 - /* 4G enough for now. can be 48-bit */
16508 - drm_mm_init(&mmu->mm, SZ_32M >> PAGE_SHIFT, (SZ_4G - SZ_32M) >> PAGE_SHIFT);
16509 - mmu->mm.color_adjust = panfrost_drm_mm_color_adjust;
16510 -
16511 - INIT_LIST_HEAD(&mmu->list);
16512 - mmu->as = -1;
16513 -
16514 - mmu->pgtbl_cfg = (struct io_pgtable_cfg) {
16515 - .pgsize_bitmap = SZ_4K | SZ_2M,
16516 - .ias = FIELD_GET(0xff, pfdev->features.mmu_features),
16517 - .oas = FIELD_GET(0xff00, pfdev->features.mmu_features),
16518 - .coherent_walk = pfdev->coherent,
16519 - .tlb = &mmu_tlb_ops,
16520 - .iommu_dev = pfdev->dev,
16521 - };
16522 -
16523 - mmu->pgtbl_ops = alloc_io_pgtable_ops(ARM_MALI_LPAE, &mmu->pgtbl_cfg,
16524 - mmu);
16525 - if (!mmu->pgtbl_ops) {
16526 - kfree(mmu);
16527 - return ERR_PTR(-EINVAL);
16528 - }
16529 -
16530 - kref_init(&mmu->refcount);
16531 -
16532 - return mmu;
16533 -}
16534 -
16538 diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.h b/drivers/gpu/drm/panfrost/panfrost_mmu.h
16540 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.h
16542 @@ -18,8 +18,7 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev);
16546 -struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu);
16547 -void panfrost_mmu_ctx_put(struct panfrost_mmu *mmu);
16548 -struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev);
16553 diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h b/drivers/gpu/drm/panfrost/panfrost_regs.h
16555 --- a/drivers/gpu/drm/panfrost/panfrost_regs.h
16557 @@ -318,8 +318,6 @@
16561 -#define AS_LOCK_REGION_MIN_SIZE (1ULL << 15)
16562 -
16563 #define gpu_write(dev, reg, data) writel(data, dev->iomem + reg)
16564 #define gpu_read(dev, reg) readl(dev->iomem + reg)
16566 diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
16568 --- a/drivers/gpu/drm/rockchip/Kconfig
16570 @@ -1,7 +1,7 @@
16571 # SPDX-License-Identifier: GPL-2.0-only
16574 - depends on DRM && ROCKCHIP_IOMMU
16576 select DRM_GEM_CMA_HELPER
16577 select DRM_KMS_HELPER
16578 select DRM_PANEL
16579 @@ -20,6 +20,53 @@ config DRM_ROCKCHIP
16620 + enable VOP on Rockchip SoC, you should select this option.
16628 + select this option.
16633 @@ -29,7 +76,6 @@ config ROCKCHIP_ANALOGIX_DP
16637 - depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m)
16641 @@ -53,6 +99,12 @@ config ROCKCHIP_DW_MIPI_DSI
16643 select this option.
16654 @@ -62,7 +114,6 @@ config ROCKCHIP_INNO_HDMI
16658 - depends on DRM_ROCKCHIP
16662 @@ -72,7 +123,6 @@ config ROCKCHIP_LVDS
16666 - depends on DRM_ROCKCHIP
16670 @@ -82,9 +132,22 @@ config ROCKCHIP_RGB
16674 - depends on DRM_ROCKCHIP
16678 HDMI on RK3066 based SoC, you should select this option.
16694 diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
16696 --- a/drivers/gpu/drm/rockchip/Makefile
16698 @@ -4,16 +4,30 @@
16701 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
16702 - rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o
16705 +rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o
16706 +rockchipdrm-$(CONFIG_ROCKCHIP_VOP2) += rockchip_drm_vop2.o rockchip_vop2_reg.o
16708 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
16709 +rockchipdrm-$(CONFIG_ROCKCHIP_DRM_DEBUG) += rockchip_drm_debugfs.o
16710 +rockchipdrm-$(CONFIG_ROCKCHIP_DRM_DIRECT_SHOW) += rockchip_drm_direct_show.o
16711 +rockchipdrm-$(CONFIG_ROCKCHIP_DRM_SELF_TEST) += rockchip_drm_display_pattern.o \
16714 rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
16715 rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
16716 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
16717 -rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
16718 +rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o \
16719 + dw-mipi-dsi2-rockchip.o
16720 +rockchipdrm-$(CONFIG_ROCKCHIP_DW_DP) += dw-dp.o
16721 rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
16722 rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
16723 rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
16724 rockchipdrm-$(CONFIG_ROCKCHIP_RK3066_HDMI) += rk3066_hdmi.o
16725 +rockchipdrm-$(CONFIG_ROCKCHIP_VCONN) += rockchip_drm_vconn.o
16726 +rockchipdrm-$(CONFIG_DRM_ROCKCHIP_VVOP) += rockchip_drm_vvop.o
16728 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
16730 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/gpu/drm/
16732 diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp
16734 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
16735 +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
16736 @@ -16,6 +16,7 @@
16744 @@ -31,29 +32,44 @@
16748 -#define RK3288_GRF_SOC_CON6 0x25c
16749 -#define RK3288_EDP_LCDC_SEL BIT(5)
16750 -#define RK3399_GRF_SOC_CON20 0x6250
16751 -#define RK3399_EDP_LCDC_SEL BIT(5)
16752 -
16753 -#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
16754 -
16774 * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
16775 - * @lcdsel_grf_reg: grf register offset of lcdc select
16776 - * @lcdsel_big: reg value of selecting vop big for eDP
16777 - * @lcdsel_lit: reg value of selecting vop little for eDP
16788 - u32 lcdsel_grf_reg;
16789 - u32 lcdsel_big;
16790 - u32 lcdsel_lit;
16802 @@ -62,23 +78,116 @@ struct rockchip_dp_device {
16806 - struct clk *pclk;
16807 - struct clk *grfclk;
16833 + if (!field->valid)
16836 + mask = GENMASK(field->msb, field->lsb);
16837 + val <<= field->lsb;
16839 + return rockchip_grf_write(grf, field->reg, mask, val);
16848 + rockchip_grf_field_write(dp->grf, &dp->data->spdif_sel,
16849 + daifmt->fmt == HDMI_SPDIF);
16850 + rockchip_grf_field_write(dp->grf, &dp->data->i2s_sel,
16851 + daifmt->fmt == HDMI_I2S);
16853 + return analogix_dp_audio_hw_params(dp->adp, daifmt, params);
16860 + analogix_dp_audio_shutdown(dp->adp);
16862 + rockchip_grf_field_write(dp->grf, &dp->data->spdif_sel, 0);
16863 + rockchip_grf_field_write(dp->grf, &dp->data->i2s_sel, 0);
16870 + return analogix_dp_audio_startup(dp->adp);
16878 + return analogix_dp_audio_get_eld(dp->adp, buf, len);
16893 + return dp->id == *id;
16910 reset_control_assert(dp->rst);
16912 reset_control_deassert(dp->rst);
16914 + reset_control_assert(dp->apb_reset);
16916 + reset_control_deassert(dp->apb_reset);
16921 @@ -87,29 +196,20 @@ static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data)
16925 - ret = clk_prepare_enable(dp->pclk);
16926 - if (ret < 0) {
16927 - DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
16928 - return ret;
16929 - }
16930 -
16933 DRM_DEV_ERROR(dp->dev, "failed to dp pre init %d\n", ret);
16934 - clk_disable_unprepare(dp->pclk);
16938 - return ret;
16939 + return rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
16946 - clk_disable_unprepare(dp->pclk);
16947 -
16948 - return 0;
16949 + return rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 0);
16953 @@ -129,6 +229,69 @@ static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data,
16960 + struct analogix_dp_plat_data *plat_data = &dp->plat_data;
16965 + if (plat_data->panel)
16966 + panel_simple_loader_protect(plat_data->panel);
16968 + analogix_dp_loader_protect(dp->adp);
16976 + if (of_device_is_compatible(bridge->of_node, "dp-connector"))
16987 + struct rockchip_drm_sub_dev *sdev = &dp->sub_dev;
16990 + if (plat_data->bridge) {
16991 + ret = drm_bridge_attach(&dp->encoder, plat_data->bridge, bridge,
17001 + sdev->connector = connector;
17002 + sdev->of_node = dp->dev->of_node;
17003 + sdev->loader_protect = rockchip_dp_loader_protect;
17014 + struct rockchip_drm_sub_dev *sdev = &dp->sub_dev;
17016 + if (sdev->connector)
17023 @@ -170,7 +333,6 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
17027 - u32 val;
17031 @@ -185,24 +347,11 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
17035 - if (ret)
17036 - val = dp->data->lcdsel_lit;
17037 - else
17038 - val = dp->data->lcdsel_big;
17039 -
17040 DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
17042 - ret = clk_prepare_enable(dp->grfclk);
17043 - if (ret < 0) {
17044 - DRM_DEV_ERROR(dp->dev, "failed to enable grfclk %d\n", ret);
17045 - return;
17046 - }
17047 -
17048 - ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
17049 + ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
17051 DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
17052 -
17053 - clk_disable_unprepare(dp->grfclk);
17057 @@ -233,9 +382,15 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
17063 struct drm_display_info *di = &conn_state->connector->display_info;
17065 + if (di->num_bus_formats)
17066 + s->bus_format = di->bus_formats[0];
17068 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
17073 @@ -246,7 +401,18 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
17075 s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
17076 s->output_type = DRM_MODE_CONNECTOR_eDP;
17077 + if (dp->plat_data.split_mode) {
17078 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
17079 + s->output_flags |= dp->id ? ROCKCHIP_OUTPUT_DATA_SWAP : 0;
17080 + s->output_if |= VOP_OUTPUT_IF_eDP0 | VOP_OUTPUT_IF_eDP1;
17082 + s->output_if |= dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0;
17084 s->output_bpc = di->bpc;
17085 + s->bus_flags = di->bus_flags;
17086 + s->tv_state = &conn_state->tv;
17087 + s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
17088 + s->color_space = V4L2_COLORSPACE_DEFAULT;
17092 @@ -264,26 +430,12 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
17093 struct device *dev = dp->dev;
17094 struct device_node *np = dev->of_node;
17096 - dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
17097 - if (IS_ERR(dp->grf)) {
17098 - DRM_DEV_ERROR(dev, "failed to get rockchip,grf property\n");
17099 - return PTR_ERR(dp->grf);
17100 - }
17101 -
17102 - dp->grfclk = devm_clk_get(dev, "grf");
17103 - if (PTR_ERR(dp->grfclk) == -ENOENT) {
17104 - dp->grfclk = NULL;
17105 - } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) {
17106 - return -EPROBE_DEFER;
17107 - } else if (IS_ERR(dp->grfclk)) {
17108 - DRM_DEV_ERROR(dev, "failed to get grf clock\n");
17109 - return PTR_ERR(dp->grfclk);
17110 - }
17111 -
17112 - dp->pclk = devm_clk_get(dev, "pclk");
17113 - if (IS_ERR(dp->pclk)) {
17114 - DRM_DEV_ERROR(dev, "failed to get pclk property\n");
17115 - return PTR_ERR(dp->pclk);
17117 + dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
17118 + if (IS_ERR(dp->grf)) {
17120 + return PTR_ERR(dp->grf);
17124 dp->rst = devm_reset_control_get(dev, "dp");
17125 @@ -292,6 +444,12 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
17126 return PTR_ERR(dp->rst);
17129 + dp->apb_reset = devm_reset_control_get_optional(dev, "apb");
17130 + if (IS_ERR(dp->apb_reset)) {
17132 + return PTR_ERR(dp->apb_reset);
17138 @@ -302,8 +460,8 @@ static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
17139 struct device *dev = dp->dev;
17142 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
17143 - dev->of_node);
17144 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
17145 + dev->of_node);
17146 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
17149 @@ -327,19 +485,44 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
17151 dp->drm_dev = drm_dev;
17153 - ret = rockchip_dp_drm_create_encoder(dp);
17154 - if (ret) {
17155 - DRM_ERROR("failed to create drm encoder\n");
17156 - return ret;
17157 + if (!dp->plat_data.left) {
17164 + dp->plat_data.encoder = &dp->encoder;
17167 - dp->plat_data.encoder = &dp->encoder;
17168 + if (dp->data->audio) {
17176 + dp->audio_pdev =
17181 + if (IS_ERR(dp->audio_pdev)) {
17182 + ret = PTR_ERR(dp->audio_pdev);
17187 ret = analogix_dp_bind(dp->adp, drm_dev);
17189 - goto err_cleanup_encoder;
17195 + if (dp->audio_pdev)
17196 + platform_device_unregister(dp->audio_pdev);
17198 dp->encoder.funcs->destroy(&dp->encoder);
17200 @@ -350,6 +533,8 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
17204 + if (dp->audio_pdev)
17205 + platform_device_unregister(dp->audio_pdev);
17206 analogix_dp_unbind(dp->adp);
17207 dp->encoder.funcs->destroy(&dp->encoder);
17209 @@ -364,29 +549,51 @@ static int rockchip_dp_probe(struct platform_device *pdev)
17210 struct device *dev = &pdev->dev;
17215 - int ret;
17220 return -ENODEV;
17222 - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
17223 - if (ret < 0)
17224 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, &bridge);
17225 + if (ret < 0 && ret != -ENODEV)
17230 return -ENOMEM;
17232 + id = of_alias_get_id(dev->of_node, "edp");
17242 + return -ENODEV;
17245 dp->dev = dev;
17246 + dp->id = id;
17247 dp->adp = ERR_PTR(-ENODEV);
17248 - dp->data = dp_data;
17249 + dp->data = &dp_data[id];
17250 + dp->plat_data.ssc = dp->data->ssc;
17251 dp->plat_data.panel = panel;
17252 dp->plat_data.dev_type = dp->data->chip_type;
17253 dp->plat_data.power_on_start = rockchip_dp_poweron_start;
17254 dp->plat_data.power_off = rockchip_dp_powerdown;
17255 dp->plat_data.get_modes = rockchip_dp_get_modes;
17256 + dp->plat_data.attach = rockchip_dp_bridge_attach;
17257 + dp->plat_data.detach = rockchip_dp_bridge_detach;
17258 + dp->plat_data.convert_to_split_mode = drm_mode_convert_to_split_mode;
17259 + dp->plat_data.convert_to_origin_mode = drm_mode_convert_to_origin_mode;
17260 + dp->plat_data.skip_connector = rockchip_dp_skip_connector(bridge);
17261 + dp->plat_data.bridge = bridge;
17265 @@ -398,6 +605,18 @@ static int rockchip_dp_probe(struct platform_device *pdev)
17266 if (IS_ERR(dp->adp))
17267 return PTR_ERR(dp->adp);
17269 + if (dp->data->split_mode && device_property_read_bool(dev, "split-mode")) {
17271 + rockchip_dp_find_by_id(dev->driver, !dp->id);
17273 + return -EPROBE_DEFER;
17275 + dp->plat_data.right = secondary->adp;
17276 + dp->plat_data.split_mode = true;
17277 + secondary->plat_data.left = dp->adp;
17278 + secondary->plat_data.split_mode = true;
17284 @@ -419,8 +638,7 @@ static int rockchip_dp_remove(struct platform_device *pdev)
17288 -#ifdef CONFIG_PM_SLEEP
17289 -static int rockchip_dp_suspend(struct device *dev)
17294 @@ -430,7 +648,7 @@ static int rockchip_dp_suspend(struct device *dev)
17295 return analogix_dp_suspend(dp->adp);
17298 -static int rockchip_dp_resume(struct device *dev)
17303 @@ -439,27 +657,49 @@ static int rockchip_dp_resume(struct device *dev)
17305 return analogix_dp_resume(dp->adp);
17307 -#endif
17313 + if (IS_ERR(dp->adp))
17316 + return analogix_dp_runtime_suspend(dp->adp);
17323 + if (IS_ERR(dp->adp))
17326 + return analogix_dp_runtime_resume(dp->adp);
17330 -#ifdef CONFIG_PM_SLEEP
17331 - .suspend_late = rockchip_dp_suspend,
17332 - .resume_early = rockchip_dp_resume,
17333 -#endif
17339 -static const struct rockchip_dp_chip_data rk3399_edp = {
17340 - .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
17341 - .lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL),
17342 - .lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL),
17343 - .chip_type = RK3399_EDP,
17353 -static const struct rockchip_dp_chip_data rk3288_dp = {
17354 - .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
17355 - .lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL),
17356 - .lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL),
17357 - .chip_type = RK3288_DP,
17368 diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
17370 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
17371 +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
17372 @@ -6,7 +6,6 @@
17376 -#include <linux/extcon.h>
17380 @@ -143,24 +142,7 @@ static void cdn_dp_clk_disable(struct cdn_dp_device *dp)
17384 - struct extcon_dev *edev = port->extcon;
17385 - union extcon_property_value property;
17386 - int dptx;
17387 - u8 lanes;
17388 -
17389 - dptx = extcon_get_state(edev, EXTCON_DISP_DP);
17390 - if (dptx > 0) {
17391 - extcon_get_property(edev, EXTCON_DISP_DP,
17392 - EXTCON_PROP_USB_SS, &property);
17393 - if (property.intval)
17394 - lanes = 2;
17395 - else
17396 - lanes = 4;
17397 - } else {
17398 - lanes = 0;
17399 - }
17400 -
17401 - return lanes;
17402 + return phy_get_bus_width(port->phy);
17406 @@ -194,7 +176,6 @@ static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
17410 - struct cdn_dp_port *port;
17413 if (dp->active_port < 0 || dp->active_port >= dp->ports) {
17414 @@ -202,8 +183,6 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
17418 - port = dp->port[dp->active_port];
17419 -
17423 @@ -211,9 +190,6 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
17427 - if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
17428 - return false;
17429 -
17433 @@ -244,6 +220,13 @@ static void cdn_dp_connector_destroy(struct drm_connector *connector)
17441 + schedule_delayed_work(&dp->event_work, msecs_to_jiffies(100));
17447 @@ -383,7 +366,6 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
17451 - union extcon_property_value property;
17454 if (!port->phy_enabled) {
17455 @@ -410,15 +392,8 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *por…
17459 - ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
17460 - EXTCON_PROP_USB_TYPEC_POLARITY, &property);
17461 - if (ret) {
17462 - DRM_DEV_ERROR(dp->dev, "get property failed\n");
17463 - goto err_power_on;
17464 - }
17465 -
17466 port->lanes = cdn_dp_get_port_lanes(port);
17467 - ret = cdn_dp_set_host_cap(dp, port->lanes, property.intval);
17468 + ret = cdn_dp_set_host_cap(dp, port->lanes, 0);
17470 DRM_DEV_ERROR(dp->dev, "set host capabilities failed: %d\n",
17472 @@ -670,7 +645,7 @@ static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
17473 * run the event_work to re-connect it.
17475 if (!dp->connected && cdn_dp_connected_port(dp))
17476 - schedule_work(&dp->event_work);
17477 + schedule_delayed_work(&dp->event_work, 0);
17481 @@ -681,6 +656,7 @@ static int cdn_dp_encoder_atomic_check(struct drm_encoder *encoder,
17483 s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
17484 s->output_type = DRM_MODE_CONNECTOR_DisplayPort;
17485 + s->tv_state = &conn_state->tv;
17489 @@ -913,7 +889,7 @@ static int cdn_dp_request_firmware(struct cdn_dp_device *dp)
17493 - struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
17496 struct drm_connector *connector = &dp->connector;
17498 @@ -986,31 +962,13 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
17499 drm_kms_helper_hotplug_event(dp->drm_dev);
17502 -static int cdn_dp_pd_event(struct notifier_block *nb,
17503 - unsigned long event, void *priv)
17504 -{
17505 - struct cdn_dp_port *port = container_of(nb, struct cdn_dp_port,
17506 - event_nb);
17507 - struct cdn_dp_device *dp = port->dp;
17508 -
17509 - /*
17510 - * It would be nice to be able to just do the work inline right here.
17511 - * However, we need to make a bunch of calls that might sleep in order
17512 - * to turn on the block/phy, so use a worker instead.
17513 - */
17514 - schedule_work(&dp->event_work);
17515 -
17516 - return NOTIFY_DONE;
17517 -}
17518 -
17524 - struct cdn_dp_port *port;
17526 - int ret, i;
17531 @@ -1022,12 +980,12 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
17532 dp->active_port = -1;
17533 dp->fw_loaded = false;
17535 - INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
17536 + INIT_DELAYED_WORK(&dp->event_work, cdn_dp_pd_event_work);
17538 encoder = &dp->encoder;
17540 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
17541 - dev->of_node);
17542 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
17543 + dev->of_node);
17544 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
17547 @@ -1059,23 +1017,14 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *dat…
17551 - for (i = 0; i < dp->ports; i++) {
17552 - port = dp->port[i];
17553 -
17554 - port->event_nb.notifier_call = cdn_dp_pd_event;
17555 - ret = devm_extcon_register_notifier(dp->dev, port->extcon,
17556 - EXTCON_DISP_DP,
17557 - &port->event_nb);
17558 - if (ret) {
17559 - DRM_DEV_ERROR(dev,
17560 - "register EXTCON_DISP_DP notifier err\n");
17561 - goto err_free_connector;
17562 - }
17563 - }
17564 + dp->sub_dev.connector = &dp->connector;
17565 + dp->sub_dev.of_node = dev->of_node;
17566 + dp->sub_dev.oob_hotplug_event = cdn_dp_oob_hotplug_event;
17567 + rockchip_drm_register_sub_dev(&dp->sub_dev);
17571 - schedule_work(&dp->event_work);
17572 + schedule_delayed_work(&dp->event_work, 0);
17576 @@ -1092,7 +1041,7 @@ static void cdn_dp_unbind(struct device *dev, struct device *master, void *da…
17577 struct drm_encoder *encoder = &dp->encoder;
17578 struct drm_connector *connector = &dp->connector;
17580 - cancel_work_sync(&dp->event_work);
17581 + cancel_delayed_work_sync(&dp->event_work);
17583 encoder->funcs->destroy(encoder);
17584 connector->funcs->destroy(connector);
17585 @@ -1123,14 +1072,14 @@ static int cdn_dp_suspend(struct device *dev)
17589 -static __maybe_unused int cdn_dp_resume(struct device *dev)
17594 mutex_lock(&dp->lock);
17595 dp->suspended = false;
17596 if (dp->fw_loaded)
17597 - schedule_work(&dp->event_work);
17598 + schedule_delayed_work(&dp->event_work, 0);
17599 mutex_unlock(&dp->lock);
17602 @@ -1143,7 +1092,6 @@ static int cdn_dp_probe(struct platform_device *pdev)
17606 - struct extcon_dev *extcon;
17610 @@ -1156,21 +1104,18 @@ static int cdn_dp_probe(struct platform_device *pdev)
17611 dp_data = (struct cdn_dp_data *)match->data;
17613 for (i = 0; i < dp_data->max_phy; i++) {
17614 - extcon = extcon_get_edev_by_phandle(dev, i);
17615 phy = devm_of_phy_get_by_index(dev, dev->of_node, i);
17617 - if (PTR_ERR(extcon) == -EPROBE_DEFER ||
17618 - PTR_ERR(phy) == -EPROBE_DEFER)
17619 + if (PTR_ERR(phy) == -EPROBE_DEFER)
17620 return -EPROBE_DEFER;
17622 - if (IS_ERR(extcon) || IS_ERR(phy))
17628 return -ENOMEM;
17630 - port->extcon = extcon;
17631 port->phy = phy;
17632 port->dp = dp;
17633 port->id = i;
17634 @@ -1178,7 +1123,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
17637 if (!dp->ports) {
17638 - DRM_DEV_ERROR(dev, "missing extcon or phy\n");
17640 return -EINVAL;
17643 diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
17645 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
17646 +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
17647 @@ -53,8 +53,6 @@ struct cdn_firmware_header {
17651 - struct notifier_block event_nb;
17652 - struct extcon_dev *extcon;
17656 @@ -68,8 +66,9 @@ struct cdn_dp_device {
17660 - struct work_struct event_work;
17667 diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi
17669 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
17670 +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
17671 @@ -16,8 +16,9 @@
17677 -
17682 @@ -140,6 +141,7 @@
17690 @@ -172,6 +174,12 @@
17703 @@ -198,6 +206,19 @@ enum {
17723 @@ -213,25 +234,42 @@ struct rockchip_dw_dsi_chip_data {
17737 -
17758 /* dual-channel */
17767 @@ -243,6 +281,9 @@ struct dw_mipi_dsi_rockchip {
17777 @@ -365,10 +406,27 @@ static inline unsigned int ns2ui(struct dw_mipi_dsi_rockchip *dsi, int ns)
17778 return DIV_ROUND_UP(ns * dsi->lane_mbps, 1000);
17783 + if (dsi->cdata->lanecfg1_grf_reg)
17784 + regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
17785 + dsi->cdata->lanecfg1);
17787 + if (dsi->cdata->lanecfg2_grf_reg)
17788 + regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg2_grf_reg,
17789 + dsi->cdata->lanecfg2);
17791 + if (dsi->cdata->enable_grf_reg)
17792 + regmap_write(dsi->grf_regmap, dsi->cdata->enable_grf_reg,
17793 + dsi->cdata->enable);
17799 - int ret, i, vco;
17804 if (dsi->phy)
17806 @@ -395,12 +453,6 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
17810 - ret = clk_prepare_enable(dsi->phy_cfg_clk);
17811 - if (ret) {
17812 - DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk\n");
17813 - return ret;
17814 - }
17815 -
17819 @@ -453,7 +505,7 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
17823 - TLP_PROGRAM_EN | ns2bc(dsi, 500));
17828 @@ -466,7 +518,7 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
17832 - TLP_PROGRAM_EN | ns2bc(dsi, 500));
17837 @@ -476,31 +528,29 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
17841 - clk_disable_unprepare(dsi->phy_cfg_clk);
17842 -
17843 - return ret;
17850 - int ret;
17852 - ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
17853 - if (ret) {
17854 - DRM_DEV_ERROR(dsi->dev, "failed to set phy mode: %d\n", ret);
17855 + if (dsi->phy_enabled)
17857 - }
17859 - phy_configure(dsi->phy, &dsi->phy_opts);
17860 phy_power_on(dsi->phy);
17861 + dsi->phy_enabled = true;
17868 + if (!dsi->phy_enabled)
17871 phy_power_off(dsi->phy);
17872 + dsi->phy_enabled = false;
17876 @@ -509,17 +559,22 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mod…
17880 + struct device *dev = dsi->dev;
17884 - unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
17896 + max_mbps = dsi->cdata->max_bit_rate_per_lane / USEC_PER_SEC;
17897 dsi->format = format;
17898 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
17900 @@ -529,23 +584,40 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mod…
17904 - mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
17905 - if (mpclk) {
17906 - /* take 1 / 0.8, since mbps must big than bandwidth of RGB */
17907 - tmp = mpclk * (bpp / lanes) * 10 / 8;
17908 - if (tmp < max_mbps)
17909 - target_mbps = tmp;
17910 - else
17911 - DRM_DEV_ERROR(dsi->dev,
17912 - "DPHY clock frequency is out of range\n");
17914 + if (!of_property_read_u32(dev->of_node, "rockchip,lane-rate", &value)) {
17917 + mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
17924 + DRM_DEV_ERROR(dsi->dev,
17932 if (dsi->phy) {
17933 - phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
17937 &dsi->phy_opts.mipi_dphy);
17938 - dsi->lane_mbps = target_mbps;
17939 + ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
17941 + DRM_DEV_ERROR(dsi->dev,
17946 + phy_configure(dsi->phy, &dsi->phy_opts);
17947 + hs_clk_rate = dsi->phy_opts.mipi_dphy.hs_clk_rate;
17948 + dsi->lane_mbps = DIV_ROUND_UP(hs_clk_rate, USEC_PER_SEC);
17949 *lane_mbps = dsi->lane_mbps;
17952 @@ -611,74 +683,18 @@ struct hstt {
17956 -#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \
17957 -{ \
17958 - .maxfreq = _maxfreq, \
17959 - .timing = { \
17960 - .clk_lp2hs = _c_lp2hs, \
17961 - .clk_hs2lp = _c_hs2lp, \
17962 - .data_lp2hs = _d_lp2hs, \
17963 - .data_hs2lp = _d_hs2lp, \
17964 - } \
17965 -}
17966 -
17967 -/* Table A-3 High-Speed Transition Times */
17968 -struct hstt hstt_table[] = {
17969 - HSTT( 90, 32, 20, 26, 13),
17970 - HSTT( 100, 35, 23, 28, 14),
17971 - HSTT( 110, 32, 22, 26, 13),
17972 - HSTT( 130, 31, 20, 27, 13),
17973 - HSTT( 140, 33, 22, 26, 14),
17974 - HSTT( 150, 33, 21, 26, 14),
17975 - HSTT( 170, 32, 20, 27, 13),
17976 - HSTT( 180, 36, 23, 30, 15),
17977 - HSTT( 200, 40, 22, 33, 15),
17978 - HSTT( 220, 40, 22, 33, 15),
17979 - HSTT( 240, 44, 24, 36, 16),
17980 - HSTT( 250, 48, 24, 38, 17),
17981 - HSTT( 270, 48, 24, 38, 17),
17982 - HSTT( 300, 50, 27, 41, 18),
17983 - HSTT( 330, 56, 28, 45, 18),
17984 - HSTT( 360, 59, 28, 48, 19),
17985 - HSTT( 400, 61, 30, 50, 20),
17986 - HSTT( 450, 67, 31, 55, 21),
17987 - HSTT( 500, 73, 31, 59, 22),
17988 - HSTT( 550, 79, 36, 63, 24),
17989 - HSTT( 600, 83, 37, 68, 25),
17990 - HSTT( 650, 90, 38, 73, 27),
17991 - HSTT( 700, 95, 40, 77, 28),
17992 - HSTT( 750, 102, 40, 84, 28),
17993 - HSTT( 800, 106, 42, 87, 30),
17994 - HSTT( 850, 113, 44, 93, 31),
17995 - HSTT( 900, 118, 47, 98, 32),
17996 - HSTT( 950, 124, 47, 102, 34),
17997 - HSTT(1000, 130, 49, 107, 35),
17998 - HSTT(1050, 135, 51, 111, 37),
17999 - HSTT(1100, 139, 51, 114, 38),
18000 - HSTT(1150, 146, 54, 120, 40),
18001 - HSTT(1200, 153, 57, 125, 41),
18002 - HSTT(1250, 158, 58, 130, 42),
18003 - HSTT(1300, 163, 58, 135, 44),
18004 - HSTT(1350, 168, 60, 140, 45),
18005 - HSTT(1400, 172, 64, 144, 47),
18006 - HSTT(1450, 176, 65, 148, 48),
18007 - HSTT(1500, 181, 66, 153, 50)
18019 - int i;
18020 -
18021 - for (i = 0; i < ARRAY_SIZE(hstt_table); i++)
18022 - if (lane_mbps < hstt_table[i].maxfreq)
18023 - break;
18024 -
18025 - if (i == ARRAY_SIZE(hstt_table))
18026 - i--;
18027 -
18028 - *timing = hstt_table[i].timing;
18033 @@ -691,26 +707,25 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
18037 -static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi)
18040 - if (dsi->cdata->lanecfg1_grf_reg)
18041 - regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
18042 - dsi->cdata->lanecfg1);
18045 - if (dsi->cdata->lanecfg2_grf_reg)
18046 - regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg2_grf_reg,
18047 - dsi->cdata->lanecfg2);
18048 + mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node,
18049 + &dsi->encoder);
18053 - if (dsi->cdata->enable_grf_reg)
18054 - regmap_write(dsi->grf_regmap, dsi->cdata->enable_grf_reg,
18055 - dsi->cdata->enable);
18056 -}
18057 + if (dsi->cdata->lcdsel_grf_reg) {
18058 + regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
18059 + mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
18061 -static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi,
18062 - int mux)
18063 -{
18064 - regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
18065 - mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
18066 + if (dsi->slave && dsi->slave->cdata->lcdsel_grf_reg)
18067 + regmap_write(dsi->slave->grf_regmap,
18068 + dsi->slave->cdata->lcdsel_grf_reg,
18069 + mux ? dsi->slave->cdata->lcdsel_lit :
18070 + dsi->slave->cdata->lcdsel_big);
18075 @@ -720,6 +735,8 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
18079 + struct drm_connector *connector = conn_state->connector;
18080 + struct drm_display_info *info = &connector->display_info;
18082 switch (dsi->format) {
18084 @@ -736,9 +753,42 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
18085 return -EINVAL;
18088 + if (info->num_bus_formats)
18089 + s->bus_format = info->bus_formats[0];
18091 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
18094 + if (dsi->cdata->soc_type == RK3568) {
18095 + s->bus_flags &= ~DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
18096 + s->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
18099 s->output_type = DRM_MODE_CONNECTOR_DSI;
18100 - if (dsi->slave)
18101 - s->output_flags = ROCKCHIP_OUTPUT_DSI_DUAL;
18102 + s->color_space = V4L2_COLORSPACE_DEFAULT;
18103 + s->output_if = dsi->id ? VOP_OUTPUT_IF_MIPI1 : VOP_OUTPUT_IF_MIPI0;
18104 + if (dsi->slave) {
18105 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
18106 + s->output_if |= VOP_OUTPUT_IF_MIPI1;
18110 + if (dsi->id && dsi->cdata->soc_type == RK3399)
18111 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
18113 + if (dsi->dsc_enable) {
18114 + s->dsc_enable = 1;
18115 + s->dsc_sink_cap.version_major = dsi->version_major;
18116 + s->dsc_sink_cap.version_minor = dsi->version_minor;
18117 + s->dsc_sink_cap.slice_width = dsi->slice_width;
18118 + s->dsc_sink_cap.slice_height = dsi->slice_height;
18120 + s->dsc_sink_cap.target_bits_per_pixel_x16 = 8 << 4;
18121 + s->dsc_sink_cap.block_pred = dsi->block_pred_enable;
18122 + s->dsc_sink_cap.native_420 = 0;
18124 + memcpy(&s->pps, dsi->pps, sizeof(struct drm_dsc_picture_parameter_set));
18129 @@ -746,42 +796,43 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
18133 - int ret, mux;
18135 - mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node,
18136 - &dsi->encoder);
18137 - if (mux < 0)
18138 - return;
18142 - pm_runtime_get_sync(dsi->dev);
18143 - if (dsi->slave)
18144 - pm_runtime_get_sync(dsi->slave->dev);
18149 - /*
18150 - * For the RK3399, the clk of grf must be enabled before writing grf
18151 - * register. And for RK3288 or other soc, this grf_clk must be NULL,
18152 - * the clk_prepare_enable return true directly.
18153 - */
18154 - ret = clk_prepare_enable(dsi->grf_clk);
18155 - if (ret) {
18156 - DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
18157 - return;
18161 + pm_runtime_get_sync(dsi->dev);
18162 + phy_init(dsi->phy);
18163 + dsi->phy_enabled = true;
18164 + if (dsi->phy)
18165 + dsi->phy->power_count++;
18167 + pm_runtime_put(dsi->dev);
18168 + phy_exit(dsi->phy);
18169 + dsi->phy_enabled = false;
18170 + if (dsi->phy)
18171 + dsi->phy->power_count--;
18174 - dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux);
18175 if (dsi->slave)
18176 - dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux);
18177 -
18178 - clk_disable_unprepare(dsi->grf_clk);
18179 + dw_mipi_dsi_rockchip_loader_protect(dsi->slave, on);
18182 -static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
18188 - if (dsi->slave)
18189 - pm_runtime_put(dsi->slave->dev);
18190 - pm_runtime_put(dsi->dev);
18191 + if (dsi->panel)
18192 + panel_simple_loader_protect(dsi->panel);
18198 @@ -797,8 +848,8 @@ static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
18199 struct drm_encoder *encoder = &dsi->encoder;
18202 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
18203 - dsi->dev->of_node);
18204 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
18205 + dsi->dev->of_node);
18209 @@ -814,61 +865,90 @@ static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
18213 - const struct of_device_id *match;
18214 - struct device_node *node = NULL, *local;
18215 -
18216 - match = of_match_device(dsi->dev->driver->of_match_table, dsi->dev);
18217 -
18218 - local = of_graph_get_remote_node(dsi->dev->of_node, 1, 0);
18219 - if (!local)
18220 - return NULL;
18221 -
18222 - while ((node = of_find_compatible_node(node, NULL,
18223 - match->compatible))) {
18224 - struct device_node *remote;
18229 + node = of_parse_phandle(dsi->dev->of_node, "rockchip,dual-channel", 0);
18233 + return ERR_PTR(-EPROBE_DEFER);
18238 + return ERR_PTR(-EPROBE_DEFER);
18241 - /* found ourself */
18242 - if (node == dsi->dev->of_node)
18243 - continue;
18244 + return &pdev->dev;
18247 - remote = of_graph_get_remote_node(node, 1, 0);
18248 - if (!remote)
18249 - continue;
18253 - /* same display device in port1-ep0 for both */
18254 - if (remote == local) {
18255 - struct dw_mipi_dsi_rockchip *dsi2;
18256 - struct platform_device *pdev;
18270 + return -ENODEV;
18273 + np = panel->dev->of_node;
18275 + np = bridge->of_node;
18277 + dsi->c_option = of_property_read_bool(np, "phy-c-option");
18278 + dsi->scrambling_en = of_property_read_bool(np, "scrambling-enable");
18279 + dsi->dsc_enable = of_property_read_bool(np, "compressed-data");
18280 + dsi->block_pred_enable = of_property_read_bool(np, "blk-pred-enable");
18281 + of_property_read_u32(np, "slice-width", &dsi->slice_width);
18282 + of_property_read_u32(np, "slice-height", &dsi->slice_height);
18283 + of_property_read_u32(np, "slice-per-pkt", &dsi->slice_per_pkt);
18284 + of_property_read_u8(np, "version-major", &dsi->version_major);
18285 + of_property_read_u8(np, "version-minor", &dsi->version_minor);
18287 + data = of_get_property(np, "panel-init-sequence", &len);
18289 + return -EINVAL;
18291 - pdev = of_find_device_by_node(node);
18292 + d = devm_kmemdup(dsi->dev, data, len, GFP_KERNEL);
18294 + return -ENOMEM;
18296 - /*
18297 - * we have found the second, so will either return it
18298 - * or return with an error. In any case won't need the
18299 - * nodes anymore nor continue the loop.
18300 - */
18301 - of_node_put(remote);
18302 - of_node_put(node);
18303 - of_node_put(local);
18307 + len -= sizeof(*header);
18309 - if (!pdev)
18310 - return ERR_PTR(-EPROBE_DEFER);
18311 + if (header->payload_length > len)
18312 + return -EINVAL;
18314 - dsi2 = platform_get_drvdata(pdev);
18315 - if (!dsi2) {
18316 - platform_device_put(pdev);
18317 - return ERR_PTR(-EPROBE_DEFER);
18318 - }
18319 + if (header->cmd_type == MIPI_DSI_PICTURE_PARAMETER_SET) {
18320 + dsc_packed_pps = devm_kmemdup(dsi->dev, d,
18321 + header->payload_length, GFP_KERNEL);
18323 + return -ENOMEM;
18325 - return &pdev->dev;
18330 - of_node_put(remote);
18331 + d += header->payload_length;
18332 + len -= header->payload_length;
18334 + dsi->pps = pps;
18336 - of_node_put(local);
18337 -
18338 - return NULL;
18343 @@ -878,7 +958,6 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18347 - bool master1, master2;
18351 @@ -886,27 +965,7 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18355 - master1 = of_property_read_bool(dsi->dev->of_node,
18356 - "clock-master");
18357 - master2 = of_property_read_bool(second->of_node,
18358 - "clock-master");
18359 -
18360 - if (master1 && master2) {
18361 - DRM_DEV_ERROR(dsi->dev, "only one clock-master allowed\n");
18362 - return -EINVAL;
18363 - }
18364 -
18365 - if (!master1 && !master2) {
18366 - DRM_DEV_ERROR(dsi->dev, "no clock-master defined\n");
18367 - return -EINVAL;
18368 - }
18369 -
18370 /* we are the slave in dual-DSI */
18371 - if (!master1) {
18372 - dsi->is_slave = true;
18373 - return 0;
18374 - }
18375 -
18376 dsi->slave = dev_get_drvdata(second);
18377 if (!dsi->slave) {
18379 @@ -918,30 +977,15 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18383 + if (dsi->is_slave)
18386 ret = clk_prepare_enable(dsi->pllref_clk);
18392 - /*
18393 - * With the GRF clock running, write lane and dual-mode configurations
18394 - * that won't change immediately. If we waited until enable() to do
18395 - * this, things like panel preparation would not be able to send
18396 - * commands over DSI.
18397 - */
18398 - ret = clk_prepare_enable(dsi->grf_clk);
18399 - if (ret) {
18400 - DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
18401 - return ret;
18402 - }
18403 -
18404 - dw_mipi_dsi_rockchip_config(dsi);
18405 - if (dsi->slave)
18406 - dw_mipi_dsi_rockchip_config(dsi->slave);
18407 -
18408 - clk_disable_unprepare(dsi->grf_clk);
18409 -
18413 @@ -954,6 +998,20 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
18417 + ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0,
18418 + &dsi->panel, NULL);
18420 + dev_err(dsi->dev, "failed to find panel\n");
18422 + dw_mipi_dsi_get_dsc_info_from_sink(dsi, dsi->panel, NULL);
18424 + dsi->sub_dev.connector = dw_mipi_dsi_get_connector(dsi->dmd);
18425 + if (dsi->sub_dev.connector) {
18426 + dsi->sub_dev.of_node = dev->of_node;
18427 + dsi->sub_dev.loader_protect = dw_mipi_dsi_rockchip_encoder_loader_protect;
18428 + rockchip_drm_register_sub_dev(&dsi->sub_dev);
18434 @@ -966,6 +1024,9 @@ static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
18435 if (dsi->is_slave)
18438 + if (dsi->sub_dev.connector)
18439 + rockchip_drm_unregister_sub_dev(&dsi->sub_dev);
18441 dw_mipi_dsi_unbind(dsi->dmd);
18443 clk_disable_unprepare(dsi->pllref_clk);
18444 @@ -1051,6 +1112,7 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
18446 if (cdata[i].reg == res->start) {
18447 dsi->cdata = &cdata[i];
18448 + dsi->id = i;
18452 @@ -1070,6 +1132,13 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
18456 + dsi->pclk = devm_clk_get(dev, "pclk");
18457 + if (IS_ERR(dsi->pclk)) {
18458 + ret = PTR_ERR(dsi->pclk);
18463 dsi->pllref_clk = devm_clk_get(dev, "ref");
18464 if (IS_ERR(dsi->pllref_clk)) {
18465 if (dsi->phy) {
18466 @@ -1106,6 +1175,15 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
18470 + if (dsi->cdata->flags & DW_MIPI_NEEDS_HCLK) {
18471 + dsi->hclk = devm_clk_get(dev, "hclk");
18472 + if (IS_ERR(dsi->hclk)) {
18473 + ret = PTR_ERR(dsi->hclk);
18479 dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
18480 if (IS_ERR(dsi->grf_regmap)) {
18481 DRM_DEV_ERROR(dsi->dev, "Unable to get rockchip,grf\n");
18482 @@ -1140,11 +1218,43 @@ static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev)
18486 + if (dsi->devcnt == 0)
18487 + component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops);
18489 dw_mipi_dsi_remove(dsi->dmd);
18498 + clk_disable_unprepare(dsi->grf_clk);
18499 + clk_disable_unprepare(dsi->pclk);
18500 + clk_disable_unprepare(dsi->hclk);
18501 + clk_disable_unprepare(dsi->phy_cfg_clk);
18510 + clk_prepare_enable(dsi->phy_cfg_clk);
18511 + clk_prepare_enable(dsi->hclk);
18512 + clk_prepare_enable(dsi->pclk);
18513 + clk_prepare_enable(dsi->grf_clk);
18526 @@ -1159,6 +1269,8 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
18535 @@ -1171,6 +1283,8 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
18544 @@ -1179,6 +1293,8 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
18553 @@ -1199,6 +1315,8 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
18562 @@ -1225,6 +1343,38 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
18601 @@ -1239,6 +1389,9 @@ static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
18603 .compatible = "rockchip,rk3399-mipi-dsi",
18606 + .compatible = "rockchip,rk3568-mipi-dsi",
18611 @@ -1249,6 +1402,7 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = {
18616 .name = "dw-mipi-dsi-rockchip",
18618 * For dual-DSI display, one DSI pokes at the other DSI's
18619 diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchi…
18621 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
18622 +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
18623 @@ -4,21 +4,31 @@
18655 @@ -29,8 +39,11 @@
18659 -#define RK3328_GRF_SOC_CON2 0x0408
18668 @@ -50,109 +63,350 @@
18672 -#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
18731 * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
18732 * @lcdsel_grf_reg: grf register offset of lcdc select
18760 - struct clk *vpll_clk;
18856 - 27000000, {
18857 - { 0x00b3, 0x0000},
18858 - { 0x2153, 0x0000},
18859 - { 0x40f3, 0x0000}
18860 - },
18861 - }, {
18862 - 36000000, {
18863 - { 0x00b3, 0x0000},
18864 - { 0x2153, 0x0000},
18865 - { 0x40f3, 0x0000}
18866 - },
18867 - }, {
18868 - 40000000, {
18869 - { 0x00b3, 0x0000},
18870 - { 0x2153, 0x0000},
18871 - { 0x40f3, 0x0000}
18872 - },
18873 - }, {
18874 - 54000000, {
18875 - { 0x0072, 0x0001},
18876 - { 0x2142, 0x0001},
18877 - { 0x40a2, 0x0001},
18878 - },
18879 - }, {
18880 - 65000000, {
18881 - { 0x0072, 0x0001},
18882 - { 0x2142, 0x0001},
18883 - { 0x40a2, 0x0001},
18884 - },
18885 - }, {
18886 - 66000000, {
18887 - { 0x013e, 0x0003},
18888 - { 0x217e, 0x0002},
18889 - { 0x4061, 0x0002}
18890 - },
18891 - }, {
18892 - 74250000, {
18893 - { 0x0072, 0x0001},
18894 - { 0x2145, 0x0002},
18895 - { 0x4061, 0x0002}
18896 - },
18897 - }, {
18898 - 83500000, {
18899 - { 0x0072, 0x0001},
18900 - },
18901 - }, {
18902 - 108000000, {
18903 - { 0x0051, 0x0002},
18904 - { 0x2145, 0x0002},
18905 - { 0x4061, 0x0002}
18906 - },
18907 - }, {
18908 - 106500000, {
18909 - { 0x0051, 0x0002},
18910 - { 0x2145, 0x0002},
18911 - { 0x4061, 0x0002}
18912 - },
18913 - }, {
18914 - 146250000, {
18915 - { 0x0051, 0x0002},
18916 - { 0x2145, 0x0002},
18917 - { 0x4061, 0x0002}
18918 - },
18919 - }, {
18920 - 148500000, {
18921 - { 0x0051, 0x0003},
18922 - { 0x214c, 0x0003},
18923 - { 0x4064, 0x0003}
18924 - },
18925 - }, {
19085 - { 0x00a0, 0x000a },
19086 - { 0x2001, 0x000f },
19087 - { 0x4002, 0x000f },
19094 @@ -160,171 +414,2177 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
19098 - 40000000, { 0x0018, 0x0018, 0x0018 },
19099 - }, {
19100 - 65000000, { 0x0028, 0x0028, 0x0028 },
19101 - }, {
19102 - 66000000, { 0x0038, 0x0038, 0x0038 },
19103 - }, {
19104 - 74250000, { 0x0028, 0x0038, 0x0038 },
19105 - }, {
19106 - 83500000, { 0x0028, 0x0038, 0x0038 },
19107 - }, {
19108 - 146250000, { 0x0038, 0x0038, 0x0038 },
19109 - }, {
19110 - 148500000, { 0x0000, 0x0038, 0x0038 },
19111 - }, {
19118 -static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
19122 - { 148500000, 0x802b, 0x0004, 0x028d},
19125 - { ~0UL, 0x0000, 0x0000, 0x0000}
19131 -static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
19350 - struct device_node *np = hdmi->dev->of_node;
19363 - hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
19364 - if (IS_ERR(hdmi->regmap)) {
19365 - DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,grf\n");
19366 - return PTR_ERR(hdmi->regmap);
19394 - hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
19395 - if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
19396 - hdmi->vpll_clk = NULL;
19397 - } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
19398 - return -EPROBE_DEFER;
19399 - } else if (IS_ERR(hdmi->vpll_clk)) {
19400 - DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
19401 - return PTR_ERR(hdmi->vpll_clk);
19416 - hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
19417 - if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
19418 - hdmi->grf_clk = NULL;
19419 - } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
19420 - return -EPROBE_DEFER;
19421 - } else if (IS_ERR(hdmi->grf_clk)) {
19422 - DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
19423 - return PTR_ERR(hdmi->grf_clk);
19460 + hdmi_bus_fmt_color_depth(hdmi->output_bus_format);
19462 + if (!hdmi_bus_fmt_is_yuv422(hdmi->output_bus_format)) {
19486 + return hdmi->id == *id;
19510 + drm_mode_copy(&mode, &crtc_state->mode);
19511 + if (hdmi->plat_data->split_mode)
19514 + max_lanes = hdmi->max_lanes;
19515 + max_rate_per_lane = hdmi->max_frl_rate_per_lane;
19518 + hdmi->link_cfg.dsc_mode = false;
19519 + hdmi->link_cfg.frl_lanes = max_lanes;
19520 + hdmi->link_cfg.rate_per_lane = max_rate_per_lane;
19523 + dev_info(hdmi->dev, "use tmds mode\n");
19524 + hdmi->link_cfg.frl_mode = false;
19528 + hdmi->link_cfg.frl_mode = true;
19530 + if (!hdmi->dsc_cap.v_1p2)
19533 + max_dsc_lanes = hdmi->dsc_cap.max_lanes;
19535 + hdmi->dsc_cap.max_frl_rate_per_lane;
19538 + !hdmi_bus_fmt_is_yuv420(hdmi->bus_format) &&
19539 + !hdmi_bus_fmt_is_yuv422(hdmi->bus_format)) {
19540 + hdmi->link_cfg.dsc_mode = true;
19541 + hdmi->link_cfg.frl_lanes = max_dsc_lanes;
19542 + hdmi->link_cfg.rate_per_lane = max_dsc_rate_per_lane;
19544 + hdmi->link_cfg.dsc_mode = false;
19545 + hdmi->link_cfg.frl_lanes = max_lanes;
19546 + hdmi->link_cfg.rate_per_lane = max_rate_per_lane;
19558 + * Select smallest slice height >=96, that results in a valid PPS and
19593 + int pixel_clock = crtc_state->mode.clock;
19604 + if (hdmi_bus_fmt_is_yuv444(hdmi->output_bus_format) ||
19605 + hdmi_bus_fmt_is_rgb(hdmi->output_bus_format))
19628 + * clock per slice (in MHz) as read from HF-VSDB.
19658 + slice_width = DIV_ROUND_UP(crtc_state->mode.hdisplay, target_slices);
19669 + int hdmi_throughput = hdmi->dsc_cap.clk_per_slice;
19670 + int hdmi_max_slices = hdmi->dsc_cap.max_slices;
19731 + /* src does not support fractional bpp implies decrement by 16 for bppx16 */
19746 + bpp_target_x16 -= bpp_decrement_x16;
19758 + bool hdmi_all_bpp = hdmi->dsc_cap.all_bpp;
19760 + int hdmi_max_chunk_bytes = hdmi->dsc_cap.total_chunk_kbytes * 1024;
19781 + hdmi_bus_fmt_is_rgb(hdmi->output_bus_format) == pps_datas[i].convert_rgb)
19785 + dev_err(hdmi->dev, "can't find pps cfg!\n");
19786 + return -EINVAL;
19789 + memcpy(hdmi->link_cfg.pps_payload, pps_datas[i].raw_pps, 128);
19790 + hdmi->link_cfg.hcactive = DIV_ROUND_UP(slice_width * (bits_per_pixel / 16), 8) *
19806 + unsigned int depth = hdmi_bus_fmt_color_depth(hdmi->output_bus_format);
19811 + hdmi_is_dsc_1_2 = hdmi->dsc_cap.v_1p2;
19816 + slice_height = hdmi_dsc_get_slice_height(crtc_state->mode.vdisplay);
19824 + slice_width = DIV_ROUND_UP(crtc_state->mode.hdisplay, slice_count);
19830 + ret = dw_hdmi_qp_set_link_cfg(hdmi, crtc_state->mode.hdisplay,
19831 + crtc_state->mode.vdisplay, slice_width,
19835 + dev_err(hdmi->dev, "set vdsc cfg failed\n");
19838 + dev_info(hdmi->dev, "dsc_enable\n");
19839 + s->dsc_enable = 1;
19840 + s->dsc_sink_cap.version_major = 1;
19841 + s->dsc_sink_cap.version_minor = 2;
19842 + s->dsc_sink_cap.slice_width = slice_width;
19843 + s->dsc_sink_cap.slice_height = slice_height;
19844 + s->dsc_sink_cap.target_bits_per_pixel_x16 = bits_per_pixel;
19845 + s->dsc_sink_cap.block_pred = 1;
19846 + s->dsc_sink_cap.native_420 = 0;
19848 + memcpy(&s->pps, hdmi->link_cfg.pps_payload, 128);
19859 + dev_err(hdmi->dev, "phy table array number is out of range\n");
19860 + return -E2BIG;
19881 + change = drm_helper_hpd_irq_event(hdmi->drm_dev);
19883 + dev_dbg(hdmi->dev, "hpd stat changed:%d\n", hdmi->hpd_stat);
19884 + dw_hdmi_qp_cec_set_hpd(hdmi->hdmi_qp, hdmi->hpd_stat, change);
19893 + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
19896 + dev_dbg(hdmi->dev, "hpd irq %#x\n", intr_stat);
19898 + if (!hdmi->id)
19904 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
19918 + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
19923 + if (!hdmi->id) {
19939 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
19942 + hdmi->hpd_stat = true;
19945 + hdmi->hpd_stat = false;
19948 + mod_delayed_work(hdmi->workqueue, &hdmi->work, msecs_to_jiffies(msecs));
19950 + if (!hdmi->id) {
19960 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
19967 + hdmi->workqueue = create_workqueue("hpd_queue");
19968 + INIT_DELAYED_WORK(&hdmi->work, repo_hpd_event);
19975 + struct device_node *np = hdmi->dev->of_node;
19977 + hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
19978 + if (IS_ERR(hdmi->regmap)) {
19979 + DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,grf\n");
19980 + return PTR_ERR(hdmi->regmap);
19983 + if (hdmi->is_hdmi_qp) {
19984 + hdmi->vo1_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,vo1_grf");
19985 + if (IS_ERR(hdmi->vo1_regmap)) {
19986 + DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,vo1_grf\n");
19987 + return PTR_ERR(hdmi->vo1_regmap);
19991 + hdmi->phyref_clk = devm_clk_get(hdmi->dev, "vpll");
19992 + if (PTR_ERR(hdmi->phyref_clk) == -ENOENT)
19993 + hdmi->phyref_clk = devm_clk_get(hdmi->dev, "ref");
19995 + if (PTR_ERR(hdmi->phyref_clk) == -ENOENT) {
19996 + hdmi->phyref_clk = NULL;
19997 + } else if (PTR_ERR(hdmi->phyref_clk) == -EPROBE_DEFER) {
19998 + return -EPROBE_DEFER;
19999 + } else if (IS_ERR(hdmi->phyref_clk)) {
20000 + DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
20001 + return PTR_ERR(hdmi->phyref_clk);
20004 + hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
20005 + if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
20006 + hdmi->grf_clk = NULL;
20007 + } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
20008 + return -EPROBE_DEFER;
20009 + } else if (IS_ERR(hdmi->grf_clk)) {
20010 + DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
20011 + return PTR_ERR(hdmi->grf_clk);
20014 + hdmi->hclk_vio = devm_clk_get(hdmi->dev, "hclk_vio");
20015 + if (PTR_ERR(hdmi->hclk_vio) == -ENOENT) {
20016 + hdmi->hclk_vio = NULL;
20017 + } else if (PTR_ERR(hdmi->hclk_vio) == -EPROBE_DEFER) {
20018 + return -EPROBE_DEFER;
20019 + } else if (IS_ERR(hdmi->hclk_vio)) {
20020 + dev_err(hdmi->dev, "failed to get hclk_vio clock\n");
20021 + return PTR_ERR(hdmi->hclk_vio);
20024 + hdmi->hclk_vop = devm_clk_get(hdmi->dev, "hclk");
20025 + if (PTR_ERR(hdmi->hclk_vop) == -ENOENT) {
20026 + hdmi->hclk_vop = NULL;
20027 + } else if (PTR_ERR(hdmi->hclk_vop) == -EPROBE_DEFER) {
20028 + return -EPROBE_DEFER;
20029 + } else if (IS_ERR(hdmi->hclk_vop)) {
20030 + dev_err(hdmi->dev, "failed to get hclk_vop clock\n");
20031 + return PTR_ERR(hdmi->hclk_vop);
20034 + hdmi->aud_clk = devm_clk_get_optional(hdmi->dev, "aud");
20035 + if (IS_ERR(hdmi->aud_clk)) {
20036 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->aud_clk),
20038 + return PTR_ERR(hdmi->aud_clk);
20041 + hdmi->hpd_clk = devm_clk_get_optional(hdmi->dev, "hpd");
20042 + if (IS_ERR(hdmi->hpd_clk)) {
20043 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hpd_clk),
20045 + return PTR_ERR(hdmi->hpd_clk);
20048 + hdmi->hclk_vo1 = devm_clk_get_optional(hdmi->dev, "hclk_vo1");
20049 + if (IS_ERR(hdmi->hclk_vo1)) {
20050 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hclk_vo1),
20052 + return PTR_ERR(hdmi->hclk_vo1);
20055 + hdmi->earc_clk = devm_clk_get_optional(hdmi->dev, "earc");
20056 + if (IS_ERR(hdmi->earc_clk)) {
20057 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->earc_clk),
20059 + return PTR_ERR(hdmi->earc_clk);
20062 + hdmi->hdmitx_ref = devm_clk_get_optional(hdmi->dev, "hdmitx_ref");
20063 + if (IS_ERR(hdmi->hdmitx_ref)) {
20064 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hdmitx_ref),
20066 + return PTR_ERR(hdmi->hdmitx_ref);
20069 + hdmi->pclk = devm_clk_get_optional(hdmi->dev, "pclk");
20070 + if (IS_ERR(hdmi->pclk)) {
20071 + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->pclk),
20073 + return PTR_ERR(hdmi->pclk);
20076 + hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable",
20078 + if (IS_ERR(hdmi->enable_gpio)) {
20079 + ret = PTR_ERR(hdmi->enable_gpio);
20080 + dev_err(hdmi->dev, "failed to request enable GPIO: %d\n", ret);
20084 + hdmi->skip_check_420_mode =
20085 + of_property_read_bool(np, "skip-check-420-mode");
20087 + if (of_get_property(np, "rockchip,phy-table", &val)) {
20091 + dev_err(hdmi->dev, "kmalloc phy table failed\n");
20093 + return -ENOMEM;
20096 + of_property_read_u32_array(np, "rockchip,phy-table",
20106 + dev_dbg(hdmi->dev, "use default hdmi phy table\n");
20117 + struct drm_encoder *encoder = connector->encoder;
20119 + struct drm_device *dev = connector->dev;
20120 + struct rockchip_drm_private *priv = dev->dev_private;
20129 + if (mode->clock > INT_MAX / 1000)
20135 + funcs = connector->helper_private;
20136 + if (funcs->atomic_best_encoder)
20137 + encoder = funcs->atomic_best_encoder(connector,
20138 + connector->state);
20140 + encoder = funcs->best_encoder(connector);
20143 + if (!encoder || !encoder->possible_crtcs)
20153 + if (!hdmi->skip_check_420_mode) {
20154 + if (mode->clock > 340000 &&
20155 + connector->display_info.max_tmds_clock < 340000 &&
20156 + (!drm_mode_is_420(&connector->display_info, mode) ||
20157 + !connector->ycbcr_420_allowed))
20160 + if (hdmi->max_tmdsclk <= 340000 && mode->clock > 340000 &&
20161 + !drm_mode_is_420(&connector->display_info, mode))
20165 + if (hdmi->phy) {
20166 + if (hdmi->is_hdmi_qp)
20167 + phy_set_bus_width(hdmi->phy, mode->clock * 10);
20169 + phy_set_bus_width(hdmi->phy, 8);
20177 + drm_for_each_crtc(crtc, connector->dev) {
20180 + priv->crtc_funcs[pipe];
20182 + if (!(encoder->possible_crtcs & drm_crtc_mask(crtc)))
20184 + if (!funcs || !funcs->mode_valid)
20187 + status = funcs->mode_valid(crtc, mode,
20199 + struct drm_crtc *crtc = encoder->crtc;
20200 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
20202 + if (crtc->state->active_changed) {
20203 + if (hdmi->plat_data->split_mode) {
20204 + s->output_if &= ~(VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1);
20206 + if (!hdmi->id)
20207 + s->output_if &= ~VOP_OUTPUT_IF_HDMI1;
20209 + s->output_if &= ~VOP_OUTPUT_IF_HDMI0;
20216 + if (hdmi->phy)
20217 + phy_set_bus_width(hdmi->phy, 8);
20223 + struct drm_crtc *crtc = encoder->crtc;
20228 + if (WARN_ON(!crtc || !crtc->state))
20231 + if (hdmi->phy)
20232 + phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
20234 + clk_set_rate(hdmi->phyref_clk,
20235 + crtc->state->adjusted_mode.crtc_clock * 1000);
20237 + if (hdmi->chip_data->lcdsel_grf_reg < 0)
20240 + mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
20242 + val = hdmi->chip_data->lcdsel_lit;
20244 + val = hdmi->chip_data->lcdsel_big;
20246 + ret = clk_prepare_enable(hdmi->grf_clk);
20248 + DRM_DEV_ERROR(hdmi->dev, "failed to enable grfclk %d\n", ret);
20252 + ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
20254 + DRM_DEV_ERROR(hdmi->dev, "Could not write to GRF: %d\n", ret);
20256 + if (hdmi->chip_data->lcdsel_grf_reg == RK3288_GRF_SOC_CON6) {
20258 + to_rockchip_crtc_state(crtc->state);
20262 + if (s->output_mode == ROCKCHIP_OUT_MODE_YUV420)
20267 + regmap_write(hdmi->regmap, RK3288_GRF_SOC_CON16, val);
20270 + clk_disable_unprepare(hdmi->grf_clk);
20271 + DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
20280 + if (!hdmi->id)
20285 + if (!hdmi->link_cfg.frl_mode) {
20288 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON4, val);
20290 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON7, val);
20294 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20296 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20303 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON4, val);
20305 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON7, val);
20307 + if (hdmi->link_cfg.dsc_mode) {
20311 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20313 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20317 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20319 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20342 + dev_err(hdmi->dev, "can't set correct color format\n");
20346 + if (hdmi->link_cfg.dsc_mode)
20354 + if (!hdmi->id)
20355 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
20357 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
20366 + color_depth = hdmi_bus_fmt_color_depth(hdmi->bus_format);
20367 + rk3588_set_color_format(hdmi, hdmi->bus_format, color_depth);
20381 + struct drm_display_info *info = &conn_state->connector->display_info;
20389 + u32 max_tmds_clock = info->max_tmds_clock;
20392 + drm_mode_copy(&mode, &crtc_state->mode);
20394 + if (hdmi->plat_data->split_mode) {
20401 + if (!hdmi->is_hdmi_qp)
20402 + sink_is_hdmi = dw_hdmi_get_output_whether_hdmi(hdmi->hdmi);
20406 + switch (hdmi->hdmi_output) {
20408 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
20410 + else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20412 + else if (conn_state->connector->ycbcr_420_allowed &&
20414 + (pixclock >= 594000 && !hdmi->is_hdmi_qp))
20418 + if (conn_state->connector->ycbcr_420_allowed &&
20421 + else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20423 + else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
20427 + if (conn_state->connector->ycbcr_420_allowed &&
20432 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20436 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
20445 + info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
20448 + info->edid_hdmi_dc_modes &
20454 + info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
20457 + if (hdmi->colordepth > 8 && support_dc)
20468 + if (conn_state->hdr_output_metadata) {
20470 + conn_state->hdr_output_metadata->data;
20471 + output_eotf = hdr_metadata->hdmi_metadata_type1.eotf;
20477 + hdmi->colorimetry = conn_state->colorspace;
20480 + conn_state->connector->hdr_sink_metadata.hdmi_type1.eotf &
20481 + BIT(*eotf)) || ((hdmi->colorimetry >= DRM_MODE_COLORIMETRY_BT2020_CYCC) &&
20482 + (hdmi->colorimetry <= DRM_MODE_COLORIMETRY_BT2020_YCC)))
20494 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
20496 + if (hdmi->is_hdmi_qp) {
20497 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB420) {
20526 + max_tmds_clock = min(max_tmds_clock, hdmi->max_tmdsclk);
20528 + if ((tmdsclock > max_tmds_clock) && !hdmi->is_hdmi_qp) {
20541 + if (mode.clock >= 340000 && hdmi->is_hdmi_qp)
20555 + !hdmi->unsupported_yuv_input)
20561 + !hdmi->unsupported_yuv_input)
20572 + hdmi->bus_format = *bus_format;
20576 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY12_1X24;
20578 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY10_1X20;
20580 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY8_1X16;
20582 + hdmi->output_bus_format = *bus_format;
20590 + struct drm_crtc_state *crtc_state = conn_state->crtc->state;
20593 + unsigned long output_bus_format = hdmi->output_bus_format;
20594 + unsigned long enc_out_encoding = hdmi->enc_out_encoding;
20601 + &hdmi->enc_out_encoding, &eotf);
20603 + if (output_bus_format != hdmi->output_bus_format ||
20604 + enc_out_encoding != hdmi->enc_out_encoding)
20629 + drm_mode_copy(&mode, &crtc_state->mode);
20631 + hdmi->vp_id = s->vp_id;
20632 + if (hdmi->plat_data->split_mode)
20638 + &hdmi->enc_out_encoding, &s->eotf);
20640 + s->bus_format = bus_format;
20641 + if (hdmi->is_hdmi_qp) {
20643 + tmdsclk = hdmi_get_tmdsclock(hdmi, crtc_state->mode.clock);
20644 + if (hdmi_bus_fmt_is_yuv420(hdmi->output_bus_format))
20648 + if (hdmi->link_cfg.frl_mode) {
20649 + gpiod_set_value(hdmi->enable_gpio, 0);
20651 + if (hdmi->link_cfg.rate_per_lane >= 10) {
20652 + hdmi->link_cfg.frl_lanes = 4;
20653 + hdmi->link_cfg.rate_per_lane = 10;
20655 + bus_width = hdmi->link_cfg.frl_lanes *
20656 + hdmi->link_cfg.rate_per_lane * 1000000;
20664 + gpiod_set_value(hdmi->enable_gpio, 1);
20666 + if (hdmi_bus_fmt_is_yuv420(hdmi->output_bus_format))
20674 + hdmi->phy_bus_width = bus_width;
20676 + if (hdmi->phy)
20677 + phy_set_bus_width(hdmi->phy, bus_width);
20679 + s->output_type = DRM_MODE_CONNECTOR_HDMIA;
20680 + s->tv_state = &conn_state->tv;
20682 + if (hdmi->plat_data->split_mode) {
20683 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
20684 + if (hdmi->plat_data->right && hdmi->id)
20685 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
20686 + s->output_if |= VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1;
20688 + if (!hdmi->id)
20689 + s->output_if |= VOP_OUTPUT_IF_HDMI0;
20691 + s->output_if |= VOP_OUTPUT_IF_HDMI1;
20694 + s->output_mode = output_mode;
20695 + hdmi->bus_format = s->bus_format;
20697 + if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_BT2020)
20698 + s->color_space = V4L2_COLORSPACE_BT2020;
20700 + s->color_space = V4L2_COLORSPACE_DEFAULT;
20701 + else if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_709)
20702 + s->color_space = V4L2_COLORSPACE_REC709;
20704 + s->color_space = V4L2_COLORSPACE_SMPTE170M;
20706 + if (hdmi->plat_data->split_mode && !secondary) {
20707 + hdmi = rockchip_hdmi_find_by_id(hdmi->dev->driver, !hdmi->id);
20721 + return hdmi->bus_format;
20729 + return hdmi->output_bus_format;
20737 + return hdmi->enc_out_encoding;
20745 + return hdmi->enc_out_encoding;
20753 + return hdmi->hdmi_quant_range;
20761 + return hdmi->hdr_panel_metadata_property;
20769 + return hdmi->hdr_panel_blob_ptr;
20778 + if (hdmi->color_changed)
20780 + hdmi->color_changed = 0;
20790 + return -EINVAL;
20801 + return -EINVAL;
20803 + return rockchip_drm_parse_cea_ext(&hdmi->dsc_cap,
20804 + &hdmi->max_frl_rate_per_lane,
20805 + &hdmi->max_lanes, edid);
20814 + struct next_hdr_sink_data *sink_data = &hdmi->next_hdr_data;
20816 + struct drm_property *property = hdmi->next_hdr_sink_data_property;
20817 + struct drm_property_blob *blob = hdmi->hdr_panel_blob_ptr;
20820 + return -EINVAL;
20824 + ret = drm_property_replace_global_blob(connector->dev, &blob, size, sink_data,
20825 + &connector->base, property);
20835 + return &hdmi->link_cfg;
20845 + snprintf(clk_name, sizeof(clk_name), "dclk_vp%d", hdmi->vp_id);
20847 + dclk = devm_clk_get(hdmi->dev, clk_name);
20849 + DRM_DEV_ERROR(hdmi->dev, "failed to get %s\n", clk_name);
20856 + DRM_DEV_ERROR(hdmi->dev, "failed to enable dclk for video port%d - %d\n",
20857 + hdmi->vp_id, ret);
20905 + struct rockchip_drm_private *private = connector->dev->dev_private;
20909 + hdmi->hdmi_output = RK_IF_FORMAT_RGB;
20910 + hdmi->colordepth = 10;
20913 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR444;
20914 + hdmi->colordepth = 8;
20917 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR444;
20918 + hdmi->colordepth = 10;
20921 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR422;
20922 + hdmi->colordepth = 10;
20925 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR422;
20926 + hdmi->colordepth = 8;
20929 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR420;
20930 + hdmi->colordepth = 8;
20933 + hdmi->hdmi_output = RK_IF_FORMAT_YCBCR420;
20934 + hdmi->colordepth = 10;
20937 + hdmi->hdmi_output = RK_IF_FORMAT_RGB;
20938 + hdmi->colordepth = 8;
20941 + hdmi->bus_format = color;
20943 + if (hdmi->hdmi_output == RK_IF_FORMAT_YCBCR422) {
20944 + if (hdmi->colordepth == 12)
20945 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY12_1X24;
20946 + else if (hdmi->colordepth == 10)
20947 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY10_1X20;
20949 + hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY8_1X16;
20951 + hdmi->output_bus_format = hdmi->bus_format;
20955 + if (!hdmi->color_depth_property && !hdmi->unsupported_deep_color) {
20956 + prop = drm_property_create_enum(connector->dev, 0,
20961 + hdmi->color_depth_property = prop;
20962 + drm_object_attach_property(&connector->base, prop, 0);
20966 + prop = drm_property_create_enum(connector->dev, 0, RK_IF_PROP_COLOR_FORMAT,
20970 + hdmi->hdmi_output_property = prop;
20971 + drm_object_attach_property(&connector->base, prop, 0);
20974 + prop = drm_property_create_range(connector->dev, 0,
20978 + hdmi->colordepth_capacity = prop;
20979 + drm_object_attach_property(&connector->base, prop, 0);
20982 + prop = drm_property_create_range(connector->dev, 0,
20986 + hdmi->outputmode_capacity = prop;
20987 + drm_object_attach_property(&connector->base, prop, 0);
20990 + prop = drm_property_create(connector->dev,
20995 + hdmi->hdr_panel_metadata_property = prop;
20996 + drm_object_attach_property(&connector->base, prop, 0);
20999 + prop = drm_property_create(connector->dev,
21004 + hdmi->next_hdr_sink_data_property = prop;
21005 + drm_object_attach_property(&connector->base, prop, 0);
21008 + prop = drm_property_create_bool(connector->dev, DRM_MODE_PROP_IMMUTABLE,
21011 + hdmi->user_split_mode_prop = prop;
21012 + drm_object_attach_property(&connector->base, prop,
21013 + hdmi->user_split_mode ? 1 : 0);
21016 + if (!hdmi->is_hdmi_qp) {
21017 + prop = drm_property_create_enum(connector->dev, 0,
21022 + hdmi->output_hdmi_dvi = prop;
21023 + drm_object_attach_property(&connector->base, prop, 0);
21026 + prop = drm_property_create_enum(connector->dev, 0,
21031 + hdmi->output_type_capacity = prop;
21032 + drm_object_attach_property(&connector->base, prop, 0);
21035 + prop = drm_property_create_enum(connector->dev, 0,
21040 + hdmi->quant_range = prop;
21041 + drm_object_attach_property(&connector->base, prop, 0);
21045 + prop = connector->dev->mode_config.hdr_output_metadata_property;
21046 + if (version >= 0x211a || hdmi->is_hdmi_qp)
21047 + drm_object_attach_property(&connector->base, prop, 0);
21050 + drm_object_attach_property(&connector->base,
21051 + connector->colorspace_property, 0);
21052 + drm_object_attach_property(&connector->base, private->connector_id_prop, hdmi->id);
21061 + if (hdmi->color_depth_property) {
21062 + drm_property_destroy(connector->dev,
21063 + hdmi->color_depth_property);
21064 + hdmi->color_depth_property = NULL;
21067 + if (hdmi->hdmi_output_property) {
21068 + drm_property_destroy(connector->dev,
21069 + hdmi->hdmi_output_property);
21070 + hdmi->hdmi_output_property = NULL;
21073 + if (hdmi->colordepth_capacity) {
21074 + drm_property_destroy(connector->dev,
21075 + hdmi->colordepth_capacity);
21076 + hdmi->colordepth_capacity = NULL;
21079 + if (hdmi->outputmode_capacity) {
21080 + drm_property_destroy(connector->dev,
21081 + hdmi->outputmode_capacity);
21082 + hdmi->outputmode_capacity = NULL;
21085 + if (hdmi->quant_range) {
21086 + drm_property_destroy(connector->dev,
21087 + hdmi->quant_range);
21088 + hdmi->quant_range = NULL;
21091 + if (hdmi->hdr_panel_metadata_property) {
21092 + drm_property_destroy(connector->dev,
21093 + hdmi->hdr_panel_metadata_property);
21094 + hdmi->hdr_panel_metadata_property = NULL;
21097 + if (hdmi->next_hdr_sink_data_property) {
21098 + drm_property_destroy(connector->dev,
21099 + hdmi->next_hdr_sink_data_property);
21100 + hdmi->next_hdr_sink_data_property = NULL;
21103 + if (hdmi->output_hdmi_dvi) {
21104 + drm_property_destroy(connector->dev,
21105 + hdmi->output_hdmi_dvi);
21106 + hdmi->output_hdmi_dvi = NULL;
21109 + if (hdmi->output_type_capacity) {
21110 + drm_property_destroy(connector->dev,
21111 + hdmi->output_type_capacity);
21112 + hdmi->output_type_capacity = NULL;
21115 - return 0;
21116 + if (hdmi->user_split_mode_prop) {
21117 + drm_property_destroy(connector->dev,
21118 + hdmi->user_split_mode_prop);
21119 + hdmi->user_split_mode_prop = NULL;
21123 -static enum drm_mode_status
21124 -dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
21125 - const struct drm_display_info *info,
21126 - const struct drm_display_mode *mode)
21134 - const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
21135 - int pclk = mode->clock * 1000;
21136 - bool valid = false;
21137 - int i;
21138 -
21139 - for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
21140 - if (pclk == mpll_cfg[i].mpixelclock) {
21141 - valid = true;
21142 - break;
21143 - }
21145 + struct drm_mode_config *config = &connector->dev->mode_config;
21147 + if (property == hdmi->color_depth_property) {
21148 + hdmi->colordepth = val;
21149 + /* If hdmi is disconnected, state->crtc is null */
21150 + if (!state->crtc)
21153 + hdmi->color_changed++;
21155 + } else if (property == hdmi->hdmi_output_property) {
21156 + hdmi->hdmi_output = val;
21157 + if (!state->crtc)
21160 + hdmi->color_changed++;
21162 + } else if (property == hdmi->quant_range) {
21163 + u64 quant_range = hdmi->hdmi_quant_range;
21165 + hdmi->hdmi_quant_range = val;
21166 + if (quant_range != hdmi->hdmi_quant_range)
21167 + dw_hdmi_set_quant_range(hdmi->hdmi);
21169 + } else if (property == config->hdr_output_metadata_property) {
21171 + } else if (property == hdmi->output_hdmi_dvi) {
21172 + if (hdmi->force_output != val)
21173 + hdmi->color_changed++;
21174 + hdmi->force_output = val;
21175 + dw_hdmi_set_output_type(hdmi->hdmi, val);
21177 + } else if (property == hdmi->colordepth_capacity) {
21179 + } else if (property == hdmi->outputmode_capacity) {
21181 + } else if (property == hdmi->output_type_capacity) {
21185 - return (valid) ? MODE_OK : MODE_BAD;
21186 -}
21188 + property->base.id, property->name);
21190 -static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
21191 -{
21192 + return -EINVAL;
21195 -static bool
21196 -dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
21197 - const struct drm_display_mode *mode,
21198 - struct drm_display_mode *adj_mode)
21206 - return true;
21207 -}
21209 + struct drm_display_info *info = &connector->display_info;
21210 + struct drm_mode_config *config = &connector->dev->mode_config;
21212 + if (property == hdmi->color_depth_property) {
21213 + *val = hdmi->colordepth;
21215 + } else if (property == hdmi->hdmi_output_property) {
21216 + *val = hdmi->hdmi_output;
21218 + } else if (property == hdmi->colordepth_capacity) {
21221 + if (hdmi->unsupported_deep_color)
21223 + if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
21225 + if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36)
21227 + if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_48)
21229 + if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
21231 + if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
21233 + if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
21236 + } else if (property == hdmi->outputmode_capacity) {
21238 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
21240 + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
21242 + if (connector->ycbcr_420_allowed &&
21243 + info->color_formats & DRM_COLOR_FORMAT_YCRCB420)
21246 + } else if (property == hdmi->quant_range) {
21247 + *val = hdmi->hdmi_quant_range;
21249 + } else if (property == config->hdr_output_metadata_property) {
21250 + *val = state->hdr_output_metadata ?
21251 + state->hdr_output_metadata->base.id : 0;
21253 + } else if (property == hdmi->output_hdmi_dvi) {
21254 + *val = hdmi->force_output;
21256 + } else if (property == hdmi->output_type_capacity) {
21257 + *val = dw_hdmi_get_output_type_cap(hdmi->hdmi);
21259 + } else if (property == hdmi->user_split_mode_prop) {
21260 + *val = hdmi->user_split_mode;
21264 -static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
21265 - struct drm_display_mode *mode,
21266 - struct drm_display_mode *adj_mode)
21267 -{
21268 - struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
21270 + property->base.id, property->name);
21272 - clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
21273 + return -EINVAL;
21276 -static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
21289 - u32 val;
21290 - int ret;
21294 - if (hdmi->chip_data->lcdsel_grf_reg < 0)
21295 + if (!encoder->crtc)
21297 + crtc = encoder->crtc;
21299 - ret = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
21300 - if (ret)
21301 - val = hdmi->chip_data->lcdsel_lit;
21302 - else
21303 - val = hdmi->chip_data->lcdsel_big;
21304 -
21305 - ret = clk_prepare_enable(hdmi->grf_clk);
21306 - if (ret < 0) {
21307 - DRM_DEV_ERROR(hdmi->dev, "failed to enable grfclk %d\n", ret);
21308 + if (!crtc->state)
21310 - }
21311 + s = to_rockchip_crtc_state(crtc->state);
21313 - ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
21314 - if (ret != 0)
21315 - DRM_DEV_ERROR(hdmi->dev, "Could not write to GRF: %d\n", ret);
21316 -
21317 - clk_disable_unprepare(hdmi->grf_clk);
21318 - DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
21319 - ret ? "LIT" : "BIG");
21320 -}
21324 -static int
21325 -dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
21326 - struct drm_crtc_state *crtc_state,
21327 - struct drm_connector_state *conn_state)
21328 -{
21329 - struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
21330 + if (hdmi->is_hdmi_qp) {
21331 + s->dsc_enable = 0;
21332 + if (hdmi->link_cfg.dsc_mode)
21333 + dw_hdmi_qp_dsc_configure(hdmi, s, crtc->state);
21335 - s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
21336 - s->output_type = DRM_MODE_CONNECTOR_HDMIA;
21337 + phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
21340 - return 0;
21341 + clk_set_rate(hdmi->phyref_clk, adj->crtc_clock * 1000);
21345 - .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
21346 - .mode_set = dw_hdmi_rockchip_encoder_mode_set,
21353 -static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
21354 - const struct drm_display_info *display,
21355 - const struct drm_display_mode *mode)
21361 - return phy_power_on(hdmi->phy);
21362 + while (hdmi->phy->power_count > 0)
21363 + phy_power_off(hdmi->phy);
21366 -static void dw_hdmi_rockchip_genphy_disable(struct dw_hdmi *dw_hdmi, void *data)
21374 - phy_power_off(hdmi->phy);
21377 + return phy_power_on(hdmi->phy);
21381 @@ -391,6 +2651,90 @@ static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
21390 + while (hdmi->phy->power_count > 0)
21391 + phy_power_off(hdmi->phy);
21401 + return phy_power_on(hdmi->phy);
21411 + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val);
21413 + if (!hdmi->id) {
21415 + hdmi->hpd_stat = true;
21418 + hdmi->hpd_stat = false;
21423 + hdmi->hpd_stat = true;
21426 + hdmi->hpd_stat = false;
21439 + if (!hdmi->id) {
21449 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
21457 + if (!hdmi->phy)
21462 + hdmi->phy_bus_width |= mode_mask;
21464 + hdmi->phy_bus_width &= ~mode_mask;
21466 + phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
21472 @@ -412,6 +2756,8 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
21481 @@ -423,9 +2769,13 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = {
21495 @@ -450,6 +2800,24 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
21504 + .lcdsel_grf_reg = -1,
21520 @@ -461,10 +2829,52 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = {
21533 + .lcdsel_grf_reg = -1,
21557 + .lcdsel_grf_reg = -1,
21573 @@ -477,9 +2887,19 @@ static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
21574 { .compatible = "rockchip,rk3328-dw-hdmi",
21578 + .compatible = "rockchip,rk3368-dw-hdmi",
21581 { .compatible = "rockchip,rk3399-dw-hdmi",
21584 + { .compatible = "rockchip,rk3568-dw-hdmi",
21587 + { .compatible = "rockchip,rk3588-dw-hdmi",
21593 @@ -488,40 +2908,108 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
21597 - struct dw_hdmi_plat_data *plat_data;
21598 - const struct of_device_id *match;
21606 if (!pdev->dev.of_node)
21607 return -ENODEV;
21609 - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
21612 return -ENOMEM;
21614 - match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
21615 - plat_data = devm_kmemdup(&pdev->dev, match->data,
21616 - sizeof(*plat_data), GFP_KERNEL);
21617 - if (!plat_data)
21618 - return -ENOMEM;
21619 + plat_data = hdmi->plat_data;
21620 + hdmi->drm_dev = drm;
21622 - hdmi->dev = &pdev->dev;
21623 - hdmi->chip_data = plat_data->phy_data;
21624 plat_data->phy_data = hdmi;
21625 - encoder = &hdmi->encoder;
21626 + plat_data->get_input_bus_format =
21628 + plat_data->get_output_bus_format =
21630 + plat_data->get_enc_in_encoding =
21632 + plat_data->get_enc_out_encoding =
21634 + plat_data->get_quant_range =
21636 + plat_data->get_hdr_property =
21638 + plat_data->get_hdr_blob =
21640 + plat_data->get_color_changed =
21642 + plat_data->get_yuv422_format =
21644 + plat_data->get_edid_dsc_info =
21646 + plat_data->get_next_hdr_data =
21648 + plat_data->get_link_cfg = dw_hdmi_rockchip_get_link_cfg;
21649 + plat_data->set_grf_cfg = rk3588_set_grf_cfg;
21650 + plat_data->convert_to_split_mode = drm_mode_convert_to_split_mode;
21651 + plat_data->convert_to_origin_mode = drm_mode_convert_to_origin_mode;
21652 + plat_data->dclk_set = dw_hdmi_dclk_set;
21654 + plat_data->property_ops = &dw_hdmi_rockchip_property_ops;
21657 + if (hdmi->chip_data->split_mode && (hdmi->hdmi_num == 2)) {
21659 + rockchip_hdmi_find_by_id(dev->driver, !hdmi->id);
21662 + return -EPROBE_DEFER;
21666 + * last bind hdmi in split mode, or hdmi->hdmi_qp will not be initialized
21667 + * and plat_data->left/right will be null pointer. we must check if split
21670 + if (device_property_read_bool(dev, "split-mode") ||
21671 + device_property_read_bool(secondary->dev, "split-mode")) {
21672 + plat_data->split_mode = true;
21673 + secondary->plat_data->split_mode = true;
21674 + if (!secondary->plat_data->first_screen)
21675 + plat_data->first_screen = true;
21678 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
21679 - /*
21680 - * If we failed to find the CRTC(s) which this encoder is
21681 - * supposed to be connected to, it's because the CRTC has
21682 - * not been registered yet. Defer probing, and hope that
21683 - * the required CRTC is added later.
21684 - */
21685 - if (encoder->possible_crtcs == 0)
21686 - return -EPROBE_DEFER;
21687 + if (device_property_read_bool(dev, "user-split-mode") ||
21688 + device_property_read_bool(secondary->dev, "user-split-mode")) {
21689 + hdmi->user_split_mode = true;
21690 + secondary->user_split_mode = true;
21694 + if (!plat_data->first_screen) {
21695 + encoder = &hdmi->encoder;
21696 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm, dev->of_node);
21703 + if (encoder->possible_crtcs == 0)
21704 + return -EPROBE_DEFER;
21710 + if (!plat_data->max_tmdsclk)
21711 + hdmi->max_tmdsclk = 594000;
21713 + hdmi->max_tmdsclk = plat_data->max_tmdsclk;
21715 + hdmi->is_hdmi_qp = plat_data->is_hdmi_qp;
21717 + hdmi->unsupported_yuv_input = plat_data->unsupported_yuv_input;
21718 + hdmi->unsupported_deep_color = plat_data->unsupported_deep_color;
21722 @@ -529,27 +3017,167 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
21726 - ret = clk_prepare_enable(hdmi->vpll_clk);
21727 + ret = clk_prepare_enable(hdmi->aud_clk);
21729 + dev_err(hdmi->dev, "Failed to enable HDMI aud_clk: %d\n", ret);
21733 + ret = clk_prepare_enable(hdmi->hpd_clk);
21735 + dev_err(hdmi->dev, "Failed to enable HDMI hpd_clk: %d\n", ret);
21739 + ret = clk_prepare_enable(hdmi->hclk_vo1);
21741 + dev_err(hdmi->dev, "Failed to enable HDMI hclk_vo1: %d\n", ret);
21745 + ret = clk_prepare_enable(hdmi->earc_clk);
21747 + dev_err(hdmi->dev, "Failed to enable HDMI earc_clk: %d\n", ret);
21751 + ret = clk_prepare_enable(hdmi->hdmitx_ref);
21753 + dev_err(hdmi->dev, "Failed to enable HDMI hdmitx_ref: %d\n",
21758 + ret = clk_prepare_enable(hdmi->pclk);
21760 + dev_err(hdmi->dev, "Failed to enable HDMI pclk: %d\n", ret);
21764 + if (hdmi->chip_data->ddc_en_reg == RK3568_GRF_VO_CON1) {
21765 + regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
21772 + if (hdmi->is_hdmi_qp) {
21773 + if (!hdmi->id) {
21778 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
21782 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
21786 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
21792 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
21796 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
21800 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
21805 + ret = clk_prepare_enable(hdmi->phyref_clk);
21807 DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
21812 + ret = clk_prepare_enable(hdmi->hclk_vio);
21814 + dev_err(hdmi->dev, "Failed to enable HDMI hclk_vio: %d\n",
21819 + ret = clk_prepare_enable(hdmi->hclk_vop);
21821 + dev_err(hdmi->dev, "Failed to enable HDMI hclk_vop: %d\n",
21826 + if (!hdmi->id)
21830 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
21832 + if (hdmi->is_hdmi_qp) {
21833 + hdmi->hpd_irq = platform_get_irq(pdev, 4);
21834 + if (hdmi->hpd_irq < 0)
21835 + return hdmi->hpd_irq;
21837 + ret = devm_request_threaded_irq(hdmi->dev, hdmi->hpd_irq,
21840 + IRQF_SHARED, "dw-hdmi-qp-hpd",
21846 hdmi->phy = devm_phy_optional_get(dev, "hdmi");
21847 if (IS_ERR(hdmi->phy)) {
21848 - ret = PTR_ERR(hdmi->phy);
21849 - if (ret != -EPROBE_DEFER)
21850 - DRM_DEV_ERROR(hdmi->dev, "failed to get phy\n");
21851 - return ret;
21852 + hdmi->phy = devm_phy_optional_get(dev, "hdmi_phy");
21853 + if (IS_ERR(hdmi->phy)) {
21854 + ret = PTR_ERR(hdmi->phy);
21855 + if (ret != -EPROBE_DEFER)
21856 + DRM_DEV_ERROR(hdmi->dev, "failed to get phy\n");
21861 - drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
21862 - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
21863 + if (hdmi->is_hdmi_qp) {
21864 + hdmi->hdmi_qp = dw_hdmi_qp_bind(pdev, &hdmi->encoder, plat_data);
21866 - platform_set_drvdata(pdev, hdmi);
21867 + if (IS_ERR(hdmi->hdmi_qp)) {
21868 + ret = PTR_ERR(hdmi->hdmi_qp);
21869 + drm_encoder_cleanup(&hdmi->encoder);
21872 + if (plat_data->connector) {
21873 + hdmi->sub_dev.connector = plat_data->connector;
21874 + hdmi->sub_dev.of_node = dev->of_node;
21875 + rockchip_drm_register_sub_dev(&hdmi->sub_dev);
21878 + if (plat_data->split_mode) {
21880 + rockchip_hdmi_find_by_id(dev->driver, !hdmi->id);
21882 + if (device_property_read_bool(dev, "split-mode")) {
21883 + plat_data->right = secondary->hdmi_qp;
21884 + secondary->plat_data->left = hdmi->hdmi_qp;
21886 + plat_data->left = secondary->hdmi_qp;
21887 + secondary->plat_data->right = hdmi->hdmi_qp;
21894 - hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
21895 + hdmi->hdmi = dw_hdmi_bind(pdev, &hdmi->encoder, plat_data);
21899 @@ -557,8 +3185,21 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
21901 if (IS_ERR(hdmi->hdmi)) {
21902 ret = PTR_ERR(hdmi->hdmi);
21903 - drm_encoder_cleanup(encoder);
21904 - clk_disable_unprepare(hdmi->vpll_clk);
21905 + drm_encoder_cleanup(&hdmi->encoder);
21906 + clk_disable_unprepare(hdmi->aud_clk);
21907 + clk_disable_unprepare(hdmi->phyref_clk);
21908 + clk_disable_unprepare(hdmi->hclk_vop);
21909 + clk_disable_unprepare(hdmi->hpd_clk);
21910 + clk_disable_unprepare(hdmi->hclk_vo1);
21911 + clk_disable_unprepare(hdmi->earc_clk);
21912 + clk_disable_unprepare(hdmi->hdmitx_ref);
21913 + clk_disable_unprepare(hdmi->pclk);
21916 + if (plat_data->connector) {
21917 + hdmi->sub_dev.connector = plat_data->connector;
21918 + hdmi->sub_dev.of_node = dev->of_node;
21919 + rockchip_drm_register_sub_dev(&hdmi->sub_dev);
21923 @@ -569,8 +3210,27 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
21927 - dw_hdmi_unbind(hdmi->hdmi);
21928 - clk_disable_unprepare(hdmi->vpll_clk);
21929 + if (hdmi->is_hdmi_qp) {
21930 + cancel_delayed_work(&hdmi->work);
21931 + flush_workqueue(hdmi->workqueue);
21932 + destroy_workqueue(hdmi->workqueue);
21935 + if (hdmi->sub_dev.connector)
21936 + rockchip_drm_unregister_sub_dev(&hdmi->sub_dev);
21938 + if (hdmi->is_hdmi_qp)
21939 + dw_hdmi_qp_unbind(hdmi->hdmi_qp);
21941 + dw_hdmi_unbind(hdmi->hdmi);
21942 + clk_disable_unprepare(hdmi->aud_clk);
21943 + clk_disable_unprepare(hdmi->phyref_clk);
21944 + clk_disable_unprepare(hdmi->hclk_vop);
21945 + clk_disable_unprepare(hdmi->hpd_clk);
21946 + clk_disable_unprepare(hdmi->hclk_vo1);
21947 + clk_disable_unprepare(hdmi->earc_clk);
21948 + clk_disable_unprepare(hdmi->hdmitx_ref);
21949 + clk_disable_unprepare(hdmi->pclk);
21953 @@ -580,32 +3240,132 @@ static const struct component_ops dw_hdmi_rockchip_ops = {
21962 + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
21964 + return -ENOMEM;
21966 + id = of_alias_get_id(pdev->dev.of_node, "hdmi");
21970 + hdmi->hdmi_num++;
21971 + hdmi->id = id;
21972 + hdmi->dev = &pdev->dev;
21974 + match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
21975 + plat_data = devm_kmemdup(&pdev->dev, match->data,
21978 + return -ENOMEM;
21980 + hdmi->plat_data = plat_data;
21981 + hdmi->chip_data = plat_data->phy_data;
21984 + pm_runtime_enable(&pdev->dev);
21985 + pm_runtime_get_sync(&pdev->dev);
21987 return component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
21992 + struct rockchip_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
21997 + if (hdmi->is_hdmi_qp) {
21998 + cancel_delayed_work(&hdmi->work);
21999 + flush_workqueue(hdmi->workqueue);
22000 + dw_hdmi_qp_suspend(hdmi->dev, hdmi->hdmi_qp);
22002 + dw_hdmi_suspend(hdmi->hdmi);
22004 + pm_runtime_put_sync(&pdev->dev);
22009 component_del(&pdev->dev, &dw_hdmi_rockchip_ops);
22010 + pm_runtime_disable(&pdev->dev);
22019 + if (hdmi->is_hdmi_qp)
22020 + dw_hdmi_qp_suspend(dev, hdmi->hdmi_qp);
22022 + dw_hdmi_suspend(hdmi->hdmi);
22028 -static int __maybe_unused dw_hdmi_rockchip_resume(struct device *dev)
22034 + if (hdmi->is_hdmi_qp) {
22035 + if (!hdmi->id) {
22040 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
22044 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
22048 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
22054 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
22058 + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
22062 + regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
22065 - dw_hdmi_resume(hdmi->hdmi);
22066 + dw_hdmi_qp_resume(dev, hdmi->hdmi_qp);
22067 + drm_helper_hpd_irq_event(hdmi->drm_dev);
22069 + dw_hdmi_resume(hdmi->hdmi);
22077 - SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_rockchip_resume)
22087 .name = "dwhdmi-rockchip",
22089 diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
22091 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c
22093 @@ -602,7 +602,7 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
22094 struct drm_encoder *encoder = &hdmi->encoder;
22095 struct device *dev = hdmi->dev;
22097 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
22098 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm, dev->of_node);
22102 diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
22104 --- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
22106 @@ -542,7 +542,7 @@ rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi)
22107 struct device *dev = hdmi->dev;
22109 encoder->possible_crtcs =
22110 - drm_of_find_possible_crtcs(drm, dev->of_node);
22111 + rockchip_drm_of_find_possible_crtcs(drm, dev->of_node);
22115 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_dr…
22117 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
22119 @@ -6,17 +6,24 @@
22123 +#include <linux/dma-buf-cache.h>
22124 #include <linux/dma-mapping.h>
22125 #include <linux/dma-iommu.h>
22144 @@ -27,16 +34,856 @@
22155 -#define DRIVER_MAJOR 1
22183 + return -ENODEV;
22186 + return -EINVAL;
22188 + priv = crtc->dev->dev_private;
22191 + if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->wait_vact_end)
22192 + ret = priv->crtc_funcs[pipe]->wait_vact_end(crtc, mstimeout);
22202 + hactive = mode->hdisplay;
22203 + hfp = mode->hsync_start - mode->hdisplay;
22204 + hsync = mode->hsync_end - mode->hsync_start;
22205 + hbp = mode->htotal - mode->hsync_end;
22207 + mode->clock *= 2;
22208 + mode->hdisplay = hactive * 2;
22209 + mode->hsync_start = mode->hdisplay + hfp * 2;
22210 + mode->hsync_end = mode->hsync_start + hsync * 2;
22211 + mode->htotal = mode->hsync_end + hbp * 2;
22220 + hactive = mode->hdisplay;
22221 + hfp = mode->hsync_start - mode->hdisplay;
22222 + hsync = mode->hsync_end - mode->hsync_start;
22223 + hbp = mode->htotal - mode->hsync_end;
22225 + mode->clock /= 2;
22226 + mode->hdisplay = hactive / 2;
22227 + mode->hsync_start = mode->hdisplay + hfp / 2;
22228 + mode->hsync_end = mode->hsync_start + hsync / 2;
22229 + mode->htotal = mode->hsync_end + hbp / 2;
22234 + * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
22238 + * driver / device. An example of this is some USB Type-C setups where the hardware
22239 + * muxes the DisplayPort data and aux-lines but does not pass the altmode HPD
22242 + * This function can be used to report these out-of-band events after obtaining
22249 + if (!connector_fwnode || !connector_fwnode->dev)
22252 + sub_dev = rockchip_drm_get_sub_dev(dev_of_node(connector_fwnode->dev));
22254 + if (sub_dev && sub_dev->connector && sub_dev->oob_hotplug_event)
22255 + sub_dev->oob_hotplug_event(sub_dev->connector);
22262 + if (info->cpp[0])
22263 + return info->cpp[0] * 8;
22265 + switch (info->format) {
22282 + * rockchip_drm_of_find_possible_crtcs - find the possible CRTCs for an active
22324 + list_add_tail(&sub_dev->list, &rockchip_drm_sub_dev_list);
22332 + list_del(&sub_dev->list);
22344 + if (sub_dev->of_node == node) {
22362 + if (sub_dev->connector->encoder) {
22363 + connector_type = sub_dev->connector->connector_type;
22375 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
22378 + if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->te_handler)
22379 + priv->crtc_funcs[pipe]->te_handler(crtc);
22384 + /* 4 - 1280x720@60Hz 16:9 */
22389 + /* 16 - 1920x1080@60Hz 16:9 */
22394 + /* 31 - 1920x1080@50Hz 16:9 */
22399 + /* 19 - 1280x720@50Hz 16:9 */
22404 + /* 0x10 - 1024x768@60Hz */
22408 + /* 17 - 720x576@50Hz 4:3 */
22413 + /* 2 - 720x480@60Hz 4:3 */
22422 + struct drm_device *dev = connector->dev;
22435 + mode->type = DRM_MODE_TYPE_PREFERRED;
22498 + /* DisplayID CTA extension blocks and top-level CEA EDID
22509 + * Byte number (decimal) within this block where the 18-byte
22510 + * DTDs begin. If no non-DTD data is present in this extension
22513 + * no non-DTD data.
22529 + return -ERANGE;
22531 + return -EOPNOTSUPP;
22544 + if (edid == NULL || edid->extensions == 0)
22548 + for (i = *ext_index; i < edid->extensions; i++) {
22554 + if (i >= edid->extensions)
22571 + base->rev, base->bytes, base->prod_id, base->ext_count);
22574 + dispid_length = sizeof(*base) + base->bytes + 1;
22575 + if (dispid_length > length - idx)
22576 + return -EINVAL;
22582 + return -EINVAL;
22600 + *length = EDID_LENGTH - 1;
22608 + *length = *idx + sizeof(*base) + base->bytes;
22638 + if (block->tag == 0x81)
22655 + return -EINVAL;
22657 + info = &connector->display_info;
22661 + return -EINVAL;
22664 + info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
22736 + dsc_cap->v_1p2 = hf_vsdb[11] & EDID_DSC_1P2;
22738 + if (!dsc_cap->v_1p2)
22741 + dsc_cap->native_420 = hf_vsdb[11] & EDID_DSC_NATIVE_420;
22742 + dsc_cap->all_bpp = hf_vsdb[11] & EDID_DSC_ALL_BPP;
22745 + dsc_cap->bpc_supported = 16;
22747 + dsc_cap->bpc_supported = 12;
22749 + dsc_cap->bpc_supported = 10;
22751 + dsc_cap->bpc_supported = 0;
22754 + get_max_frl_rate(dsc_max_frl_rate, &dsc_cap->max_lanes,
22755 + &dsc_cap->max_frl_rate_per_lane);
22756 + dsc_cap->total_chunk_kbytes = hf_vsdb[13] & EDID_DSC_TOTAL_CHUNK_KBYTES;
22761 + dsc_cap->max_slices = 1;
22762 + dsc_cap->clk_per_slice = 340;
22765 + dsc_cap->max_slices = 2;
22766 + dsc_cap->clk_per_slice = 340;
22769 + dsc_cap->max_slices = 4;
22770 + dsc_cap->clk_per_slice = 340;
22773 + dsc_cap->max_slices = 8;
22774 + dsc_cap->clk_per_slice = 340;
22777 + dsc_cap->max_slices = 8;
22778 + dsc_cap->clk_per_slice = 400;
22781 + dsc_cap->max_slices = 12;
22782 + dsc_cap->clk_per_slice = 400;
22785 + dsc_cap->max_slices = 16;
22786 + dsc_cap->clk_per_slice = 400;
22790 + dsc_cap->max_slices = 0;
22791 + dsc_cap->clk_per_slice = 0;
22818 + return -ENOENT;
22824 + hdr->yuv422_12bit = data[5] & BIT(0);
22825 + hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
22826 + hdr->global_dimming = (data[5] & BIT(2)) >> 2;
22828 + hdr->dm_major_ver = (data[21] & 0xf0) >> 4;
22829 + hdr->dm_minor_ver = data[21] & 0xf;
22831 + hdr->t_min_pq = (data[19] << 4) | ((data[18] & 0xf0) >> 4);
22832 + hdr->t_max_pq = (data[20] << 4) | (data[18] & 0xf);
22834 + hdr->rx = (data[7] << 4) | ((data[6] & 0xf0) >> 4);
22835 + hdr->ry = (data[8] << 4) | (data[6] & 0xf);
22836 + hdr->gx = (data[10] << 4) | ((data[9] & 0xf0) >> 4);
22837 + hdr->gy = (data[11] << 4) | (data[9] & 0xf);
22838 + hdr->bx = (data[13] << 4) | ((data[12] & 0xf0) >> 4);
22839 + hdr->by = (data[14] << 4) | (data[12] & 0xf);
22840 + hdr->wx = (data[16] << 4) | ((data[15] & 0xf0) >> 4);
22841 + hdr->wy = (data[17] << 4) | (data[15] & 0xf);
22846 + hdr->yuv422_12bit = data[5] & BIT(0);
22847 + hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
22848 + hdr->global_dimming = data[6] & BIT(0);
22850 + hdr->dm_version = (data[5] & 0x1c) >> 2;
22852 + hdr->colorimetry = data[7] & BIT(0);
22854 + hdr->t_max_lum = (data[6] & 0xfe) >> 1;
22855 + hdr->t_min_lum = (data[7] & 0xfe) >> 1;
22857 + hdr->rx = data[9];
22858 + hdr->ry = data[10];
22859 + hdr->gx = data[11];
22860 + hdr->gy = data[12];
22861 + hdr->bx = data[13];
22862 + hdr->by = data[14];
22867 + hdr->yuv422_12bit = data[5] & BIT(0);
22868 + hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
22869 + hdr->global_dimming = data[6] & BIT(0);
22871 + hdr->dm_version = (data[5] & 0x1c) >> 2;
22873 + hdr->colorimetry = data[7] & BIT(0);
22875 + hdr->t_max_lum = (data[6] & 0xfe) >> 1;
22876 + hdr->t_min_lum = (data[7] & 0xfe) >> 1;
22878 + hdr->low_latency = data[8] & 0x3;
22880 + hdr->unique_rx = (data[11] & 0xf8) >> 3;
22881 + hdr->unique_ry = (data[11] & 0x7) << 2 | (data[10] & BIT(0)) << 1 |
22883 + hdr->unique_gx = (data[9] & 0xfe) >> 1;
22884 + hdr->unique_gy = (data[10] & 0xfe) >> 1;
22885 + hdr->unique_bx = (data[8] & 0xe0) >> 5;
22886 + hdr->unique_by = (data[8] & 0x1c) >> 2;
22891 + hdr->yuv422_12bit = data[5] & BIT(0);
22892 + hdr->backlt_ctrl = (data[5] & BIT(1)) >> 1;
22893 + hdr->global_dimming = (data[6] & BIT(2)) >> 2;
22895 + hdr->dm_version = (data[5] & 0x1c) >> 2;
22896 + hdr->backlt_min_luma = data[6] & 0x3;
22897 + hdr->interface = data[7] & 0x3;
22898 + hdr->yuv444_10b_12b = (data[8] & BIT(0)) << 1 | (data[9] & BIT(0));
22900 + hdr->t_min_pq_v2 = (data[6] & 0xf8) >> 3;
22901 + hdr->t_max_pq_v2 = (data[7] & 0xf8) >> 3;
22903 + hdr->unique_rx = (data[10] & 0xf8) >> 3;
22904 + hdr->unique_ry = (data[11] & 0xf8) >> 3;
22905 + hdr->unique_gx = (data[8] & 0xfe) >> 1;
22906 + hdr->unique_gy = (data[9] & 0xfe) >> 1;
22907 + hdr->unique_bx = data[10] & 0x7;
22908 + hdr->unique_by = data[11] & 0x7;
22921 + sink_data->version = version;
22925 + parse_ver_26_v0_data(&sink_data->ver_26_v0, next_hdr_db);
22928 + parse_ver_15_v1_data(&sink_data->ver_15_v1, next_hdr_db);
22931 + parse_ver_12_v1_data(&sink_data->ver_12_v1, next_hdr_db);
22934 + parse_ver_12_v2_data(&sink_data->ver_12_v2, next_hdr_db);
22949 + return -EINVAL;
22953 + return -EINVAL;
22956 + return -EINVAL;
22977 + return -EINVAL;
22983 + return -EINVAL;
22986 + return -EINVAL;
23002 @@ -72,6 +919,66 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
23008 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23012 + priv->crtc_funcs[pipe] &&
23013 + priv->crtc_funcs[pipe]->crtc_standby)
23014 + priv->crtc_funcs[pipe]->crtc_standby(crtc, standby);
23021 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23024 + return -EINVAL;
23026 + priv->crtc_funcs[pipe] = crtc_funcs;
23034 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23039 + priv->crtc_funcs[pipe] = NULL;
23047 + struct rockchip_drm_private *priv = drm_dev->dev_private;
23054 + if (priv->crtc_funcs[pipe] &&
23055 + priv->crtc_funcs[pipe]->regs_dump)
23056 + priv->crtc_funcs[pipe]->regs_dump(crtc, NULL);
23058 + if (priv->crtc_funcs[pipe] &&
23059 + priv->crtc_funcs[pipe]->debugfs_dump)
23060 + priv->crtc_funcs[pipe]->debugfs_dump(crtc, NULL);
23068 struct rockchip_drm_private *private = drm_dev->dev_private;
23069 @@ -94,6 +1001,9 @@ static int rockchip_drm_init_iommu(struct drm_device *drm_dev)
23070 drm_mm_init(&private->mm, start, end - start + 1);
23071 mutex_init(&private->mm_lock);
23073 + iommu_set_fault_handler(private->domain, rockchip_drm_fault_handler,
23079 @@ -108,6 +1018,229 @@ static void rockchip_iommu_cleanup(struct drm_device *drm_dev)
23080 iommu_domain_free(private->domain);
23086 + struct drm_info_node *node = s->private;
23087 + struct drm_minor *minor = node->minor;
23088 + struct drm_device *drm_dev = minor->dev;
23089 + struct rockchip_drm_private *priv = drm_dev->dev_private;
23092 + if (!priv->domain)
23094 + mutex_lock(&priv->mm_lock);
23095 + drm_mm_print(&priv->mm, &p);
23096 + mutex_unlock(&priv->mm_lock);
23103 + struct drm_info_node *node = s->private;
23104 + struct drm_minor *minor = node->minor;
23105 + struct drm_device *drm_dev = minor->dev;
23106 + struct rockchip_drm_private *priv = drm_dev->dev_private;
23112 + if (priv->crtc_funcs[pipe] &&
23113 + priv->crtc_funcs[pipe]->debugfs_dump)
23114 + priv->crtc_funcs[pipe]->debugfs_dump(crtc, s);
23127 + struct drm_device *dev = minor->dev;
23128 + struct rockchip_drm_private *priv = dev->dev_private;
23133 + minor->debugfs_root, minor);
23138 + if (priv->crtc_funcs[pipe] &&
23139 + priv->crtc_funcs[pipe]->debugfs_init)
23140 + priv->crtc_funcs[pipe]->debugfs_init(minor, crtc);
23148 + struct rockchip_drm_private *private = dev->dev_private;
23153 + return -ENOMEM;
23154 + private->eotf_prop = prop;
23159 + return -ENOMEM;
23160 + private->color_space_prop = prop;
23165 + return -ENOMEM;
23166 + private->async_commit_prop = prop;
23171 + return -ENOMEM;
23172 + private->share_id_prop = prop;
23177 + return -ENOMEM;
23178 + private->connector_id_prop = prop;
23183 + private->soc_id_prop = prop;
23188 + private->port_id_prop = prop;
23190 + private->aclk_prop = drm_property_create_range(dev, 0, "ACLK", 0, UINT_MAX);
23191 + private->bg_prop = drm_property_create_range(dev, 0, "BACKGROUND", 0, UINT_MAX);
23192 + private->line_flag_prop = drm_property_create_range(dev, 0, "LINE_FLAG1", 0, UINT_MAX);
23200 + struct drm_mode_config *conf = &drm->mode_config;
23203 + mutex_lock(&drm->mode_config.mutex);
23206 + drm_object_attach_property(&connector->base, prop, v)
23210 + ROCKCHIP_PROP_ATTACH(conf->tv_brightness_property, 50);
23211 + ROCKCHIP_PROP_ATTACH(conf->tv_contrast_property, 50);
23212 + ROCKCHIP_PROP_ATTACH(conf->tv_saturation_property, 50);
23213 + ROCKCHIP_PROP_ATTACH(conf->tv_hue_property, 50);
23218 + mutex_unlock(&drm->mode_config.mutex);
23224 + struct drm_mode_config *conf = &drm->mode_config;
23231 + state = drm_atomic_helper_duplicate_state(drm, conf->acquire_ctx);
23236 + state->acquire_ctx = conf->acquire_ctx;
23245 + DRM_ERROR("Connector[%d]: Failed to get state\n", connector->base.id);
23249 + connector_state->tv.brightness = 50;
23250 + connector_state->tv.contrast = 50;
23251 + connector_state->tv.saturation = 50;
23252 + connector_state->tv.hue = 50;
23257 + WARN_ON(ret == -EDEADLK);
23268 + struct rockchip_drm_private *private = drm->dev_private;
23269 + struct device_node *np = drm->dev->of_node;
23275 + node = of_parse_phandle(np, "secure-memory-region", 0);
23277 + return -ENXIO;
23285 + return -ENOMEM;
23287 + private->secure_buffer_pool = gen_pool_create(PAGE_SHIFT, -1);
23288 + if (!private->secure_buffer_pool)
23289 + return -ENOMEM;
23291 + gen_pool_add(private->secure_buffer_pool, start, size, -1);
23298 + struct rockchip_drm_private *private = drm->dev_private;
23300 + if (!private->secure_buffer_pool)
23303 + gen_pool_destroy(private->secure_buffer_pool);
23309 @@ -126,10 +1259,32 @@ static int rockchip_drm_bind(struct device *dev)
23313 + mutex_init(&private->ovl_lock);
23315 drm_dev->dev_private = private;
23317 INIT_LIST_HEAD(&private->psr_list);
23318 mutex_init(&private->psr_list_lock);
23319 + mutex_init(&private->commit_lock);
23321 + private->hdmi_pll.pll = devm_clk_get_optional(dev, "hdmi-tmds-pll");
23322 + if (PTR_ERR(private->hdmi_pll.pll) == -EPROBE_DEFER) {
23323 + ret = -EPROBE_DEFER;
23325 + } else if (IS_ERR(private->hdmi_pll.pll)) {
23326 + dev_err(dev, "failed to get hdmi-tmds-pll\n");
23327 + ret = PTR_ERR(private->hdmi_pll.pll);
23330 + private->default_pll.pll = devm_clk_get_optional(dev, "default-vop-pll");
23331 + if (PTR_ERR(private->default_pll.pll) == -EPROBE_DEFER) {
23332 + ret = -EPROBE_DEFER;
23334 + } else if (IS_ERR(private->default_pll.pll)) {
23336 + ret = PTR_ERR(private->default_pll.pll);
23342 @@ -140,17 +1295,19 @@ static int rockchip_drm_bind(struct device *dev)
23346 -
23351 - goto err_iommu_cleanup;
23355 ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
23364 @@ -158,12 +1315,21 @@ static int rockchip_drm_bind(struct device *dev)
23366 drm_dev->irq_enabled = true;
23372 + ret = of_reserved_mem_device_init(drm_dev->dev);
23382 - /* init kms poll for handling hpd */
23383 - drm_kms_helper_poll_init(drm_dev);
23384 + drm_dev->mode_config.allow_fb_modifiers = true;
23388 @@ -171,13 +1337,18 @@ static int rockchip_drm_bind(struct device *dev)
23402 + drm_dev->dev_private = NULL;
23407 @@ -189,15 +1360,121 @@ static void rockchip_drm_unbind(struct device *dev)
23419 + drm_dev->dev_private = NULL;
23427 + struct rockchip_drm_private *priv = crtc->dev->dev_private;
23431 + priv->crtc_funcs[pipe] &&
23432 + priv->crtc_funcs[pipe]->cancel_pending_vblank)
23433 + priv->crtc_funcs[pipe]->cancel_pending_vblank(crtc, file_priv);
23441 + crtc->primary->fb = NULL;
23451 + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
23457 + struct rockchip_drm_private *priv = dev->dev_private;
23459 + if (!priv->logo)
23460 + drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev_helper);
23468 + struct drm_device *dev = crtc->dev;
23475 + e->pipe = drm_crtc_index(crtc);
23476 + e->event.base.type = DRM_EVENT_ROCKCHIP_CRTC_VCNT;
23477 + e->event.base.length = sizeof(e->event.vbl);
23478 + e->event.vbl.crtc_id = crtc->base.id;
23479 + e->event.vbl.user_data = vblwait->request.signal;
23481 + spin_lock_irqsave(&dev->event_lock, flags);
23482 + drm_event_reserve_init_locked(dev, file_priv, &e->base, &e->event.base);
23483 + spin_unlock_irqrestore(&dev->event_lock, flags);
23491 + struct rockchip_drm_private *priv = dev->dev_private;
23497 + flags = vblwait->request.type & (_DRM_VBLANK_FLAGS_MASK | _DRM_ROCKCHIP_VCNT_EVENT);
23498 + pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
23508 + priv->vcnt[pipe].event = e;
23529 @@ -209,19 +1486,160 @@ static const struct file_operations rockchip_drm_driver_fops = {
23536 + struct drm_gem_object *obj = dma_buf->priv;
23544 + struct drm_gem_object *obj = dma_buf->priv;
23554 + struct drm_gem_object *obj = dma_buf->priv;
23564 + struct drm_gem_object *obj = dma_buf->priv;
23595 + if (dma_buf->ops == &rockchip_drm_gem_prime_dmabuf_ops) {
23596 + obj = dma_buf->priv;
23597 + if (obj->dev == dev) {
23607 + if (!dev->driver->gem_prime_import_sg_table)
23608 + return ERR_PTR(-EINVAL);
23622 + obj = dev->driver->gem_prime_import_sg_table(dev, attach, sgt);
23628 + obj->import_attach = attach;
23629 + obj->resv = dma_buf->resv;
23645 + return rockchip_drm_gem_prime_import_dev(dev, dma_buf, dev->dev);
23651 + struct drm_device *dev = obj->dev;
23654 + .owner = dev->driver->fops->owner,
23656 + .size = obj->size,
23659 + .resv = obj->resv,
23666 - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
23667 - .lastclose = drm_fb_helper_lastclose,
23692 @@ -371,7 +1789,7 @@ static int rockchip_drm_platform_of_probe(struct device *dev)
23695 iommu = of_parse_phandle(port->parent, "iommus", 0);
23696 - if (!iommu || !of_device_is_available(iommu->parent)) {
23699 "no iommu attached for %pOF, using non-iommu buffers\n",
23700 port->parent);
23701 @@ -409,8 +1827,10 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
23712 @@ -422,6 +1842,10 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
23723 @@ -470,7 +1894,12 @@ static int __init rockchip_drm_init(void)
23727 - ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP);
23737 @@ -480,10 +1909,15 @@ static int __init rockchip_drm_init(void)
23753 @@ -493,6 +1927,8 @@ static int __init rockchip_drm_init(void)
23762 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_dr…
23764 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
23766 @@ -9,32 +9,375 @@
23770 -#include <drm/drm_fb_helper.h>
23776 -
23783 +#include "panel/panel-simple.h"
23789 -#define ROCKCHIP_MAX_CRTC 2
23817 +#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */
24145 @@ -43,13 +386,55 @@ struct rockchip_crtc_state {
24146 * @mm_lock: protect drm_mm on multi-threads.
24149 - struct drm_fb_helper fbdev_helper;
24202 @@ -57,14 +442,51 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
24254 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
24256 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
24258 @@ -5,6 +5,7 @@
24266 @@ -13,18 +14,47 @@
24279 + return fb->flags & ROCKCHIP_DRM_MODE_LOGO_FB ? true : false;
24292 + rockchip_free_loader_memory(fb->dev);
24297 + if (fb->obj[i])
24298 + drm_gem_object_put(fb->obj[i]);
24306 - .destroy = drm_gem_fb_destroy,
24309 - .dirty = drm_atomic_helper_dirtyfb,
24312 -static struct drm_framebuffer *
24317 @@ -53,8 +83,103 @@ rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cm
24331 + return ERR_PTR(-ENOMEM);
24332 + fb = &rockchip_logo_fb->fb;
24338 + DRM_DEV_ERROR(dev->dev,
24345 + fb->flags |= ROCKCHIP_DRM_MODE_LOGO_FB;
24346 + rockchip_logo_fb->logo = logo;
24347 + rockchip_logo_fb->fb.obj[0] = &rockchip_logo_fb->rk_obj.base;
24348 + rockchip_logo_fb->rk_obj.dma_addr = logo->dma_addr;
24349 + rockchip_logo_fb->rk_obj.kvaddr = logo->kvaddr;
24350 + logo->count++;
24352 + return &rockchip_logo_fb->fb;
24359 + struct rockchip_drm_private *priv = dev->dev_private;
24365 + vop_bw_info->line_bw_mbyte = 0;
24366 + vop_bw_info->frame_bw_mbyte = 0;
24367 + vop_bw_info->plane_num = 0;
24370 + funcs = priv->crtc_funcs[drm_crtc_index(crtc)];
24372 + if (funcs && funcs->bandwidth)
24373 + funcs->bandwidth(crtc, old_crtc_state, vop_bw_info);
24380 + * rockchip_drm_atomic_helper_commit_tail_rpm - commit atomic update to hardware
24391 + struct drm_device *dev = old_state->dev;
24392 + struct rockchip_drm_private *prv = dev->dev_private;
24403 + mutex_lock(&prv->ovl_lock);
24405 + mutex_unlock(&prv->ovl_lock);
24417 - .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
24422 @@ -81,7 +206,7 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
24425 if (drm_is_afbc(mode_cmd->modifier[0])) {
24426 - int ret, i;
24431 @@ -98,9 +223,18 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
24432 return &afbc_fb->base;
24437 + struct rockchip_drm_private *private = dev->dev_private;
24438 + struct drm_fb_helper *fb_helper = private->fbdev_helper;
24440 + if (fb_helper && dev->mode_config.poll_enabled && !private->loader_protect)
24446 - .output_poll_changed = drm_fb_helper_output_poll_changed,
24451 @@ -125,12 +259,13 @@ void rockchip_drm_mode_config_init(struct drm_device *dev)
24452 dev->mode_config.min_height = 0;
24455 - * set max width and height as default value(4096x4096).
24460 - dev->mode_config.max_width = 4096;
24461 - dev->mode_config.max_height = 4096;
24462 + dev->mode_config.max_width = 16384;
24463 + dev->mode_config.max_height = 16384;
24464 + dev->mode_config.async_page_flip = true;
24466 dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;
24467 dev->mode_config.helper_private = &rockchip_mode_config_helpers;
24468 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h
24470 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h
24472 @@ -7,6 +7,10 @@
24483 @@ -14,4 +18,19 @@ rockchip_drm_framebuffer_init(struct drm_device *dev,
24503 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_…
24505 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
24507 @@ -15,14 +15,12 @@
24511 -#define to_drm_private(x) \
24512 - container_of(x, struct rockchip_drm_private, fbdev_helper)
24517 struct drm_fb_helper *helper = info->par;
24518 - struct rockchip_drm_private *private = to_drm_private(helper);
24519 + struct rockchip_drm_private *private = helper->dev->dev_private;
24521 return rockchip_gem_mmap_buf(private->fbdev_bo, vma);
24523 @@ -39,7 +37,7 @@ static const struct fb_ops rockchip_drm_fbdev_ops = {
24527 - struct rockchip_drm_private *private = to_drm_private(helper);
24528 + struct rockchip_drm_private *private = helper->dev->dev_private;
24530 struct drm_device *dev = helper->dev;
24532 @@ -60,7 +58,7 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
24536 - rk_obj = rockchip_gem_create_object(dev, size, true);
24539 return -ENOMEM;
24541 @@ -120,7 +118,10 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
24542 if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
24543 return -EINVAL;
24545 - helper = &private->fbdev_helper;
24546 + helper = devm_kzalloc(dev->dev, sizeof(*helper), GFP_KERNEL);
24548 + return -ENOMEM;
24549 + private->fbdev_helper = helper;
24553 @@ -150,9 +151,10 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
24556 struct rockchip_drm_private *private = dev->dev_private;
24557 - struct drm_fb_helper *helper;
24558 + struct drm_fb_helper *helper = private->fbdev_helper;
24560 - helper = &private->fbdev_helper;
24566 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_ge…
24568 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
24570 @@ -4,7 +4,7 @@
24571 * Author:Mark Yao <mark.yao@rock-chips.com>
24574 -#include <linux/dma-buf.h>
24575 +#include <linux/dma-buf-cache.h>
24579 @@ -13,9 +13,25 @@
24604 struct drm_device *drm = rk_obj->base.dev;
24605 @@ -45,6 +61,8 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
24609 + iommu_flush_iotlb_all(private->domain);
24611 rk_obj->size = ret;
24614 @@ -73,25 +91,137 @@ static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
24625 + list_del(&info->list);
24637 + bank_bit_first = ddr_map_info->bank_bit_first;
24638 + bank_bit_mask = ddr_map_info->bank_bit_mask;
24644 struct drm_device *drm = rk_obj->base.dev;
24647 -
24648 - rk_obj->pages = drm_gem_get_pages(&rk_obj->base);
24649 - if (IS_ERR(rk_obj->pages))
24650 - return PTR_ERR(rk_obj->pages);
24668 + pages = drm_gem_get_pages(&rk_obj->base);
24672 + rk_obj->pages = pages;
24674 rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
24676 + n_pages = rk_obj->num_pages;
24681 + ret = -ENOMEM;
24694 + page_to_pfn(pages[j - 1]) + 1)
24698 + chunk_pages = j - cur_page;
24707 + ret = -ENOMEM;
24711 + INIT_LIST_HEAD(&info->list);
24712 + info->page = pages[cur_page + i];
24713 + phys = page_to_phys(info->page);
24715 + list_add_tail(&info->list, &lists[bit_index]);
24721 + remain -= chunk_pages;
24735 + dst_pages[end++] = info->page;
24736 + list_del(&info->list);
24744 rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->base.dev,
24745 - rk_obj->pages, rk_obj->num_pages);
24746 + dst_pages, rk_obj->num_pages);
24747 if (IS_ERR(rk_obj->sgt)) {
24748 ret = PTR_ERR(rk_obj->sgt);
24749 - goto err_put_pages;
24753 + rk_obj->pages = dst_pages;
24758 @@ -104,8 +234,13 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
24760 dma_sync_sgtable_for_device(drm->dev, rk_obj->sgt, DMA_TO_DEVICE);
24770 drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false);
24772 @@ -118,59 +253,164 @@ static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj)
24773 drm_gem_put_pages(&rk_obj->base, rk_obj->pages, true, true);
24776 -static int rockchip_gem_alloc_iommu(struct rockchip_gem_object *rk_obj,
24777 - bool alloc_kmap)
24784 - int ret;
24785 + struct drm_gem_object *obj = &rk_obj->base;
24786 + struct drm_device *drm = obj->dev;
24791 - ret = rockchip_gem_get_pages(rk_obj);
24792 - if (ret < 0)
24793 - return ret;
24794 + rk_obj->dma_attrs = DMA_ATTR_WRITE_COMBINE;
24796 - ret = rockchip_gem_iommu_map(rk_obj);
24797 - if (ret < 0)
24798 - goto err_free;
24799 -
24800 - if (alloc_kmap) {
24801 - rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP,
24802 - pgprot_writecombine(PAGE_KERNEL));
24803 - if (!rk_obj->kvaddr) {
24804 - DRM_ERROR("failed to vmap() buffer\n");
24805 - ret = -ENOMEM;
24806 - goto err_unmap;
24807 - }
24809 + rk_obj->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
24811 + rk_obj->kvaddr = dma_alloc_attrs(drm->dev, obj->size,
24812 + &rk_obj->dma_handle, GFP_KERNEL,
24813 + rk_obj->dma_attrs);
24814 + if (!rk_obj->kvaddr) {
24815 + DRM_ERROR("failed to allocate %zu byte dma buffer", obj->size);
24816 + return -ENOMEM;
24821 + ret = -ENOMEM;
24825 + ret = dma_get_sgtable_attrs(drm->dev, sgt, rk_obj->kvaddr,
24826 + rk_obj->dma_handle, obj->size,
24827 + rk_obj->dma_attrs);
24833 + for_each_sg(sgt->sgl, s, sgt->nents, i)
24836 + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
24838 + rk_obj->pages = drm_calloc_large(rk_obj->num_pages,
24839 + sizeof(*rk_obj->pages));
24840 + if (!rk_obj->pages) {
24845 + if (drm_prime_sg_to_page_addr_arrays(sgt, rk_obj->pages, NULL,
24846 + rk_obj->num_pages)) {
24848 + ret = -EINVAL;
24852 + rk_obj->sgt = sgt;
24856 -err_unmap:
24857 - rockchip_gem_iommu_unmap(rk_obj);
24858 -err_free:
24859 - rockchip_gem_put_pages(rk_obj);
24861 + drm_free_large(rk_obj->pages);
24867 + dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr,
24868 + rk_obj->dma_handle, rk_obj->dma_attrs);
24873 -static int rockchip_gem_alloc_dma(struct rockchip_gem_object *rk_obj,
24874 - bool alloc_kmap)
24894 struct drm_gem_object *obj = &rk_obj->base;
24895 struct drm_device *drm = obj->dev;
24896 + struct rockchip_drm_private *private = drm->dev_private;
24901 - rk_obj->dma_attrs = DMA_ATTR_WRITE_COMBINE;
24902 -
24903 - if (!alloc_kmap)
24904 - rk_obj->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
24905 + if (!private->secure_buffer_pool) {
24907 + return -ENOMEM;
24910 - rk_obj->kvaddr = dma_alloc_attrs(drm->dev, obj->size,
24911 - &rk_obj->dma_addr, GFP_KERNEL,
24912 - rk_obj->dma_attrs);
24913 - if (!rk_obj->kvaddr) {
24914 - DRM_ERROR("failed to allocate %zu byte dma buffer", obj->size);
24915 + paddr = gen_pool_alloc(private->secure_buffer_pool, rk_obj->base.size);
24918 return -ENOMEM;
24921 + rk_obj->dma_handle = paddr;
24922 + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
24924 + rk_obj->pages = drm_calloc_large(rk_obj->num_pages,
24925 + sizeof(*rk_obj->pages));
24926 + if (!rk_obj->pages) {
24928 + ret = -ENOMEM;
24933 + while (i < rk_obj->num_pages) {
24934 + rk_obj->pages[i] = phys_to_page(paddr);
24938 + sgt = drm_prime_pages_to_sg(obj->dev, rk_obj->pages, rk_obj->num_pages);
24944 + rk_obj->sgt = sgt;
24949 + drm_free_large(rk_obj->pages);
24951 + gen_pool_free(private->secure_buffer_pool, paddr, rk_obj->base.size);
24958 + struct drm_gem_object *obj = &rk_obj->base;
24959 + struct drm_device *drm = obj->dev;
24960 + struct rockchip_drm_private *private = drm->dev_private;
24962 + drm_free_large(rk_obj->pages);
24963 + sg_free_table(rk_obj->sgt);
24964 + kfree(rk_obj->sgt);
24965 + gen_pool_free(private->secure_buffer_pool, rk_obj->dma_handle,
24966 + rk_obj->base.size);
24970 @@ -179,18 +419,66 @@ static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
24971 struct drm_gem_object *obj = &rk_obj->base;
24972 struct drm_device *drm = obj->dev;
24973 struct rockchip_drm_private *private = drm->dev_private;
24976 + if (!private->domain)
24977 + rk_obj->flags |= ROCKCHIP_BO_CONTIG;
24979 + if (rk_obj->flags & ROCKCHIP_BO_SECURE) {
24980 + rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_SECURE;
24981 + rk_obj->flags |= ROCKCHIP_BO_CONTIG;
24984 + return -EINVAL;
24989 + } else if (rk_obj->flags & ROCKCHIP_BO_CONTIG) {
24990 + rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_CMA;
24995 + rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_SHMEM;
25001 + rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages,
25004 + if (!rk_obj->kvaddr) {
25006 + ret = -ENOMEM;
25012 + if (private->domain) {
25017 + WARN_ON(!rk_obj->dma_handle);
25018 + rk_obj->dma_addr = rk_obj->dma_handle;
25024 if (private->domain)
25025 - return rockchip_gem_alloc_iommu(rk_obj, alloc_kmap);
25028 + if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SECURE)
25030 + else if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_CMA)
25033 - return rockchip_gem_alloc_dma(rk_obj, alloc_kmap);
25034 -}
25035 -
25036 -static void rockchip_gem_free_iommu(struct rockchip_gem_object *rk_obj)
25037 -{
25038 - vunmap(rk_obj->kvaddr);
25039 - rockchip_gem_iommu_unmap(rk_obj);
25040 - rockchip_gem_put_pages(rk_obj);
25046 @@ -198,16 +486,29 @@ static void rockchip_gem_free_dma(struct rockchip_gem_object *rk_obj)
25047 struct drm_gem_object *obj = &rk_obj->base;
25048 struct drm_device *drm = obj->dev;
25050 - dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr, rk_obj->dma_addr,
25051 - rk_obj->dma_attrs);
25052 + drm_free_large(rk_obj->pages);
25053 + sg_free_table(rk_obj->sgt);
25054 + kfree(rk_obj->sgt);
25055 + dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr,
25056 + rk_obj->dma_handle, rk_obj->dma_attrs);
25061 - if (rk_obj->pages)
25062 - rockchip_gem_free_iommu(rk_obj);
25063 - else
25064 + struct drm_device *drm = rk_obj->base.dev;
25065 + struct rockchip_drm_private *private = drm->dev_private;
25067 + if (private->domain)
25070 + if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SHMEM) {
25071 + vunmap(rk_obj->kvaddr);
25073 + } else if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SECURE) {
25081 @@ -239,16 +540,24 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
25086 + if (rk_obj->flags & ROCKCHIP_BO_CACHABLE)
25087 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
25093 vma->vm_flags &= ~VM_PFNMAP;
25095 - if (rk_obj->pages)
25096 + if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SECURE) {
25098 + ret = -EINVAL;
25099 + } else if (rk_obj->pages) {
25101 - else
25108 @@ -298,9 +607,15 @@ static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj)
25124 @@ -311,12 +626,15 @@ static struct rockchip_gem_object *
25128 + mapping = file_inode(obj->filp)->i_mapping;
25136 - bool alloc_kmap)
25141 @@ -324,6 +642,7 @@ rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
25145 + rk_obj->flags = flags;
25149 @@ -336,6 +655,28 @@ rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
25154 + * rockchip_gem_destroy - destroy gem object
25156 + * The dma_buf_unmap_attachment and dma_buf_detach will be re-defined if
25166 + attach = obj->import_attach;
25169 + dma_buf = attach->dmabuf;
25170 + dma_buf_detach(attach->dmabuf, attach);
25176 * rockchip_gem_free_object - (struct drm_driver)->gem_free_object_unlocked
25178 @@ -353,7 +694,11 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
25179 dma_unmap_sgtable(drm->dev, rk_obj->sgt,
25182 - drm_prime_gem_destroy(obj, rk_obj->sgt);
25183 + drm_free_large(rk_obj->pages);
25185 + rockchip_gem_destroy(obj, rk_obj->sgt);
25187 + drm_prime_gem_destroy(obj, rk_obj->sgt);
25191 @@ -371,13 +716,14 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
25195 - unsigned int *handle)
25203 - rk_obj = rockchip_gem_create_object(drm, size, false);
25208 @@ -414,7 +760,7 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv,
25212 - int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
25213 + u32 min_pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
25217 @@ -423,7 +769,7 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv,
25218 args->size = args->pitch * args->height;
25220 rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
25221 - &args->handle);
25222 + &args->handle, args->flags);
25226 @@ -514,6 +860,21 @@ rockchip_gem_prime_import_sg_table(struct drm_device *drm,
25230 + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
25231 + rk_obj->pages = drm_calloc_large(rk_obj->num_pages, sizeof(*rk_obj->pages));
25232 + if (!rk_obj->pages) {
25234 + ret = -ENOMEM;
25238 + ret = drm_prime_sg_to_page_addr_arrays(sg, rk_obj->pages, NULL, rk_obj->num_pages);
25241 + drm_free_large(rk_obj->pages);
25245 return &rk_obj->base;
25248 @@ -546,3 +907,155 @@ void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
25259 + rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
25260 + &args->handle, args->flags);
25269 + return drm_gem_dumb_map_offset(file_priv, drm, args->handle,
25270 + &args->offset);
25281 + obj = drm_gem_object_lookup(file_priv, args->handle);
25284 + return -EINVAL;
25288 + if (!(rk_obj->flags & ROCKCHIP_BO_CONTIG)) {
25289 + DRM_ERROR("Can't get phys address from non-continue buf.\n");
25290 + ret = -EINVAL;
25294 + args->phy_addr = page_to_phys(rk_obj->pages[0]);
25306 + struct drm_device *drm = obj->dev;
25308 + if (!rk_obj->sgt)
25311 + dma_sync_sg_for_cpu(drm->dev, rk_obj->sgt->sgl,
25312 + rk_obj->sgt->nents, dir);
25320 + struct drm_device *drm = obj->dev;
25322 + if (!rk_obj->sgt)
25325 + dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
25326 + rk_obj->sgt->nents, dir);
25343 + len += sg->length;
25348 + sg_left = len - offset;
25349 + sg_offset = sg->length - sg_left;
25360 + length -= size;
25375 + struct drm_device *drm = obj->dev;
25377 + if (!rk_obj->sgt)
25380 + rockchip_gem_prime_sgl_sync_range(drm->dev, rk_obj->sgt->sgl,
25381 + rk_obj->sgt->nents,
25393 + struct drm_device *drm = obj->dev;
25395 + if (!rk_obj->sgt)
25398 + rockchip_gem_prime_sgl_sync_range(drm->dev, rk_obj->sgt->sgl,
25399 + rk_obj->sgt->nents,
25404 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_ge…
25406 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
25408 @@ -7,14 +7,24 @@
25412 +#include <linux/dma-direction.h>
25428 - dma_addr_t dma_addr;
25434 @@ -42,12 +52,43 @@ int rockchip_gem_mmap_buf(struct drm_gem_object *obj,
25438 - rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
25439 - bool alloc_kmap);
25480 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vo…
25482 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
25484 @@ -6,21 +6,28 @@
25490 +#include <linux/fixp-arith.h>
25513 @@ -32,6 +39,12 @@
25517 +#include <dt-bindings/soc/rockchip-system-status.h>
25520 +#include <soc/rockchip/rockchip-system-status.h>
25526 @@ -39,28 +52,65 @@
25530 -#define VOP_WIN_SET(vop, win, name, v) \
25531 - vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
25532 -#define VOP_SCL_SET(vop, win, name, v) \
25533 - vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
25534 -#define VOP_SCL_SET_EXT(vop, win, name, v) \
25535 - vop_reg_set(vop, &win->phy->scl->ext->name, \
25536 - win->base, ~0, v, #name)
25540 + (reg.major == VOP_MAJOR(vop->version) && \
25541 + reg.begin_minor <= VOP_MINOR(vop->version) && \
25542 + reg.end_minor >= VOP_MINOR(vop->version))))
25544 -#define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
25545 - do { \
25546 - if (win_yuv2yuv && win_yuv2yuv->name.mask) \
25547 - vop_reg_set(vop, &win_yuv2yuv->name, 0, ~0, v, #name); \
25548 - } while (0)
25550 + VOP_REG_SUPPORT(vop, win->phy->name)
25553 + (win->phy->scl->ext && \
25554 + VOP_REG_SUPPORT(vop, win->phy->scl->ext->name))
25556 -#define VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, win_yuv2yuv, name, v) \
25558 + VOP_REG_SUPPORT(vop, vop->data->ctrl->name)
25561 + VOP_REG_SUPPORT(vop, vop->data->intr->name)
25568 - if (win_yuv2yuv && win_yuv2yuv->phy->name.mask) \
25569 - vop_reg_set(vop, &win_yuv2yuv->phy->name, win_yuv2yuv->base, ~0, v, #name); \
25574 + dev_dbg(vop->dev, "Warning: not support "#name"\n"); \
25583 + REG_SET(x, name, win->offset, VOP_WIN_NAME(win, name), v, true)
25585 + REG_SET(x, name, 0, win->ext->name, v, true)
25587 + REG_SET(x, name, win->offset, win->phy->scl->name, v, true)
25589 + REG_SET(x, name, win->offset, win->phy->scl->ext->name, v, true)
25592 + REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
25595 + vop_read_reg(vop, 0, &vop->data->ctrl->name)
25598 + REG_SET(vop, name, 0, vop->data->intr->name, \
25601 - vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
25602 + REG_SET_MASK(vop, name, 0, vop->data->intr->name, \
25607 vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
25608 @@ -79,66 +129,132 @@
25610 vop_get_intr_type(vop, &vop->data->intr->name, type)
25612 -#define VOP_WIN_GET(vop, win, name) \
25613 - vop_read_reg(vop, win->base, &win->phy->name)
25615 + vop_read_reg(x, 0, &vop->data->ctrl->name)
25617 -#define VOP_WIN_HAS_REG(win, name) \
25618 - (!!(win->phy->name.mask))
25620 + vop_read_reg(vop, win->offset, &VOP_WIN_NAME(win, name))
25622 -#define VOP_WIN_GET_YRGBADDR(vop, win) \
25623 - vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
25625 + (vop_get_win_phy(win, &win->phy->name)->name)
25628 ((vop_win) - (vop_win)->vop->win)
25630 -#define VOP_AFBC_SET(vop, name, v) \
25633 - if ((vop)->data->afbc) \
25634 - vop_reg_set((vop), &(vop)->data->afbc->name, \
25635 - 0, ~0, v, #name); \
25636 + if (vop->data->grf_ctrl) { \
25637 + vop_grf_writel(vop, vop->data->grf_ctrl->reg, v); \
25641 -#define to_vop(x) container_of(x, struct vop, crtc)
25645 -#define AFBC_FMT_RGB565 0x0
25646 -#define AFBC_FMT_U8U8U8U8 0x5
25647 -#define AFBC_FMT_U8U8U8 0x4
25652 -#define AFBC_TILE_16x16 BIT(4)
25658 -/*
25659 - * The coefficients of the following matrix are all fixed points.
25660 - * The format is S2.10 for the 3x3 part of the matrix, and S9.12 for the offsets.
25661 - * They are all represented in two's complement.
25662 - */
25663 -static const uint32_t bt601_yuv2rgb[] = {
25664 - 0x4A8, 0x0, 0x662,
25665 - 0x4A8, 0x1E6F, 0x1CBF,
25666 - 0x4A8, 0x812, 0x0,
25667 - 0x321168, 0x0877CF, 0x2EB127
25672 + struct drm_rect src;
25694 -enum vop_pending {
25695 - VOP_PENDING_FB_UNREF,
25708 - const struct vop_win_data *data;
25709 - const struct vop_win_yuv2yuv_data *yuv2yuv_data;
25737 -struct rockchip_rgb;
25739 - struct drm_crtc crtc;
25752 -
25770 - unsigned int win_enabled;
25772 /* protected by dev->event_lock */
25774 @@ -149,14 +265,22 @@ struct vop {
25782 - void __iomem *lut_regs;
25798 @@ -172,16 +296,83 @@ struct vop {
25808 - /* optional internal rgb encoder */
25809 - struct rockchip_rgb *rgb;
25818 + * bus-format types.
25858 + mutex_lock(&vop->vop_lock);
25865 + mutex_unlock(&vop->vop_lock);
25872 + if (IS_ERR_OR_NULL(vop->grf))
25877 + regmap_write(vop->grf, reg.offset, val);
25883 writel(v, vop->regs + offset);
25884 @@ -199,23 +390,15 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
25885 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
25888 -static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
25889 - uint32_t _offset, uint32_t _mask, uint32_t v,
25890 - const char *reg_name)
25895 - int offset, mask, shift;
25896 -
25897 - if (!reg || !reg->mask) {
25898 - DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name);
25901 - }
25902 -
25903 - offset = reg->offset + _offset;
25904 - mask = reg->mask & _mask;
25905 - shift = reg->shift;
25907 - if (reg->write_mask) {
25908 - v = ((v << shift) & 0xffff) | (mask << (shift + 16));
25912 uint32_t cached_val = vop->regsbak[offset >> 2];
25914 @@ -223,12 +406,21 @@ static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
25915 vop->regsbak[offset >> 2] = v;
25918 - if (reg->relaxed)
25920 writel_relaxed(v, vop->regs + offset);
25922 writel(v, vop->regs + offset);
25928 + if (!reg->mask && win->parent)
25929 + return win->parent->phy;
25931 + return win->phy;
25937 @@ -243,9 +435,147 @@ static inline uint32_t vop_get_intr_type(struct vop *vop,
25944 + const struct vop_hdr_table *table = vop->data->hdr_table;
25948 + hdr2sdr_eetf_oetf_yn[i] = table->hdr2sdr_eetf_yn[i] +
25949 + (table->hdr2sdr_bt1886oetf_yn[i] << 16);
25951 + vop_writel(vop, table->hdr2sdr_eetf_oetf_y0_offset,
25955 + table->hdr2sdr_eetf_oetf_y1_offset + (i - 1) * 4,
25958 + vop_writel(vop, table->hdr2sdr_sat_y0_offset,
25959 + table->hdr2sdr_sat_yn[0]);
25961 + vop_writel(vop, table->hdr2sdr_sat_y1_offset + (i - 1) * 4,
25962 + table->hdr2sdr_sat_yn[i]);
25964 + VOP_CTRL_SET(vop, hdr2sdr_src_min, table->hdr2sdr_src_range_min);
25965 + VOP_CTRL_SET(vop, hdr2sdr_src_max, table->hdr2sdr_src_range_max);
25966 + VOP_CTRL_SET(vop, hdr2sdr_normfaceetf, table->hdr2sdr_normfaceetf);
25967 + VOP_CTRL_SET(vop, hdr2sdr_dst_min, table->hdr2sdr_dst_range_min);
25968 + VOP_CTRL_SET(vop, hdr2sdr_dst_max, table->hdr2sdr_dst_range_max);
25969 + VOP_CTRL_SET(vop, hdr2sdr_normfacgamma, table->hdr2sdr_normfacgamma);
25975 + const struct vop_hdr_table *table = vop->data->hdr_table;
25982 + table->sdr2hdr_bt1886eotf_yn_for_bt2020[i] +
25983 + (table->sdr2hdr_st2084oetf_yn_for_bt2020[i] << 18);
25986 + table->sdr2hdr_bt1886eotf_yn_for_hdr[i] +
25987 + (table->sdr2hdr_st2084oetf_yn_for_hdr[i] << 18);
25990 + table->sdr2hdr_bt1886eotf_yn_for_hlg_hdr[i] +
25991 + (table->sdr2hdr_st2084oetf_yn_for_hlg_hdr[i] << 18);
25993 + vop_writel(vop, table->sdr2hdr_eotf_oetf_y0_offset,
25996 + vop_writel(vop, table->sdr2hdr_eotf_oetf_y1_offset +
25997 + (i - 1) * 4, sdr2hdr_eotf_oetf_yn[i]);
26000 + sdr2hdr_oetf_dx_dxpow[i] = table->sdr2hdr_st2084oetf_dxn[i] +
26001 + (table->sdr2hdr_st2084oetf_dxn_pow2[i] << 16);
26002 + vop_writel(vop, table->sdr2hdr_oetf_dx_dxpow1_offset + i * 4,
26007 + vop_writel(vop, table->sdr2hdr_oetf_xn1_offset + i * 4,
26008 + table->sdr2hdr_st2084oetf_xn[i]);
26028 - VOP_REG_SET(vop, common, cfg_done, 1);
26036 + for (i = 0; i < vop->num_wins; i++) {
26037 + struct vop_win *win = &vop->win[i];
26052 + if (win->phy->scl && win->phy->scl->ext) {
26060 + if (win->area_id == 0)
26068 + for (i = 0; i < vop->num_wins; i++) {
26069 + struct vop_win *win = &vop->win[i];
26077 + writel(v, vop->lut_regs + offset);
26082 + return readl(vop->lut_regs + offset);
26086 @@ -276,11 +606,19 @@ static enum vop_data_format vop_convert_format(uint32_t format)
26105 return -EINVAL;
26106 @@ -294,13 +632,13 @@ static int vop_convert_afbc_format(uint32_t format)
26110 - return AFBC_FMT_U8U8U8U8;
26114 - return AFBC_FMT_U8U8U8;
26118 - return AFBC_FMT_RGB565;
26123 @@ -310,6 +648,133 @@ static int vop_convert_afbc_format(uint32_t format)
26124 return -EINVAL;
26247 + for (i = 0 ; i < plane->modifier_count; i++)
26248 + if (plane->modifiers[i] == modifier)
26251 + return (i < plane->modifier_count) ? true : false;
26254 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
26257 @@ -344,29 +809,37 @@ static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
26261 -static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
26262 - uint32_t src_w, uint32_t src_h, uint32_t dst_w,
26263 - uint32_t dst_h, const struct drm_format_info *info)
26272 + uint8_t hsub = info->hsub;
26273 + uint8_t vsub = info->vsub;
26275 - uint16_t cbcr_src_w = src_w / info->hsub;
26276 - uint16_t cbcr_src_h = src_h / info->vsub;
26282 + const struct vop_data *vop_data = vop->data;
26285 - if (info->is_yuv)
26286 - is_yuv = true;
26287 -
26288 - if (dst_w > 3840) {
26289 - DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
26290 + if (!win->phy->scl)
26293 + if (!(vop_data->feature & VOP_FEATURE_ALPHA_SCALE)) {
26299 + if (info->is_yuv)
26302 if (!win->phy->scl->ext) {
26305 @@ -448,45 +921,411 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *…
26309 -static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
26313 + * HDR/SDR --> win0 --> HDR2SDR ----\
26314 + * \ MUX --\
26315 + * \ --> SDR2HDR/CSC--/ \
26317 + * SDR --> win1 -->pre_overlay ->SDR2HDR/CSC --> post_ovrlay-->post CSC-->output
26318 + * SDR --> win2 -/
26325 - unsigned long flags;
26326 + struct drm_atomic_state *state = crtc_state->state;
26336 - if (WARN_ON(!vop->is_enabled))
26337 - return;
26338 + if (!vop->data->hdr_table)
26349 + if (!pstate->fb)
26352 - spin_lock_irqsave(&vop->irq_lock, flags);
26353 + if (vop_plane_state->eotf > s->eotf)
26354 + if (win->feature & WIN_FEATURE_HDR2SDR)
26356 + if (vop_plane_state->eotf < s->eotf) {
26357 + if (win->feature & WIN_FEATURE_PRE_OVERLAY)
26365 - VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1);
26366 - VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1);
26375 - spin_unlock_irqrestore(&vop->irq_lock, flags);
26376 -}
26392 + if (!pstate->fb)
26395 -static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
26396 -{
26397 - unsigned long flags;
26398 + if (vop_plane_state->color_space == V4L2_COLORSPACE_BT2020 &&
26399 + vop_plane_state->color_space > s->color_space) {
26400 + if (win->feature & WIN_FEATURE_PRE_OVERLAY) {
26408 + if (s->color_space == V4L2_COLORSPACE_BT2020 &&
26409 + vop_plane_state->color_space < s->color_space) {
26410 + if (win->feature & WIN_FEATURE_PRE_OVERLAY) {
26421 - if (WARN_ON(!vop->is_enabled))
26422 - return;
26428 - spin_lock_irqsave(&vop->irq_lock, flags);
26430 + s->hdr.pre_overlay = pre_overlay;
26431 + s->hdr.hdr2sdr_en = hdr2sdr_en;
26432 + if (s->hdr.pre_overlay)
26433 + s->yuv_overlay = 0;
26435 - VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0);
26436 + s->hdr.sdr2hdr_state.bt1886eotf_pre_conv_en = !!pre_sdr2hdr_state;
26437 + s->hdr.sdr2hdr_state.rgb2rgb_pre_conv_en = !!pre_sdr2hdr_state;
26438 + s->hdr.sdr2hdr_state.rgb2rgb_pre_conv_mode = pre_sdr2hdr_mode;
26439 + s->hdr.sdr2hdr_state.st2084oetf_pre_conv_en = !!pre_sdr2hdr_state;
26441 - spin_unlock_irqrestore(&vop->irq_lock, flags);
26442 + s->hdr.sdr2hdr_state.bt1886eotf_post_conv_en = !!post_sdr2hdr_state;
26443 + s->hdr.sdr2hdr_state.rgb2rgb_post_conv_en = !!post_sdr2hdr_state;
26444 + s->hdr.sdr2hdr_state.rgb2rgb_post_conv_mode = post_sdr2hdr_mode;
26445 + s->hdr.sdr2hdr_state.st2084oetf_post_conv_en = !!post_sdr2hdr_state;
26446 + s->hdr.sdr2hdr_state.sdr2hdr_func = sdr2hdr_func;
26482 + dev_err(vop->dev, "wait win close timeout\n");
26486 - * (1) each frame starts at the start of the Vsync pulse which is signaled by
26487 - * the "FRAME_SYNC" interrupt.
26488 - * (2) the active data region of each frame ends at dsp_vact_end
26489 - * (3) we should program this same number (dsp_vact_end) into dsp_line_frag_num,
26490 - * to get "LINE_FLAG" interrupt at the end of the active on screen data.
26493 + * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
26494 + * RGB --> R2Y __/
26496 - * VOP_INTR_CTRL0.dsp_line_frag_num = VOP_DSP_VACT_ST_END.dsp_vact_end
26497 - * Interrupts
26498 - * LINE_FLAG -------------------------------+
26499 + * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020)
26500 + * RGB --> 709To2020->R2Y __/
26502 + * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709)
26503 + * RGB --> R2Y __/
26505 + * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
26506 + * RGB --> 709To2020->R2Y __/
26508 + * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709)
26509 + * RGB --> R2Y __/
26511 + * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601)
26512 + * RGB --> R2Y(601) __/
26514 + * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709)
26515 + * RGB --> bypass __/
26517 + * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020)
26519 + * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709)
26521 + * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601)
26523 + * 11. RGB --> bypass --> RGB_OUTPUT(709)
26544 + *y2r_table = csc_table->y2r_bt709;
26547 + *r2r_table = csc_table->r2r_bt709_to_bt2020;
26548 + *r2y_table = csc_table->r2y_bt2020;
26551 + *y2r_table = csc_table->y2r_bt2020;
26553 + *r2r_table = csc_table->r2r_bt2020_to_bt709;
26558 + *r2y_table = csc_table->r2y_bt709;
26562 + *r2y_table = csc_table->r2y_bt601_12_235; /* bt601 limit */
26564 + *r2y_table = csc_table->r2y_bt601; /* bt601 full */
26575 + return -EINVAL;
26578 + *y2r_table = csc_table->y2r_bt2020;
26582 + *y2r_table = csc_table->y2r_bt709;
26586 + *y2r_table = csc_table->y2r_bt601_12_235; /* bt601 limit */
26588 + *y2r_table = csc_table->y2r_bt601; /* bt601 full */
26594 + *r2r_table = csc_table->r2r_bt2020_to_bt709;
26617 + struct drm_atomic_state *state = crtc_state->state;
26619 + const struct vop_csc_table *csc_table = vop->data->csc_table;
26625 + is_output_yuv = is_yuv_output(s->bus_format);
26636 + if (!pstate->fb)
26638 + is_input_yuv = is_yuv_support(pstate->fb->format->format);
26639 + vop_plane_state->y2r_en = false;
26640 + vop_plane_state->r2r_en = false;
26641 + vop_plane_state->r2y_en = false;
26645 + vop_plane_state->color_space,
26646 + s->color_space,
26647 + &vop_plane_state->y2r_table,
26648 + &vop_plane_state->r2r_table,
26649 + &vop_plane_state->r2y_table);
26653 + vop_setup_csc_mode(is_input_yuv, s->yuv_overlay,
26654 + vop_plane_state->color_space, s->color_space,
26655 + &vop_plane_state->y2r_en,
26656 + &vop_plane_state->r2y_en,
26657 + &vop_plane_state->csc_mode);
26660 + vop_plane_state->y2r_en = !!vop_plane_state->y2r_table;
26661 + vop_plane_state->r2r_en = !!vop_plane_state->r2r_table;
26662 + vop_plane_state->r2y_en = !!vop_plane_state->r2y_table;
26668 + * hdr2sdr on rk3328, vop can't support per-pixel alpha * global
26671 + * UI(rgbx) -> yuv -> rgb ->hdr2sdr -> overlay -> output.
26673 + if (s->hdr.hdr2sdr_en &&
26674 + vop_plane_state->eotf == HDMI_EOTF_SMPTE_ST2084 &&
26675 + !is_yuv_support(pstate->fb->format->format))
26676 + vop_plane_state->r2y_en = true;
26677 + if (win->feature & WIN_FEATURE_PRE_OVERLAY)
26678 + vop_plane_state->r2r_en =
26679 + s->hdr.sdr2hdr_state.rgb2rgb_pre_conv_en;
26680 + else if (win->feature & WIN_FEATURE_HDR2SDR)
26681 + vop_plane_state->r2r_en =
26682 + s->hdr.sdr2hdr_state.rgb2rgb_post_conv_en;
26704 + if (WARN_ON(!vop->is_enabled))
26707 + spin_lock_irqsave(&vop->irq_lock, flags);
26712 + spin_unlock_irqrestore(&vop->irq_lock, flags);
26719 + if (WARN_ON(!vop->is_enabled))
26722 + spin_lock_irqsave(&vop->irq_lock, flags);
26726 + spin_unlock_irqrestore(&vop->irq_lock, flags);
26738 + * LINE_FLAG -------------------------------+
26739 * FRAME_SYNC ----+ |
26742 @@ -567,147 +1406,234 @@ static void vop_core_clks_disable(struct vop *vop)
26743 clk_disable(vop->hclk);
26746 -static void vop_win_disable(struct vop *vop, const struct vop_win *vop_win)
26749 - const struct vop_win_data *win = vop_win->data;
26753 - if (win->phy->scl && win->phy->scl->ext) {
26754 - VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
26755 - VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
26756 - VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
26757 - VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
26758 + if (!vop->is_enabled || !vop->lut || !vop->lut_regs)
26761 + if (WARN_ON(!drm_modeset_is_locked(&crtc->mutex)))
26765 + spin_lock(&vop->reg_lock);
26768 + spin_unlock(&vop->reg_lock);
26777 - VOP_WIN_SET(vop, win, enable, 0);
26778 - vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win));
26779 + for (i = 0; i < vop->lut_len; i++)
26780 + vop_write_lut(vop, i << 2, vop->lut[i]);
26782 + spin_lock(&vop->reg_lock);
26787 + vop->lut_active = true;
26789 + spin_unlock(&vop->reg_lock);
26803 -static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
26808 - int ret, i;
26809 + u32 lut_len = vop->lut_len;
26812 - ret = pm_runtime_get_sync(vop->dev);
26813 - if (ret < 0) {
26814 - DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
26815 - return ret;
26816 - }
26817 + if (regno >= lut_len || !vop->lut)
26820 - ret = vop_core_clks_enable(vop);
26821 - if (WARN_ON(ret < 0))
26822 - goto err_put_pm_runtime;
26823 + r = red * (lut_len - 1) / 0xffff;
26824 + g = green * (lut_len - 1) / 0xffff;
26825 + b = blue * (lut_len - 1) / 0xffff;
26826 + vop->lut[regno] = r * lut_len * lut_len + g * lut_len + b;
26829 - ret = clk_enable(vop->dclk);
26830 - if (WARN_ON(ret < 0))
26831 - goto err_disable_core;
26836 + u32 lut_len = vop->lut_len;
26839 - /*
26840 - * Slave iommu shares power, irq and clock with vop. It was associated
26841 - * automatically with this master device via common driver code.
26842 - * Now that we have enabled the clock we attach it to the shared drm
26843 - * mapping.
26844 - */
26845 - ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
26846 - if (ret) {
26847 - DRM_DEV_ERROR(vop->dev,
26848 - "failed to attach dma mapping, %d\n", ret);
26849 - goto err_disable_dclk;
26850 - }
26851 + if (regno >= lut_len || !vop->lut)
26854 - spin_lock(&vop->reg_lock);
26855 - for (i = 0; i < vop->len; i += 4)
26856 - writel_relaxed(vop->regsbak[i / 4], vop->regs + i);
26857 + r = (vop->lut[regno] / lut_len / lut_len) & (lut_len - 1);
26858 + g = (vop->lut[regno] / lut_len) & (lut_len - 1);
26859 + b = vop->lut[regno] & (lut_len - 1);
26860 + *red = r * 0xffff / (lut_len - 1);
26861 + *green = g * 0xffff / (lut_len - 1);
26862 + *blue = b * 0xffff / (lut_len - 1);
26865 - /*
26866 - * We need to make sure that all windows are disabled before we
26867 - * enable the crtc. Otherwise we might try to scan from a destroyed
26868 - * buffer later.
26869 - *
26870 - * In the case of enable-after-PSR, we don't need to worry about this
26871 - * case since the buffer is guaranteed to be valid and disabling the
26872 - * window will result in screen glitches on PSR exit.
26873 - */
26874 - if (!old_state || !old_state->self_refresh_active) {
26875 - for (i = 0; i < vop->data->win_size; i++) {
26876 - struct vop_win *vop_win = &vop->win[i];
26882 + int len = min(size, vop->lut_len);
26885 - vop_win_disable(vop, vop_win);
26886 - }
26887 - }
26888 + if (!vop->lut)
26889 + return -EINVAL;
26891 - if (vop->data->afbc) {
26892 - struct rockchip_crtc_state *s;
26893 - /*
26894 - * Disable AFBC and forget there was a vop window with AFBC
26895 - */
26896 - VOP_AFBC_SET(vop, enable, 0);
26897 - s = to_rockchip_crtc_state(crtc->state);
26898 - s->enable_afbc = false;
26911 + struct drm_color_lut *lut = vop->gamma_lut;
26914 + for (i = 0; i < vop->lut_len; i++)
26927 + ret = clk_prepare_enable(vop->hclk);
26929 + dev_err(vop->dev, "failed to enable hclk - %d\n", ret);
26933 - vop_cfg_done(vop);
26934 + ret = clk_prepare_enable(vop->dclk);
26936 + dev_err(vop->dev, "failed to enable dclk - %d\n", ret);
26940 - spin_unlock(&vop->reg_lock);
26941 + ret = clk_prepare_enable(vop->aclk);
26943 + dev_err(vop->dev, "failed to enable aclk - %d\n", ret);
26947 - /*
26948 - * At here, vop clock & iommu is enable, R/W vop regs would be safe.
26949 - */
26950 - vop->is_enabled = true;
26951 + ret = pm_runtime_get_sync(vop->dev);
26953 + dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
26957 - spin_lock(&vop->reg_lock);
26958 + memcpy(vop->regsbak, vop->regs, vop->len);
26960 - VOP_REG_SET(vop, common, standby, 1);
26964 - spin_unlock(&vop->reg_lock);
26969 + vop->version = VOP_VERSION(3, 1);
26972 - drm_crtc_vblank_on(crtc);
26973 + vop->is_enabled = true;
26975 - return 0;
26979 - clk_disable(vop->dclk);
26980 -err_disable_core:
26981 - vop_core_clks_disable(vop);
26982 -err_put_pm_runtime:
26983 - pm_runtime_put_sync(vop->dev);
26984 - return ret;
26985 + clk_disable_unprepare(vop->dclk);
26987 + clk_disable_unprepare(vop->hclk);
26990 -static void rockchip_drm_set_win_enabled(struct drm_crtc *crtc, bool enabled)
26993 - struct vop *vop = to_vop(crtc);
26994 - int i;
27006 - spin_lock(&vop->reg_lock);
27012 + for (i = 0; i < vop->num_wins; i++) {
27013 + struct vop_win *win = &vop->win[i];
27016 - for (i = 0; i < vop->data->win_size; i++) {
27017 - struct vop_win *vop_win = &vop->win[i];
27018 - const struct vop_win_data *win = vop_win->data;
27025 - VOP_WIN_SET(vop, win, enable,
27026 - enabled && (vop->win_enabled & BIT(i)));
27027 - }
27028 - vop_cfg_done(vop);
27034 - spin_unlock(&vop->reg_lock);
27037 + vop->aclk_rate = clk_get_rate(vop->aclk);
27038 + clk_set_rate(vop->aclk, vop->aclk_rate / 3);
27039 + vop->aclk_rate_reset = true;
27049 WARN_ON(vop->event);
27051 - if (crtc->state->self_refresh_active)
27052 - rockchip_drm_set_win_enabled(crtc, false);
27053 -
27054 - mutex_lock(&vop->vop_lock);
27055 + if (crtc->state->self_refresh_active) {
27064 -
27065 - if (crtc->state->self_refresh_active)
27066 - goto out;
27073 @@ -721,28 +1647,34 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
27075 spin_lock(&vop->reg_lock);
27077 - VOP_REG_SET(vop, common, standby, 1);
27080 spin_unlock(&vop->reg_lock);
27082 - wait_for_completion(&vop->dsp_hold_completion);
27083 + WARN_ON(!wait_for_completion_timeout(&vop->dsp_hold_completion,
27088 vop->is_enabled = false;
27089 + if (vop->is_iommu_enabled) {
27094 + rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
27095 + vop->is_iommu_enabled = false;
27098 - /*
27099 - * vop standby complete, so iommu detach is safe.
27100 - */
27101 - rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
27102 + pm_runtime_put_sync(vop->dev);
27103 + clk_disable_unprepare(vop->dclk);
27104 + clk_disable_unprepare(vop->aclk);
27105 + clk_disable_unprepare(vop->hclk);
27108 - clk_disable(vop->dclk);
27109 - vop_core_clks_disable(vop);
27110 - pm_runtime_put(vop->dev);
27114 - mutex_unlock(&vop->vop_lock);
27115 -
27116 if (crtc->state->event && !crtc->state->active) {
27117 spin_lock_irq(&crtc->dev->event_lock);
27118 drm_crtc_send_vblank_event(crtc, crtc->state->event);
27119 @@ -752,23 +1684,29 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
27123 -static void vop_plane_destroy(struct drm_plane *plane)
27127 - drm_plane_cleanup(plane);
27128 + if (plane->state->fb)
27129 + drm_framebuffer_get(plane->state->fb);
27134 -static inline bool rockchip_afbc(u64 modifier)
27138 - return modifier == ROCKCHIP_AFBC_MOD;
27139 + if (old_state->fb)
27140 + drm_framebuffer_put(old_state->fb);
27143 -static bool rockchip_mod_supported(struct drm_plane *plane,
27144 - u32 format, u64 modifier)
27151 - if (!rockchip_afbc(modifier)) {
27156 @@ -783,21 +1721,43 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27157 struct drm_crtc *crtc = state->crtc;
27159 struct drm_framebuffer *fb = state->fb;
27160 - struct vop_win *vop_win = to_vop_win(plane);
27161 - const struct vop_win_data *win = vop_win->data;
27167 + struct drm_rect *dest = &vop_plane_state->dest;
27168 + struct drm_rect *src = &vop_plane_state->src;
27171 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
27173 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
27178 - if (!crtc || WARN_ON(!fb))
27179 + crtc = crtc ? crtc : plane->state->crtc;
27181 + plane->state->visible = false;
27185 crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
27187 return -EINVAL;
27189 + src->x1 = state->src_x;
27190 + src->y1 = state->src_y;
27191 + src->x2 = state->src_x + state->src_w;
27192 + src->y2 = state->src_y + state->src_h;
27193 + dest->x1 = state->crtc_x;
27194 + dest->y1 = state->crtc_y;
27195 + dest->x2 = state->crtc_x + state->crtc_w;
27196 + dest->y2 = state->crtc_y + state->crtc_h;
27197 + vop_plane_state->zpos = state->zpos;
27198 + vop_plane_state->blend_mode = state->pixel_blend_mode;
27203 @@ -807,16 +1767,37 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27204 if (!state->visible)
27207 - ret = vop_convert_format(fb->format->format);
27208 - if (ret < 0)
27209 - return ret;
27210 + vop_plane_state->format = vop_convert_format(fb->format->format);
27211 + if (vop_plane_state->format < 0)
27212 + return vop_plane_state->format;
27214 - /*
27215 - * Src.x1 can be odd when do clip, but yuv plane start point
27216 - * need align with 2 pixel.
27217 - */
27218 - if (fb->format->is_yuv && ((state->src.x1 >> 16) % 2)) {
27219 - DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n");
27221 + vop_data = vop->data;
27223 + if (state->src_w >> 16 < 4 || state->src_h >> 16 < 4 ||
27224 + state->crtc_w < 4 || state->crtc_h < 4) {
27225 + DRM_ERROR("Invalid size: %dx%d->%dx%d, min size is 4x4\n",
27226 + state->src_w >> 16, state->src_h >> 16,
27227 + state->crtc_w, state->crtc_h);
27228 + return -EINVAL;
27231 + if (drm_rect_width(src) >> 16 > vop_data->max_input.width ||
27232 + drm_rect_height(src) >> 16 > vop_data->max_input.height) {
27234 + drm_rect_width(src) >> 16,
27235 + drm_rect_height(src) >> 16,
27236 + vop_data->max_input.width,
27237 + vop_data->max_input.height);
27238 + return -EINVAL;
27242 + * Src.x1 can be odd when do clip, but yuv plane start point
27245 + if (fb->format->is_yuv && ((state->src.x1 >> 16) % 2)) {
27247 return -EINVAL;
27250 @@ -825,28 +1806,28 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27251 return -EINVAL;
27254 - if (rockchip_afbc(fb->modifier)) {
27255 - struct vop *vop = to_vop(crtc);
27256 + offset = (src->x1 >> 16) * fb->format->cpp[0];
27257 + vop_plane_state->offset = offset + fb->offsets[0];
27258 + if (state->rotation & DRM_MODE_REFLECT_Y)
27259 + offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
27261 + offset += (src->y1 >> 16) * fb->pitches[0];
27263 - if (!vop->data->afbc) {
27264 - DRM_ERROR("vop does not support AFBC\n");
27265 - return -EINVAL;
27266 - }
27267 + obj = fb->obj[0];
27269 + vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
27270 + if (fb->format->is_yuv) {
27271 + int hsub = fb->format->hsub;
27272 + int vsub = fb->format->vsub;
27274 - ret = vop_convert_afbc_format(fb->format->format);
27275 - if (ret < 0)
27276 - return ret;
27277 + offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub;
27278 + offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
27280 - if (state->src.x1 || state->src.y1) {
27281 - DRM_ERROR("AFBC does not support offset display, xpos=%d, ypos=%d, offset=%d\n", state->src.x1,…
27282 - return -EINVAL;
27283 - }
27284 + uv_obj = fb->obj[1];
27287 - if (state->rotation && state->rotation != DRM_MODE_ROTATE_0) {
27288 - DRM_ERROR("No rotation support in AFBC, rotation=%d\n",
27289 - state->rotation);
27290 - return -EINVAL;
27291 - }
27292 + dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
27293 + vop_plane_state->uv_mst = dma_addr;
27297 @@ -855,15 +1836,33 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
27301 - struct vop_win *vop_win = to_vop_win(plane);
27303 struct vop *vop = to_vop(old_state->crtc);
27306 + to_vop_plane_state(plane->state);
27309 if (!old_state->crtc)
27312 spin_lock(&vop->reg_lock);
27314 - vop_win_disable(vop, vop_win);
27322 + if (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 5 &&
27323 + win->win_id == 2)
27327 + kfree(vop_plane_state->planlist);
27328 + vop_plane_state->planlist = NULL;
27331 spin_unlock(&vop->reg_lock);
27333 @@ -873,26 +1872,46 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
27335 struct drm_plane_state *state = plane->state;
27336 struct drm_crtc *crtc = state->crtc;
27337 - struct vop_win *vop_win = to_vop_win(plane);
27338 - const struct vop_win_data *win = vop_win->data;
27339 - const struct vop_win_yuv2yuv_data *win_yuv2yuv = vop_win->yuv2yuv_data;
27343 + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
27345 struct vop *vop = to_vop(state->crtc);
27346 struct drm_framebuffer *fb = state->fb;
27347 - unsigned int actual_w, actual_h;
27351 - struct drm_rect *src = &state->src;
27352 - struct drm_rect *dest = &state->dst;
27353 - struct drm_gem_object *obj, *uv_obj;
27354 - struct rockchip_gem_object *rk_obj, *rk_uv_obj;
27355 - unsigned long offset;
27356 - dma_addr_t dma_addr;
27357 + struct drm_rect *src = &vop_plane_state->src;
27358 + struct drm_rect *dest = &vop_plane_state->dest;
27359 + const uint32_t *y2r_table = vop_plane_state->y2r_table;
27360 + const uint32_t *r2r_table = vop_plane_state->r2r_table;
27361 + const uint32_t *r2y_table = vop_plane_state->r2y_table;
27363 - bool rb_swap;
27364 - int win_index = VOP_WIN_TO_INDEX(vop_win);
27365 - int format;
27367 int is_yuv = fb->format->is_yuv;
27368 - int i;
27380 + obj = fb->obj[0];
27383 + num_pages = rk_obj->num_pages;
27384 + pages = rk_obj->pages;
27386 + if (fb->modifier == DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16))
27394 @@ -908,206 +1927,427 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
27398 - obj = fb->obj[0];
27399 - rk_obj = to_rockchip_obj(obj);
27400 -
27401 + mode = &crtc->state->adjusted_mode;
27402 actual_w = drm_rect_width(src) >> 16;
27403 actual_h = drm_rect_height(src) >> 16;
27404 - act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
27406 - dsp_info = (drm_rect_height(dest) - 1) << 16;
27407 - dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
27408 -
27409 - dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
27410 - dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
27411 - dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
27413 + if (dest->x1 + dsp_w > adjusted_mode->hdisplay) {
27414 + DRM_ERROR("%s win%d dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
27415 + crtc->name, win->win_id, dest->x1, dsp_w, adjusted_mode->hdisplay);
27416 + dsp_w = adjusted_mode->hdisplay - dest->x1;
27422 + if (dest->y1 + dsp_h > adjusted_mode->vdisplay) {
27423 + DRM_ERROR("%s win%d dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
27424 + crtc->name, win->win_id, dest->y1, dsp_h, adjusted_mode->vdisplay);
27425 + dsp_h = adjusted_mode->vdisplay - dest->y1;
27431 - offset = (src->x1 >> 16) * fb->format->cpp[0];
27432 - offset += (src->y1 >> 16) * fb->pitches[0];
27433 - dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
27434 + act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
27436 - /*
27437 - * For y-mirroring we need to move address
27438 - * to the beginning of the last line.
27439 - */
27440 - if (state->rotation & DRM_MODE_REFLECT_Y)
27441 - dma_addr += (actual_h - 1) * fb->pitches[0];
27442 + dsp_info = (dsp_h - 1) << 16;
27443 + dsp_info |= (dsp_w - 1) & 0xffff;
27445 - format = vop_convert_format(fb->format->format);
27446 + dsp_stx = dest->x1 + mode->crtc_htotal - mode->crtc_hsync_start;
27447 + dsp_sty = dest->y1 + mode->crtc_vtotal - mode->crtc_vsync_start;
27450 + s = to_rockchip_crtc_state(crtc->state);
27451 spin_lock(&vop->reg_lock);
27453 - if (rockchip_afbc(fb->modifier)) {
27454 - int afbc_format = vop_convert_afbc_format(fb->format->format);
27455 -
27456 - VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16);
27457 - VOP_AFBC_SET(vop, hreg_block_split, 0);
27458 - VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win));
27459 - VOP_AFBC_SET(vop, hdr_ptr, dma_addr);
27460 - VOP_AFBC_SET(vop, pic_size, act_info);
27461 - }
27462 -
27463 - VOP_WIN_SET(vop, win, format, format);
27464 + VOP_WIN_SET(vop, win, format, vop_plane_state->format);
27465 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
27466 - VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
27467 - VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
27468 - VOP_WIN_SET(vop, win, y_mir_en,
27469 + VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
27472 (state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0);
27473 - VOP_WIN_SET(vop, win, x_mir_en,
27475 (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
27478 - int hsub = fb->format->hsub;
27479 - int vsub = fb->format->vsub;
27480 - int bpp = fb->format->cpp[1];
27481 -
27482 - uv_obj = fb->obj[1];
27483 - rk_uv_obj = to_rockchip_obj(uv_obj);
27484 -
27485 - offset = (src->x1 >> 16) * bpp / hsub;
27486 - offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
27487 -
27488 - dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
27489 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
27490 - VOP_WIN_SET(vop, win, uv_mst, dma_addr);
27491 -
27492 - for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) {
27493 - VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop,
27494 - win_yuv2yuv,
27495 - y2r_coefficients[i],
27496 - bt601_yuv2rgb[i]);
27497 - }
27498 + VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst);
27500 + VOP_WIN_SET(vop, win, fmt_10, is_yuv_10bit(fb->format->format));
27501 + VOP_WIN_SET(vop, win, fmt_yuyv, is_yuyv_format(fb->format->format));
27503 if (win->phy->scl)
27506 - fb->format);
27507 + fb->format->format);
27513 rb_swap = has_rb_swapped(fb->format->format);
27514 - VOP_WIN_SET(vop, win, rb_swap, rb_swap);
27515 -
27517 - * Blending win0 with the background color doesn't seem to work
27518 - * correctly. We only get the background color, no matter the contents
27519 - * of the win0 framebuffer. However, blending pre-multiplied color
27520 - * with the default opaque black default background color is a no-op,
27521 - * so we can just disable blending to get the correct result.
27524 - if (fb->format->has_alpha && win_index > 0) {
27525 + if ((fb->format->format == DRM_FORMAT_RGB888 || fb->format->format == DRM_FORMAT_BGR888) &&
27526 + VOP_MAJOR(vop->version) == 3)
27530 + global_alpha_en = (vop_plane_state->global_alpha == 0xff) ? 0 : 1;
27531 + if ((is_alpha_support(fb->format->format) || global_alpha_en) &&
27532 + (s->dsp_layer_sel & 0x3) != win->win_id) {
27535 + if (is_alpha_support(fb->format->format) && global_alpha_en)
27537 + else if (is_alpha_support(fb->format->format))
27546 - SRC_BLEND_M0(ALPHA_PER_PIX) |
27547 - SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
27548 - SRC_FACTOR_M0(ALPHA_ONE);
27554 -
27555 - VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL);
27556 - VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX);
27558 + vop_plane_state->blend_mode == DRM_MODE_BLEND_PREMULTI ? 1 : 0);
27565 -
27566 + VOP_WIN_SET(vop, win, global_alpha_val, vop_plane_state->global_alpha);
27568 + VOP_WIN_SET(vop, win, csc_mode, vop_plane_state->csc_mode);
27569 + if (win->csc) {
27570 + vop_load_csc_table(vop, win->csc->y2r_offset, y2r_table);
27571 + vop_load_csc_table(vop, win->csc->r2r_offset, r2r_table);
27572 + vop_load_csc_table(vop, win->csc->r2y_offset, r2y_table);
27573 + VOP_WIN_SET_EXT(vop, win, csc, y2r_en, vop_plane_state->y2r_en);
27574 + VOP_WIN_SET_EXT(vop, win, csc, r2r_en, vop_plane_state->r2r_en);
27575 + VOP_WIN_SET_EXT(vop, win, csc, r2y_en, vop_plane_state->r2y_en);
27576 + VOP_WIN_SET_EXT(vop, win, csc, csc_mode, vop_plane_state->csc_mode);
27579 - vop->win_enabled |= BIT(win_index);
27581 spin_unlock(&vop->reg_lock);
27583 + * spi interface(vop_plane_state->yrgb_kvaddr, fb->pixel_format,
27586 + vop->is_iommu_needed = true;
27588 + kfree(vop_plane_state->planlist);
27589 + vop_plane_state->planlist = NULL;
27593 + planlist->dump_info.AFBC_flag = AFBC_flag;
27594 + planlist->dump_info.area_id = win->area_id;
27595 + planlist->dump_info.win_id = win->win_id;
27596 + planlist->dump_info.yuv_format =
27597 + is_yuv_support(fb->format->format);
27598 + planlist->dump_info.num_pages = num_pages;
27599 + planlist->dump_info.pages = pages;
27600 + planlist->dump_info.offset = vop_plane_state->offset;
27601 + planlist->dump_info.pitches = fb->pitches[0];
27602 + planlist->dump_info.height = actual_h;
27603 + planlist->dump_info.format = fb->format;
27604 + list_add_tail(&planlist->entry, &vop->rockchip_crtc.vop_dump_list_head);
27605 + vop_plane_state->planlist = planlist;
27610 + if (vop->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
27611 + vop->rockchip_crtc.vop_dump_times > 0) {
27612 + rockchip_drm_dump_plane_buffer(&planlist->dump_info, vop->rockchip_crtc.frame_count);
27613 + vop->rockchip_crtc.vop_dump_times--;
27618 -static int vop_plane_atomic_async_check(struct drm_plane *plane,
27619 - struct drm_plane_state *state)
27659 - struct vop_win *vop_win = to_vop_win(plane);
27660 - const struct vop_win_data *win = vop_win->data;
27661 - int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
27662 - DRM_PLANE_HELPER_NO_SCALING;
27663 - int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
27664 - DRM_PLANE_HELPER_NO_SCALING;
27665 - struct drm_crtc_state *crtc_state;
27671 - if (plane != state->crtc->cursor)
27672 - return -EINVAL;
27673 + state = drm_atomic_state_alloc(plane->dev);
27675 + return -ENOMEM;
27677 - if (!plane->state)
27678 - return -EINVAL;
27679 + state->acquire_ctx = ctx;
27686 - if (!plane->state->fb)
27687 - return -EINVAL;
27694 + plane_state->crtc_x = crtc_x;
27695 + plane_state->crtc_y = crtc_y;
27696 + plane_state->crtc_w = crtc_w;
27697 + plane_state->crtc_h = crtc_h;
27698 + plane_state->src_x = src_x;
27699 + plane_state->src_y = src_y;
27700 + plane_state->src_w = src_w;
27701 + plane_state->src_h = src_h;
27703 + if (plane == crtc->cursor || vop_plane_state->async_commit)
27704 + state->legacy_cursor_update = true;
27733 + state = drm_atomic_state_alloc(plane->dev);
27735 + return -ENOMEM;
27737 + state->acquire_ctx = ctx;
27745 - if (state->state)
27746 - crtc_state = drm_atomic_get_existing_crtc_state(state->state,
27747 - state->crtc);
27748 - else /* Special case for asynchronous cursor updates. */
27749 - crtc_state = plane->crtc->state;
27750 + if ((plane_state->crtc && plane_state->crtc->cursor == plane) ||
27751 + vop_plane_state->async_commit)
27752 + plane_state->state->legacy_cursor_update = true;
27754 - return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
27755 - min_scale, max_scale,
27756 - true, true);
27767 -static void vop_plane_atomic_async_update(struct drm_plane *plane,
27768 - struct drm_plane_state *new_state)
27771 - struct vop *vop = to_vop(plane->state->crtc);
27772 - struct drm_framebuffer *old_fb = plane->state->fb;
27776 - plane->state->crtc_x = new_state->crtc_x;
27777 - plane->state->crtc_y = new_state->crtc_y;
27778 - plane->state->crtc_h = new_state->crtc_h;
27779 - plane->state->crtc_w = new_state->crtc_w;
27780 - plane->state->src_x = new_state->src_x;
27781 - plane->state->src_y = new_state->src_y;
27782 - plane->state->src_h = new_state->src_h;
27783 - plane->state->src_w = new_state->src_w;
27784 - swap(plane->state->fb, new_state->fb);
27788 + to_vop_plane_state(plane->state);
27791 + if (plane->state && plane->state->fb)
27792 + __drm_atomic_helper_plane_destroy_state(plane->state);
27798 - if (vop->is_enabled) {
27799 - vop_plane_atomic_update(plane, plane->state);
27800 - spin_lock(&vop->reg_lock);
27801 - vop_cfg_done(vop);
27802 - spin_unlock(&vop->reg_lock);
27803 + __drm_atomic_helper_plane_reset(plane, &vop_plane_state->base);
27804 + win->state.zpos = win->zpos;
27805 + vop_plane_state->global_alpha = 0xff;
27808 - /*
27809 - * A scanout can still be occurring, so we can't drop the
27810 - * reference to the old framebuffer. To solve this we get a
27811 - * reference to old_fb and set a worker to release it later.
27812 - * FIXME: if we perform 500 async_update calls before the
27813 - * vblank, then we can have 500 different framebuffers waiting
27814 - * to be released.
27815 - */
27816 - if (old_fb && plane->state->fb != old_fb) {
27817 - drm_framebuffer_get(old_fb);
27818 - WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
27819 - drm_flip_work_queue(&vop->fb_unref_work, old_fb);
27820 - set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
27821 - }
27828 + if (WARN_ON(!plane->state))
27831 + old_vop_plane_state = to_vop_plane_state(plane->state);
27838 + &vop_plane_state->base);
27840 + return &vop_plane_state->base;
27858 + struct rockchip_drm_private *private = plane->dev->dev_private;
27862 + if (property == private->eotf_prop) {
27863 + plane_state->eotf = val;
27867 + if (property == private->color_space_prop) {
27868 + plane_state->color_space = val;
27872 + if (property == private->async_commit_prop) {
27873 + plane_state->async_commit = val;
27877 + if (property == win->color_key_prop) {
27878 + plane_state->color_key = val;
27883 + property->base.id, property->name);
27885 + return -EINVAL;
27888 -static const struct drm_plane_helper_funcs plane_helper_funcs = {
27889 - .atomic_check = vop_plane_atomic_check,
27890 - .atomic_update = vop_plane_atomic_update,
27891 - .atomic_disable = vop_plane_atomic_disable,
27892 - .atomic_async_check = vop_plane_atomic_async_check,
27893 - .atomic_async_update = vop_plane_atomic_async_update,
27894 - .prepare_fb = drm_gem_fb_prepare_fb,
27895 -};
27903 + struct rockchip_drm_private *private = plane->dev->dev_private;
27905 + if (property == private->eotf_prop) {
27906 + *val = plane_state->eotf;
27910 + if (property == private->color_space_prop) {
27911 + *val = plane_state->color_space;
27915 + if (property == private->async_commit_prop) {
27916 + *val = plane_state->async_commit;
27920 + if (property == private->share_id_prop) {
27922 + struct drm_mode_object *obj = &plane->base;
27924 + for (i = 0; i < obj->properties->count; i++) {
27925 + if (obj->properties->properties[i] == property) {
27926 + *val = obj->properties->values[i];
27932 + if (property == win->color_key_prop) {
27933 + *val = plane_state->color_key;
27938 + property->base.id, property->name);
27940 + return -EINVAL;
27944 - .update_plane = drm_atomic_helper_update_plane,
27945 - .disable_plane = drm_atomic_helper_disable_plane,
27949 - .reset = drm_atomic_helper_plane_reset,
27950 - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
27951 - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
27952 - .format_mod_supported = rockchip_mod_supported,
27962 @@ -1115,281 +2355,1485 @@ static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
27966 - if (WARN_ON(!vop->is_enabled))
27967 - return -EPERM;
27968 + if (WARN_ON(!vop->is_enabled))
27969 + return -EPERM;
27971 + spin_lock_irqsave(&vop->irq_lock, flags);
27973 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7) {
27981 + spin_unlock_irqrestore(&vop->irq_lock, flags);
27991 + if (WARN_ON(!vop->is_enabled))
27994 + spin_lock_irqsave(&vop->irq_lock, flags);
27996 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7)
28001 + spin_unlock_irqrestore(&vop->irq_lock, flags);
28007 + struct drm_device *drm = crtc->dev;
28012 + spin_lock_irqsave(&drm->event_lock, flags);
28013 + e = vop->event;
28014 + if (e && e->base.file_priv == file_priv) {
28015 + vop->event = NULL;
28017 + /* e->base.destroy(&e->base);//todo */
28018 + file_priv->event_space += sizeof(e->event);
28020 + spin_unlock_irqrestore(&drm->event_lock, flags);
28025 + struct rockchip_drm_private *private = crtc->dev->dev_private;
28030 + if (on == vop->loader_protect)
28034 + if (vop->dclk_source) {
28037 + parent = clk_get_parent(vop->dclk_source);
28039 + if (clk_is_match(private->default_pll.pll, parent))
28040 + vop->pll = &private->default_pll;
28041 + else if (clk_is_match(private->hdmi_pll.pll, parent))
28042 + vop->pll = &private->hdmi_pll;
28043 + if (vop->pll)
28044 + vop->pll->use_count++;
28051 + vop->loader_protect = true;
28055 + if (vop->dclk_source && vop->pll) {
28056 + vop->pll->use_count--;
28057 + vop->pll = NULL;
28059 + vop->loader_protect = false;
28076 + struct drm_plane_state *state = plane->state;
28078 + struct drm_rect *src, *dest;
28079 + struct drm_framebuffer *fb = state->fb;
28088 + DEBUG_PRINT(" win%d-%d: %s\n", win->win_id, win->area_id,
28089 + state->crtc ? "ACTIVE" : "DISABLED");
28093 + src = &pstate->src;
28094 + dest = &pstate->dest;
28096 + drm_get_format_name(fb->format->format, &format_name);
28099 + fb->modifier == afbdc_format ? "[AFBC]" : "",
28100 + pstate->eotf ? " HDR" : " SDR", pstate->eotf,
28101 + pstate->color_space);
28103 + pstate->y2r_en, pstate->r2r_en, pstate->r2y_en,
28104 + pstate->csc_mode);
28105 + DEBUG_PRINT("\tzpos: %d\n", pstate->zpos);
28106 + DEBUG_PRINT("\tsrc: pos[%dx%d] rect[%dx%d]\n", src->x1 >> 16,
28107 + src->y1 >> 16, drm_rect_width(src) >> 16,
28108 + drm_rect_height(src) >> 16);
28109 + DEBUG_PRINT("\tdst: pos[%dx%d] rect[%dx%d]\n", dest->x1, dest->y1,
28112 + for (i = 0; i < fb->format->num_planes; i++) {
28113 + obj = fb->obj[0];
28115 + fb_addr = rk_obj->dma_addr + fb->offsets[0];
28118 + i, &fb_addr, fb->pitches[i], fb->offsets[i]);
28129 + drm_connector_list_iter_begin(crtc->dev, &conn_iter);
28131 + if (crtc->state->connector_mask & drm_connector_mask(connector))
28132 + DEBUG_PRINT(" Connector: %s\n", connector->name);
28141 + struct drm_crtc_state *crtc_state = crtc->state;
28142 + struct drm_display_mode *mode = &crtc->state->adjusted_mode;
28143 + struct rockchip_crtc_state *state = to_rockchip_crtc_state(crtc->state);
28144 + bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
28148 + DEBUG_PRINT("VOP [%s]: %s\n", dev_name(vop->dev),
28149 + crtc_state->active ? "ACTIVE" : "DISABLED");
28151 + if (!crtc_state->active)
28155 + DEBUG_PRINT("\tbus_format[%x]: %s\n", state->bus_format,
28156 + drm_get_bus_format_name(state->bus_format));
28158 + state->yuv_overlay, state->output_mode);
28160 + state->color_space);
28162 + mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
28165 + mode->clock, mode->crtc_clock, mode->type, mode->flags);
28166 + DEBUG_PRINT("\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
28167 + mode->hsync_end, mode->htotal);
28168 + DEBUG_PRINT("\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
28169 + mode->vsync_end, mode->vtotal);
28171 + for (i = 0; i < vop->num_wins; i++) {
28172 + plane = &vop->win[i].base;
28176 + state->hdr.sdr2hdr_state.bt1886eotf_post_conv_en,
28177 + state->hdr.hdr2sdr_en);
28179 + state->hdr.sdr2hdr_state.bt1886eotf_pre_conv_en);
28181 + state->post_r2y_en, state->post_y2r_en,
28182 + state->post_csc_mode);
28190 + struct drm_crtc_state *crtc_state = crtc->state;
28191 + int dump_len = vop->len > 0x400 ? 0x400 : vop->len;
28194 + if (!crtc_state->active)
28206 + struct drm_info_node *node = s->private;
28207 + struct vop *vop = node->info_ent->data;
28210 + if (!vop->lut || !vop->lut_active || !vop->lut_regs)
28213 + for (i = 0; i < vop->lut_len; i++) {
28216 + DEBUG_PRINT("0x%08x ", vop->lut[i]);
28234 + vop->debugfs = debugfs_create_dir(dev_name(vop->dev),
28235 + minor->debugfs_root);
28237 + if (!vop->debugfs)
28238 + return -ENOMEM;
28240 + vop->debugfs_files = kmemdup(vop_debugfs_files,
28243 + if (!vop->debugfs_files) {
28244 + ret = -ENOMEM;
28248 + rockchip_drm_add_dump_buffer(crtc, vop->debugfs);
28251 + vop->debugfs_files[i].data = vop;
28253 + drm_debugfs_create_files(vop->debugfs_files, ARRAY_SIZE(vop_debugfs_files),
28254 + vop->debugfs, minor);
28258 + debugfs_remove(vop->debugfs);
28259 + vop->debugfs = NULL;
28267 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
28268 + const struct vop_data *vop_data = vop->data;
28269 + int request_clock = mode->clock;
28272 + if (mode->hdisplay > vop_data->max_output.width)
28275 + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
28276 + VOP_MAJOR(vop->version) == 3 &&
28277 + VOP_MINOR(vop->version) <= 2)
28280 + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
28282 + clock = clk_round_rate(vop->dclk, request_clock * 1000) / 1000;
28287 + if (s->output_type == DRM_MODE_CONNECTOR_HDMIA ||
28288 + s->output_type == DRM_MODE_CONNECTOR_DisplayPort)
28306 + return pa->y1 - pb->y2;
28312 + struct vop_win *win = to_vop_win(pstate->plane);
28313 + struct drm_crtc *crtc = pstate->crtc;
28315 + struct drm_framebuffer *fb = pstate->fb;
28316 + struct drm_rect *dest = &vop_plane_state->dest;
28317 + struct drm_rect *src = &vop_plane_state->src;
28318 + int bpp = fb->format->cpp[0] << 3;
28319 + int src_width = drm_rect_width(src) >> 16;
28320 + int src_height = drm_rect_height(src) >> 16;
28369 + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
28370 + u16 htotal = adjusted_mode->crtc_htotal;
28371 + u16 vdisplay = adjusted_mode->crtc_vdisplay;
28372 + int clock = adjusted_mode->crtc_clock;
28379 + struct drm_atomic_state *state = crtc_state->state;
28389 + if (!vop->rockchip_crtc.vop_dump_list_init_flag) {
28390 + INIT_LIST_HEAD(&vop->rockchip_crtc.vop_dump_list_head);
28391 + vop->rockchip_crtc.vop_dump_list_init_flag = true;
28393 + list_for_each_entry_safe(pos, n, &vop->rockchip_crtc.vop_dump_list_head, entry) {
28394 + list_del(&pos->entry);
28396 + if (vop->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
28397 + vop->rockchip_crtc.vop_dump_times > 0) {
28398 + vop->rockchip_crtc.frame_count++;
28405 + vop_bw_info->plane_num += plane_num;
28409 + return -ENOMEM;
28415 + if (pstate->crtc != crtc || !pstate->fb)
28419 + afbc_fac = rockchip_afbc(plane, pstate->fb->modifier) ? 2 : 1;
28422 + pbandwidth[cnt].y1 = vop_plane_state->dest.y1;
28423 + pbandwidth[cnt].y2 = vop_plane_state->dest.y2;
28426 + act_w = drm_rect_width(&pstate->src) >> 16;
28427 + act_h = drm_rect_height(&pstate->src) >> 16;
28428 + cpp = pstate->fb->format->cpp[0];
28430 + vop_bw_info->frame_bw_mbyte += act_w * act_h / 1000 * cpp * drm_mode_vrefresh(adjusted_mode) / 1…
28436 + vop_bw_info->line_bw_mbyte = vop_calc_max_bandwidth(pbandwidth, 0, cnt, vdisplay);
28445 + vop_bw_info->line_bw_mbyte = line_bw_mbyte;
28447 + return vop_bw_info->line_bw_mbyte;
28457 + mutex_lock(&vop->vop_lock);
28458 + if (!vop->is_enabled) {
28459 + mutex_unlock(&vop->vop_lock);
28464 + mutex_unlock(&vop->vop_lock);
28482 + dev_err(vop->dev, "wait mode 0x%x timeout\n", mode);
28495 + state = to_rockchip_crtc_state(crtc->state);
28502 + mutex_lock(&vop->vop_lock);
28503 + if (vop && vop->is_enabled) {
28521 + mutex_unlock(&vop->vop_lock);
28527 + vop_set_out_mode(vop, state->output_mode);
28536 + if (!vop->is_enabled)
28537 + return -ENODEV;
28539 + mutex_lock(&vop->vop_lock);
28542 + ret = -EBUSY;
28546 + reinit_completion(&vop->line_flag_completion);
28549 + jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
28554 + DRM_DEV_ERROR(vop->dev, "timeout waiting for lineflag IRQ\n");
28555 + ret = -ETIMEDOUT;
28560 + mutex_unlock(&vop->vop_lock);
28581 + const struct vop_data *vop_data = vop->data;
28583 + if (mode->hdisplay > vop_data->max_output.width)
28589 + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
28590 + adj_mode->crtc_clock *= 2;
28592 + adj_mode->crtc_clock =
28593 + DIV_ROUND_UP(clk_round_rate(vop->dclk, adj_mode->crtc_clock * 1000),
28602 + to_rockchip_crtc_state(crtc->state);
28610 + if (vop->mcu_timing.mcu_pix_total)
28613 + switch (s->bus_format) {
28646 + s->output_mode == ROCKCHIP_OUT_MODE_AAAA ? 0 : 1);
28653 + to_rockchip_crtc_state(crtc->state);
28657 + if ((s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
28658 + !(vop->data->feature & VOP_FEATURE_OUTPUT_10BIT)) ||
28659 + (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) >= 12 &&
28660 + s->output_if & VOP_OUTPUT_IF_BT656))
28661 + s->output_mode = ROCKCHIP_OUT_MODE_P888;
28663 + if (is_uv_swap(s->bus_format, s->output_mode))
28668 + VOP_CTRL_SET(vop, out_mode, s->output_mode);
28672 + s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0);
28674 + s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0);
28676 + VOP_CTRL_SET(vop, overlay_mode, s->yuv_overlay);
28677 + VOP_CTRL_SET(vop, dsp_out_yuv, is_yuv_output(s->bus_format));
28682 + if (!is_yuv_output(s->bus_format))
28684 + else if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) == 8 &&
28685 + s->hdr.pre_overlay)
28687 + else if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 5)
28700 + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
28701 + u16 hsync_len = adjusted_mode->crtc_hsync_end -
28702 + adjusted_mode->crtc_hsync_start;
28703 + u16 hdisplay = adjusted_mode->crtc_hdisplay;
28704 + u16 htotal = adjusted_mode->crtc_htotal;
28705 + u16 hact_st = adjusted_mode->crtc_htotal -
28706 + adjusted_mode->crtc_hsync_start;
28708 + u16 vdisplay = adjusted_mode->crtc_vdisplay;
28709 + u16 vtotal = adjusted_mode->crtc_vtotal;
28710 + u16 vsync_len = adjusted_mode->crtc_vsync_end -
28711 + adjusted_mode->crtc_vsync_start;
28712 + u16 vact_st = adjusted_mode->crtc_vtotal -
28713 + adjusted_mode->crtc_vsync_start;
28719 + u32 crtc_clock = adjusted_mode->crtc_clock * 100;
28725 + crtc_clock != clk_get_rate(vop->dclk))
28739 + VOP_CTRL_SET(vop, mcu_pix_total, vop->mcu_timing.mcu_pix_total);
28740 + VOP_CTRL_SET(vop, mcu_cs_pst, vop->mcu_timing.mcu_cs_pst);
28741 + VOP_CTRL_SET(vop, mcu_cs_pend, vop->mcu_timing.mcu_cs_pend);
28742 + VOP_CTRL_SET(vop, mcu_rw_pst, vop->mcu_timing.mcu_rw_pst);
28743 + VOP_CTRL_SET(vop, mcu_rw_pend, vop->mcu_timing.mcu_rw_pend);
28750 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
28751 + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
28752 + u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
28753 + u16 hdisplay = adjusted_mode->crtc_hdisplay;
28754 + u16 htotal = adjusted_mode->crtc_htotal;
28755 + u16 hact_st = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_start;
28757 + u16 vdisplay = adjusted_mode->crtc_vdisplay;
28758 + u16 vtotal = adjusted_mode->crtc_vtotal;
28759 + u16 vsync_len = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
28760 + u16 vact_st = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
28766 + bool interlaced = !!(adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE);
28770 + if (old_state && old_state->self_refresh_active) {
28772 + if (vop->aclk_rate_reset)
28773 + clk_set_rate(vop->aclk, vop->aclk_rate);
28774 + vop->aclk_rate_reset = false;
28781 + DRM_DEV_INFO(vop->dev, "Update mode to %dx%d%s%d, type: %d\n",
28783 + drm_mode_vrefresh(adjusted_mode), s->output_type);
28787 + s->mode_update = vop_crtc_mode_update(crtc);
28788 + if (s->mode_update)
28793 + if (vop->lut_active)
28796 + if (vop->mcu_timing.mcu_pix_total)
28799 + dclk_inv = (s->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
28802 + val = (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ?
28804 + val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ?
28808 + if (vop->dclk_source && vop->pll && vop->pll->pll) {
28809 + if (clk_set_parent(vop->dclk_source, vop->pll->pll))
28810 + DRM_DEV_ERROR(vop->dev,
28814 + switch (s->output_type) {
28824 + if (s->output_if & VOP_OUTPUT_IF_BT1120) {
28826 + yc_swap = is_yc_swap(s->bus_format);
28829 + } else if (s->output_if & VOP_OUTPUT_IF_BT656) {
28848 + !!(s->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE));
28850 + !!(s->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) ||
28851 + vop->dual_channel_swap);
28873 + DRM_ERROR("unsupported connector_type[%d]\n", s->output_type);
28887 + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
28907 + if (VOP_MAJOR(vop->version) == 3 &&
28908 + (VOP_MINOR(vop->version) == 2 || VOP_MINOR(vop->version) == 8))
28912 + act_end - us_to_vertical_line(adjusted_mode, for_ddr_freq));
28917 + !!(adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) ||
28918 + s->output_if & VOP_OUTPUT_IF_BT656);
28922 + clk_set_rate(vop->dclk, adjusted_mode->crtc_clock * 1000);
28936 + return pa->zpos - pb->zpos;
28944 + struct drm_atomic_state *state = crtc_state->state;
28949 + struct drm_rect *src;
28953 + s->afbdc_en = 0;
28962 + pstate = plane->state;
28964 + fb = pstate->fb;
28966 + if (pstate->crtc != crtc || !fb)
28968 + if (fb->modifier !=
28974 + return -EINVAL;
28979 + switch (plane_state->format) {
28990 + return -EINVAL;
28993 + if (s->afbdc_en) {
28995 + return -EINVAL;
28999 + src = &plane_state->src;
29000 + if (!(win->feature & WIN_FEATURE_AFBDC)) {
29002 + win->win_id, win->feature);
29003 + return -EINVAL;
29005 + if (!IS_ALIGNED(fb->width, 16)) {
29007 + win->win_id, fb->width);
29008 + return -EINVAL;
29017 + obj = fb->obj[0];
29019 + fb_addr = rk_obj->dma_addr + fb->offsets[0];
29021 + s->afbdc_win_format = afbdc_format;
29022 + s->afbdc_win_id = win->win_id;
29023 + s->afbdc_win_ptr = fb_addr;
29024 + s->afbdc_win_vir_width = fb->width;
29025 + s->afbdc_win_xoffset = (src->x1 >> 16);
29026 + s->afbdc_win_yoffset = (src->y1 >> 16);
29028 + align_x1 = (src->x1 >> 16) - ((src->x1 >> 16) % 16);
29029 + align_y1 = (src->y1 >> 16) - ((src->y1 >> 16) % 16);
29031 + align_val = (src->x2 >> 16) % 16;
29033 + align_x2 = (src->x2 >> 16) + (16 - align_val);
29035 + align_x2 = src->x2 >> 16;
29037 + align_val = (src->y2 >> 16) % 16;
29039 + align_y2 = (src->y2 >> 16) + (16 - align_val);
29041 + align_y2 = src->y2 >> 16;
29043 + s->afbdc_win_width = align_x2 - align_x1 - 1;
29044 + s->afbdc_win_height = align_y2 - align_y1 - 1;
29046 + s->afbdc_en = 1;
29050 + if (src->x1 || src->y1 || fb->offsets[0]) {
29052 + win->win_id);
29054 + src->x1, src->y1, fb->offsets[0]);
29055 + return -EINVAL;
29057 + s->afbdc_win_format = afbdc_format;
29058 + s->afbdc_win_width = fb->width - 1;
29059 + s->afbdc_win_height = (drm_rect_height(src) >> 16) - 1;
29060 + s->afbdc_win_id = win->win_id;
29061 + s->afbdc_win_ptr = plane_state->yrgb_mst;
29062 + s->afbdc_en = 1;
29071 + struct rockchip_drm_private *private = crtc->dev->dev_private;
29073 + struct rockchip_crtc_state *old_s = to_rockchip_crtc_state(crtc->state);
29075 + struct rockchip_dclk_pll *old_pll = vop->pll;
29077 + if (!vop->dclk_source)
29080 + if (crtc_state->active) {
29081 + WARN_ON(vop->pll && !vop->pll->use_count);
29082 + if (!vop->pll || vop->pll->use_count > 1 ||
29083 + s->output_type != old_s->output_type) {
29084 + if (vop->pll)
29085 + vop->pll->use_count--;
29087 + if (s->output_type != DRM_MODE_CONNECTOR_HDMIA &&
29088 + !private->default_pll.use_count)
29089 + vop->pll = &private->default_pll;
29091 + vop->pll = &private->hdmi_pll;
29093 + vop->pll->use_count++;
29095 + } else if (vop->pll) {
29096 + vop->pll->use_count--;
29097 + vop->pll = NULL;
29099 + if (vop->pll != old_pll)
29100 + crtc_state->mode_changed = true;
29106 + struct drm_atomic_state *state = crtc_state->state;
29109 + const struct vop_data *vop_data = vop->data;
29121 + s->yuv_overlay = 0;
29123 + s->yuv_overlay = is_yuv_output(s->bus_format);
29132 + pzpos = kmalloc_array(vop_data->win_size, sizeof(*pzpos), GFP_KERNEL);
29134 + return -ENOMEM;
29136 - spin_lock_irqsave(&vop->irq_lock, flags);
29137 + for (i = 0; i < vop_data->win_size; i++) {
29138 + const struct vop_win_data *win_data = &vop_data->win[i];
29141 - VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1);
29142 - VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1);
29143 + if (!win_data->phy)
29146 - spin_unlock_irqrestore(&vop->irq_lock, flags);
29147 + for (j = 0; j < vop->num_wins; j++) {
29148 + win = &vop->win[j];
29150 - return 0;
29151 -}
29152 + if (win->win_id == i && !win->area_id)
29155 + if (WARN_ON(j >= vop->num_wins)) {
29156 + ret = -EINVAL;
29160 -static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
29161 -{
29162 - struct vop *vop = to_vop(crtc);
29163 - unsigned long flags;
29164 + plane = &win->base;
29165 + pstate = state->planes[drm_plane_index(plane)].state;
29171 + pstate = plane->state;
29174 - if (WARN_ON(!vop->is_enabled))
29175 - return;
29176 + if (!pstate->visible)
29179 + pzpos[cnt].zpos = plane_state->zpos;
29180 + pzpos[cnt++].win_id = win->win_id;
29183 - spin_lock_irqsave(&vop->irq_lock, flags);
29186 - VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0);
29187 + for (i = 0, cnt = 0; i < vop_data->win_size; i++) {
29188 + const struct vop_win_data *win_data = &vop_data->win[i];
29191 - spin_unlock_irqrestore(&vop->irq_lock, flags);
29192 -}
29193 + if (win_data->phy) {
29196 -static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
29197 - const struct drm_display_mode *mode,
29198 - struct drm_display_mode *adjusted_mode)
29199 -{
29200 - struct vop *vop = to_vop(crtc);
29201 - unsigned long rate;
29202 + dsp_layer_sel |= zpos->win_id << shift;
29208 - /*
29209 - * Clock craziness.
29210 - *
29211 - * Key points:
29212 - *
29213 - * - DRM works in in kHz.
29214 - * - Clock framework works in Hz.
29215 - * - Rockchip's clock driver picks the clock rate that is the
29216 - * same _OR LOWER_ than the one requested.
29217 - *
29218 - * Action plan:
29219 - *
29220 - * 1. When DRM gives us a mode, we should add 999 Hz to it. That way
29221 - * if the clock we need is 60000001 Hz (~60 MHz) and DRM tells us to
29222 - * make 60000 kHz then the clock framework will actually give us
29223 - * the right clock.
29224 - *
29225 - * NOTE: if the PLL (maybe through a divider) could actually make
29226 - * a clock rate 999 Hz higher instead of the one we want then this
29227 - * could be a problem. Unfortunately there's not much we can do
29228 - * since it's baked into DRM to use kHz. It shouldn't matter in
29229 - * practice since Rockchip PLLs are controlled by tables and
29230 - * even if there is a divider in the middle I wouldn't expect PLL
29231 - * rates in the table that are just a few kHz different.
29232 - *
29233 - * 2. Get the clock framework to round the rate for us to tell us
29234 - * what it will actually make.
29235 - *
29236 - * 3. Store the rounded up rate so that we don't need to worry about
29237 - * this in the actual clk_set_rate().
29238 - */
29239 - rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
29240 - adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
29241 + s->dsp_layer_sel = dsp_layer_sel;
29243 - return true;
29251 -static bool vop_dsp_lut_is_enabled(struct vop *vop)
29254 - return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en);
29256 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
29257 + struct drm_display_mode *mode = &crtc->state->adjusted_mode;
29258 + u16 vtotal = mode->crtc_vtotal;
29259 + u16 hdisplay = mode->crtc_hdisplay;
29260 + u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
29261 + u16 vdisplay = mode->crtc_vdisplay;
29262 + u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
29263 + u16 hsize = hdisplay * (s->left_margin + s->right_margin) / 200;
29264 + u16 vsize = vdisplay * (s->top_margin + s->bottom_margin) / 200;
29268 + if (mode->flags & DRM_MODE_FLAG_INTERLACE)
29271 + hact_st += hdisplay * (100 - s->left_margin) / 200;
29276 + vact_st += vdisplay * (100 - s->top_margin) / 200;
29290 + if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
29299 -static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc)
29303 - struct drm_color_lut *lut = crtc->state->gamma_lut->data;
29304 - unsigned int i;
29306 + to_rockchip_crtc_state(crtc->state);
29308 + struct rockchip_sdr2hdr_state *sdr2hdr_state = &s->hdr.sdr2hdr_state;
29310 - for (i = 0; i < crtc->gamma_size; i++) {
29311 - u32 word;
29312 + if (!vop->data->hdr_table)
29315 - word = (drm_color_lut_extract(lut[i].red, 10) << 20) |
29316 - (drm_color_lut_extract(lut[i].green, 10) << 10) |
29317 - drm_color_lut_extract(lut[i].blue, 10);
29318 - writel(word, vop->lut_regs + i * 4);
29319 + if (s->hdr.hdr2sdr_en) {
29327 + VOP_CTRL_SET(vop, hdr2sdr_en, s->hdr.hdr2sdr_en);
29330 + sdr2hdr_state->bt1886eotf_pre_conv_en);
29332 + sdr2hdr_state->bt1886eotf_post_conv_en);
29335 + sdr2hdr_state->rgb2rgb_pre_conv_en);
29337 + sdr2hdr_state->rgb2rgb_pre_conv_mode);
29339 + sdr2hdr_state->st2084oetf_pre_conv_en);
29342 + sdr2hdr_state->rgb2rgb_post_conv_en);
29344 + sdr2hdr_state->rgb2rgb_post_conv_mode);
29346 + sdr2hdr_state->st2084oetf_post_conv_en);
29348 + if (sdr2hdr_state->bt1886eotf_pre_conv_en ||
29349 + sdr2hdr_state->bt1886eotf_post_conv_en)
29350 + vop_load_sdr2hdr_table(vop, sdr2hdr_state->sdr2hdr_func);
29354 -static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
29355 - struct drm_crtc_state *old_state)
29359 - struct drm_crtc_state *state = crtc->state;
29360 - unsigned int idle;
29361 - int ret;
29363 + to_rockchip_crtc_state(crtc->state);
29368 + const struct vop_data *vop_data = vop->data;
29370 - if (!vop->lut_regs)
29371 + if (!s->tv_state)
29373 - /*
29374 - * To disable gamma (gamma_lut is null) or to write
29375 - * an update to the LUT, clear dsp_lut_en.
29376 - */
29377 - spin_lock(&vop->reg_lock);
29378 - VOP_REG_SET(vop, common, dsp_lut_en, 0);
29379 - vop_cfg_done(vop);
29380 - spin_unlock(&vop->reg_lock);
29383 - * In order to write the LUT to the internal memory,
29384 - * we need to first make sure the dsp_lut_en bit is cleared.
29393 - ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
29394 - idle, !idle, 5, 30 * 1000);
29395 - if (ret) {
29396 - DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
29397 + if (!memcmp(s->tv_state,
29398 + &vop->active_tv_state, sizeof(*s->tv_state)) &&
29399 + s->yuv_overlay == old_s->yuv_overlay && s->mode_update &&
29400 + s->bcsh_en == old_s->bcsh_en && s->bus_format == old_s->bus_format)
29403 + memcpy(&vop->active_tv_state, s->tv_state, sizeof(*s->tv_state));
29405 + s->post_r2y_en = 0;
29406 + s->post_y2r_en = 0;
29407 + s->bcsh_en = 0;
29408 + if (s->tv_state) {
29409 + if (s->tv_state->brightness != 50 ||
29410 + s->tv_state->contrast != 50 ||
29411 + s->tv_state->saturation != 50 || s->tv_state->hue != 50)
29412 + s->bcsh_en = 1;
29415 + if (s->bcsh_en) {
29416 + if (!s->yuv_overlay)
29417 + s->post_r2y_en = 1;
29418 + if (!is_yuv_output(s->bus_format))
29419 + s->post_y2r_en = 1;
29421 + if (!s->yuv_overlay && is_yuv_output(s->bus_format))
29422 + s->post_r2y_en = 1;
29423 + if (s->yuv_overlay && !is_yuv_output(s->bus_format))
29424 + s->post_y2r_en = 1;
29427 - if (!state->gamma_lut)
29428 + s->post_csc_mode = to_vop_csc_mode(s->color_space);
29429 + VOP_CTRL_SET(vop, bcsh_r2y_en, s->post_r2y_en);
29430 + VOP_CTRL_SET(vop, bcsh_y2r_en, s->post_y2r_en);
29431 + VOP_CTRL_SET(vop, bcsh_r2y_csc_mode, s->post_csc_mode);
29432 + VOP_CTRL_SET(vop, bcsh_y2r_csc_mode, s->post_csc_mode);
29433 + if (!s->bcsh_en) {
29434 + VOP_CTRL_SET(vop, bcsh_en, s->bcsh_en);
29438 - spin_lock(&vop->reg_lock);
29439 - vop_crtc_write_gamma_lut(vop, crtc);
29440 - VOP_REG_SET(vop, common, dsp_lut_en, 1);
29441 - vop_cfg_done(vop);
29442 - spin_unlock(&vop->reg_lock);
29443 -}
29444 + if (vop_data->feature & VOP_FEATURE_OUTPUT_10BIT)
29445 + brightness = interpolate(0, -128, 100, 127, s->tv_state->brightness);
29446 + else if (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 6) /* px30 vopb */
29447 + brightness = interpolate(0, -64, 100, 63, s->tv_state->brightness);
29449 + brightness = interpolate(0, -32, 100, 31, s->tv_state->brightness);
29451 -static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
29452 - struct drm_crtc_state *old_crtc_state)
29453 -{
29454 - struct vop *vop = to_vop(crtc);
29455 + if ((VOP_MAJOR(vop->version) == 3) ||
29456 + (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 6)) { /* px30 vopb */
29457 + contrast = interpolate(0, 0, 100, 511, s->tv_state->contrast);
29458 + saturation = interpolate(0, 0, 100, 511, s->tv_state->saturation);
29460 + * a:[-30~0]:
29461 + * sin_hue = 0x100 - sin(a)*256;
29467 + hue = interpolate(0, -30, 100, 30, s->tv_state->hue);
29472 - /*
29473 - * Only update GAMMA if the 'active' flag is not changed,
29474 - * otherwise it's updated by .atomic_enable.
29475 - */
29476 - if (crtc->state->color_mgmt_changed &&
29477 - !crtc->state->active_changed)
29478 - vop_crtc_gamma_set(vop, crtc, old_crtc_state);
29480 + contrast = interpolate(0, 0, 100, 255, s->tv_state->contrast);
29481 + saturation = interpolate(0, 0, 100, 255, s->tv_state->saturation);
29483 + * a:[-30~0]:
29484 + * sin_hue = 0x100 - sin(a)*128;
29490 + hue = interpolate(0, -30, 100, 30, s->tv_state->hue);
29501 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) == 0)
29503 + VOP_CTRL_SET(vop, bcsh_en, s->bcsh_en);
29506 -static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
29507 - struct drm_crtc_state *old_state)
29512 + to_rockchip_crtc_state(crtc->state);
29514 const struct vop_data *vop_data = vop->data;
29515 - struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
29516 - struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
29517 - u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
29518 - u16 hdisplay = adjusted_mode->hdisplay;
29519 - u16 htotal = adjusted_mode->htotal;
29520 - u16 hact_st = adjusted_mode->htotal - adjusted_mode->hsync_start;
29521 - u16 hact_end = hact_st + hdisplay;
29522 - u16 vdisplay = adjusted_mode->vdisplay;
29523 - u16 vtotal = adjusted_mode->vtotal;
29524 - u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
29525 - u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
29526 - u16 vact_end = vact_st + vdisplay;
29527 - uint32_t pin_pol, val;
29528 - int dither_bpc = s->output_bpc ? s->output_bpc : 10;
29529 - int ret;
29530 -
29531 - if (old_state && old_state->self_refresh_active) {
29532 - drm_crtc_vblank_on(crtc);
29533 - rockchip_drm_set_win_enabled(crtc, true);
29534 - return;
29535 - }
29536 -
29537 - /*
29538 - * If we have a GAMMA LUT in the state, then let's make sure
29539 - * it's updated. We might be coming out of suspend,
29540 - * which means the LUT internal memory needs to be re-written.
29541 - */
29542 - if (crtc->state->gamma_lut)
29543 - vop_crtc_gamma_set(vop, crtc, old_state);
29544 -
29545 - mutex_lock(&vop->vop_lock);
29547 - WARN_ON(vop->event);
29548 + spin_lock(&vop->reg_lock);
29550 - ret = vop_enable(crtc, old_state);
29551 - if (ret) {
29552 - mutex_unlock(&vop->vop_lock);
29553 - DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
29554 - return;
29555 - }
29556 - pin_pol = (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ?
29557 - BIT(HSYNC_POSITIVE) : 0;
29558 - pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
29559 - BIT(VSYNC_POSITIVE) : 0;
29560 - VOP_REG_SET(vop, output, pin_pol, pin_pol);
29561 - VOP_REG_SET(vop, output, mipi_dual_channel_en, 0);
29564 - switch (s->output_type) {
29565 - case DRM_MODE_CONNECTOR_LVDS:
29566 - VOP_REG_SET(vop, output, rgb_dclk_pol, 1);
29567 - VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
29568 - VOP_REG_SET(vop, output, rgb_en, 1);
29569 - break;
29570 - case DRM_MODE_CONNECTOR_eDP:
29571 - VOP_REG_SET(vop, output, edp_dclk_pol, 1);
29572 - VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
29573 - VOP_REG_SET(vop, output, edp_en, 1);
29574 - break;
29575 - case DRM_MODE_CONNECTOR_HDMIA:
29576 - VOP_REG_SET(vop, output, hdmi_dclk_pol, 1);
29577 - VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
29578 - VOP_REG_SET(vop, output, hdmi_en, 1);
29579 - break;
29580 - case DRM_MODE_CONNECTOR_DSI:
29581 - VOP_REG_SET(vop, output, mipi_dclk_pol, 1);
29582 - VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
29583 - VOP_REG_SET(vop, output, mipi_en, 1);
29584 - VOP_REG_SET(vop, output, mipi_dual_channel_en,
29585 - !!(s->output_flags & ROCKCHIP_OUTPUT_DSI_DUAL));
29586 - break;
29587 - case DRM_MODE_CONNECTOR_DisplayPort:
29588 - VOP_REG_SET(vop, output, dp_dclk_pol, 0);
29589 - VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
29590 - VOP_REG_SET(vop, output, dp_en, 1);
29591 - break;
29592 - default:
29593 - DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
29594 - s->output_type);
29595 - }
29598 - /*
29599 - * if vop is not support RGB10 output, need force RGB10 to RGB888.
29600 - */
29601 - if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
29602 - !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
29603 - s->output_mode = ROCKCHIP_OUT_MODE_P888;
29604 + if (s->afbdc_en) {
29607 - if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8)
29608 - VOP_REG_SET(vop, common, pre_dither_down, 1);
29609 - else
29610 - VOP_REG_SET(vop, common, pre_dither_down, 0);
29611 + VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4);
29613 + VOP_CTRL_SET(vop, afbdc_sel, s->afbdc_win_id);
29614 + VOP_CTRL_SET(vop, afbdc_hdr_ptr, s->afbdc_win_ptr);
29615 + pic_size = (s->afbdc_win_width & 0xffff);
29616 + pic_size |= s->afbdc_win_height << 16;
29619 - if (dither_bpc == 6) {
29620 - VOP_REG_SET(vop, common, dither_down_sel, DITHER_DOWN_ALLEGRO);
29621 - VOP_REG_SET(vop, common, dither_down_mode, RGB888_TO_RGB666);
29622 - VOP_REG_SET(vop, common, dither_down_en, 1);
29623 - } else {
29624 - VOP_REG_SET(vop, common, dither_down_en, 0);
29625 + VOP_CTRL_SET(vop, afbdc_pic_vir_width, s->afbdc_win_vir_width);
29626 + pic_offset = (s->afbdc_win_xoffset & 0xffff);
29627 + pic_offset |= s->afbdc_win_yoffset << 16;
29631 - VOP_REG_SET(vop, common, out_mode, s->output_mode);
29632 + VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
29634 - VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
29635 - val = hact_st << 16;
29636 - val |= hact_end;
29637 - VOP_REG_SET(vop, modeset, hact_st_end, val);
29638 - VOP_REG_SET(vop, modeset, hpost_st_end, val);
29639 -
29640 - VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
29641 - val = vact_st << 16;
29642 - val |= vact_end;
29643 - VOP_REG_SET(vop, modeset, vact_st_end, val);
29644 - VOP_REG_SET(vop, modeset, vpost_st_end, val);
29645 -
29646 - VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
29647 + VOP_CTRL_SET(vop, dsp_layer_sel, s->dsp_layer_sel);
29648 + if (vop_data->feature & VOP_FEATURE_OVERSCAN)
29651 - clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
29652 -
29653 - VOP_REG_SET(vop, common, standby, 0);
29654 - mutex_unlock(&vop->vop_lock);
29655 + spin_unlock(&vop->reg_lock);
29660 - return VOP_INTR_GET_TYPE(vop, status, FS_INTR);
29661 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7)
29668 @@ -1413,72 +3857,66 @@ static void vop_wait_for_irq_handler(struct vop *vop)
29669 synchronize_irq(vop->irq);
29672 -static int vop_crtc_atomic_check(struct drm_crtc *crtc,
29673 - struct drm_crtc_state *crtc_state)
29677 + struct drm_atomic_state *old_state = old_crtc_state->state;
29681 - struct drm_plane_state *plane_state;
29682 - struct rockchip_crtc_state *s;
29683 - int afbc_planes = 0;
29687 + to_rockchip_crtc_state(crtc->state);
29689 - if (vop->lut_regs && crtc_state->color_mgmt_changed &&
29690 - crtc_state->gamma_lut) {
29691 - unsigned int len;
29694 - len = drm_color_lut_size(crtc_state->gamma_lut);
29695 - if (len != crtc->gamma_size) {
29696 - DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
29697 - len, crtc->gamma_size);
29698 - return -EINVAL;
29699 - }
29700 - }
29701 + if (!vop->is_iommu_enabled && vop->is_iommu_needed) {
29704 - drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
29705 - plane_state =
29706 - drm_atomic_get_plane_state(crtc_state->state, plane);
29707 - if (IS_ERR(plane_state)) {
29708 - DRM_DEBUG_KMS("Cannot get plane state for plane %s\n",
29709 - plane->name);
29710 - return PTR_ERR(plane_state);
29711 - }
29712 + if (s->mode_update)
29715 - if (drm_is_afbc(plane_state->fb->modifier))
29716 - ++afbc_planes;
29717 + ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
29719 + vop->is_iommu_enabled = false;
29721 + dev_err(vop->dev, "failed to attach dma mapping, %d\n",
29724 + vop->is_iommu_enabled = true;
29729 - if (afbc_planes > 1) {
29730 - DRM_DEBUG_KMS("Invalid number of AFBC planes; got %d, expected at most 1\n", afbc_planes);
29731 - return -EINVAL;
29733 + if (old_crtc_state->color_mgmt_changed || old_crtc_state->active_changed) {
29734 + if (crtc->state->gamma_lut || vop->gamma_lut) {
29735 + if (old_crtc_state->gamma_lut)
29736 + vop->gamma_lut = old_crtc_state->gamma_lut->data;
29741 - s = to_rockchip_crtc_state(crtc_state);
29742 - s->enable_afbc = afbc_planes > 0;
29743 -
29744 - return 0;
29745 -}
29746 -
29747 -static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
29748 - struct drm_crtc_state *old_crtc_state)
29749 -{
29750 - struct drm_atomic_state *old_state = old_crtc_state->state;
29751 - struct drm_plane_state *old_plane_state, *new_plane_state;
29752 - struct vop *vop = to_vop(crtc);
29753 - struct drm_plane *plane;
29754 - struct rockchip_crtc_state *s;
29755 - int i;
29756 -
29757 - if (WARN_ON(!vop->is_enabled))
29758 - return;
29759 -
29760 - spin_lock(&vop->reg_lock);
29761 -
29762 - /* Enable AFBC if there is some AFBC window, disable otherwise. */
29763 - s = to_rockchip_crtc_state(crtc->state);
29764 - VOP_AFBC_SET(vop, enable, s->enable_afbc);
29765 + spin_lock_irqsave(&vop->irq_lock, flags);
29766 + vop->pre_overlay = s->hdr.pre_overlay;
29769 + * rk322x and rk332x odd-even field will mistake when in interlace mode.
29773 + if (VOP_MAJOR(vop->version) == 3 &&
29774 + (VOP_MINOR(vop->version) == 7 || VOP_MINOR(vop->version) == 8)) {
29775 + if (!s->mode_update && VOP_CTRL_GET(vop, reg_done_frm))
29780 + if (vop->mcu_timing.mcu_pix_total)
29783 - spin_unlock(&vop->reg_lock);
29784 + spin_unlock_irqrestore(&vop->irq_lock, flags);
29788 @@ -1496,13 +3934,11 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
29789 crtc->state->event = NULL;
29791 spin_unlock_irq(&crtc->dev->event_lock);
29792 -
29793 - for_each_oldnew_plane_in_state(old_state, plane, old_plane_state,
29794 - new_plane_state, i) {
29796 if (!old_plane_state->fb)
29799 - if (old_plane_state->fb == new_plane_state->fb)
29800 + if (old_plane_state->fb == plane->state->fb)
29803 drm_framebuffer_get(old_plane_state->fb);
29804 @@ -1514,8 +3950,8 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
29810 - .atomic_begin = vop_crtc_atomic_begin,
29814 @@ -1526,14 +3962,36 @@ static void vop_crtc_destroy(struct drm_crtc *crtc)
29820 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
29822 + if (crtc->state) {
29823 + __drm_atomic_helper_crtc_destroy_state(crtc->state);
29830 + crtc->state = &s->base;
29831 + crtc->state->crtc = crtc;
29833 + s->left_margin = 100;
29834 + s->right_margin = 100;
29835 + s->top_margin = 100;
29836 + s->bottom_margin = 100;
29841 - struct rockchip_crtc_state *rockchip_state;
29844 if (WARN_ON(!crtc->state))
29847 - rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
29848 + old_state = to_rockchip_crtc_state(crtc->state);
29853 @@ -1550,17 +4008,6 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc,
29857 -static void vop_crtc_reset(struct drm_crtc *crtc)
29858 -{
29859 - struct rockchip_crtc_state *crtc_state =
29860 - kzalloc(sizeof(*crtc_state), GFP_KERNEL);
29861 -
29862 - if (crtc->state)
29863 - vop_crtc_destroy_state(crtc, crtc->state);
29864 -
29865 - __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
29866 -}
29867 -
29871 @@ -1626,18 +4073,116 @@ vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
29880 + struct drm_device *drm_dev = crtc->dev;
29881 + struct rockchip_drm_private *private = drm_dev->dev_private;
29882 + struct drm_mode_config *mode_config = &drm_dev->mode_config;
29886 + if (property == mode_config->tv_left_margin_property) {
29887 + *val = s->left_margin;
29891 + if (property == mode_config->tv_right_margin_property) {
29892 + *val = s->right_margin;
29896 + if (property == mode_config->tv_top_margin_property) {
29897 + *val = s->top_margin;
29901 + if (property == mode_config->tv_bottom_margin_property) {
29902 + *val = s->bottom_margin;
29906 + if (property == private->aclk_prop) {
29907 + /* KHZ, keep align with mode->clock */
29908 + *val = clk_get_rate(vop->aclk) / 1000;
29912 + if (property == private->bg_prop) {
29913 + *val = vop->background;
29917 + if (property == private->line_flag_prop) {
29918 + *val = vop->line_flag;
29923 + return -EINVAL;
29931 + struct drm_device *drm_dev = crtc->dev;
29932 + struct rockchip_drm_private *private = drm_dev->dev_private;
29933 + struct drm_mode_config *mode_config = &drm_dev->mode_config;
29937 + if (property == mode_config->tv_left_margin_property) {
29938 + s->left_margin = val;
29942 + if (property == mode_config->tv_right_margin_property) {
29943 + s->right_margin = val;
29947 + if (property == mode_config->tv_top_margin_property) {
29948 + s->top_margin = val;
29952 + if (property == mode_config->tv_bottom_margin_property) {
29953 + s->bottom_margin = val;
29957 + if (property == private->bg_prop) {
29958 + vop->background = val;
29962 + if (property == private->line_flag_prop) {
29963 + vop->line_flag = val;
29968 + return -EINVAL;
29985 - .gamma_set = drm_atomic_helper_legacy_gamma_set,
29989 @@ -1645,22 +4190,23 @@ static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
29993 - drm_crtc_vblank_put(&vop->crtc);
29994 + drm_crtc_vblank_put(&vop->rockchip_crtc.crtc);
30000 struct drm_device *drm = vop->drm_dev;
30001 - struct drm_crtc *crtc = &vop->crtc;
30002 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30005 - spin_lock(&drm->event_lock);
30006 + spin_lock_irqsave(&drm->event_lock, flags);
30007 if (vop->event) {
30008 drm_crtc_send_vblank_event(crtc, vop->event);
30010 vop->event = NULL;
30012 - spin_unlock(&drm->event_lock);
30013 + spin_unlock_irqrestore(&drm->event_lock, flags);
30015 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
30016 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
30017 @@ -1669,8 +4215,9 @@ static void vop_handle_vblank(struct vop *vop)
30021 - struct drm_crtc *crtc = &vop->crtc;
30022 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30028 @@ -1689,14 +4236,14 @@ static irqreturn_t vop_isr(int irq, void *data)
30032 - spin_lock(&vop->irq_lock);
30033 + spin_lock_irqsave(&vop->irq_lock, flags);
30040 - spin_unlock(&vop->irq_lock);
30041 + spin_unlock_irqrestore(&vop->irq_lock, flags);
30045 @@ -1714,17 +4261,41 @@ static irqreturn_t vop_isr(int irq, void *data)
30049 - if (active_irqs & FS_INTR) {
30055 + spin_lock_irqsave(&vop->irq_lock, flags);
30056 + VOP_CTRL_SET(vop, level2_overlay_en, vop->pre_overlay);
30057 + VOP_CTRL_SET(vop, alpha_hard_calc, vop->pre_overlay);
30058 + spin_unlock_irqrestore(&vop->irq_lock, flags);
30061 - active_irqs &= ~FS_INTR;
30069 + DRM_DEV_ERROR_RATELIMITED(vop->dev, #x " irq err\n"); \
30085 - DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n",
30086 - active_irqs);
30091 @@ -1733,27 +4304,254 @@ static irqreturn_t vop_isr(int irq, void *data)
30095 -static void vop_plane_add_properties(struct drm_plane *plane,
30096 - const struct vop_win_data *win_data)
30103 - flags |= VOP_WIN_HAS_REG(win_data, x_mir_en) ? DRM_MODE_REFLECT_X : 0;
30104 - flags |= VOP_WIN_HAS_REG(win_data, y_mir_en) ? DRM_MODE_REFLECT_Y : 0;
30113 -static int vop_create_crtc(struct vop *vop)
30116 + struct drm_prop_enum_list *props = vop->plane_name_list;
30118 + uint64_t bits = BIT_ULL(win->plane_id);
30120 + prop = drm_property_create_bitmask(vop->drm_dev,
30122 + props, vop->num_wins, bits);
30124 + DRM_DEV_ERROR(vop->dev, "create Name prop for %s failed\n", win->name);
30125 + return -ENOMEM;
30127 + win->name_prop = prop;
30128 + drm_object_attach_property(&win->base.base, win->name_prop, bits);
30136 + struct rockchip_drm_private *private = vop->drm_dev->dev_private;
30139 + const struct vop_data *vop_data = vop->data;
30143 + ret = drm_universal_plane_init(vop->drm_dev, &win->base, possible_crtcs, &vop_plane_funcs,
30144 + win->data_formats, win->nformats, win->format_modifiers,
30145 + win->type, win->name);
30150 + drm_plane_helper_add(&win->base, &plane_helper_funcs);
30152 + if (win->phy->scl)
30157 + if (win->feature & WIN_FEATURE_HDR2SDR)
30159 + if (win->feature & WIN_FEATURE_SDR2HDR)
30161 + if (win->feature & WIN_FEATURE_AFBDC)
30164 + drm_object_attach_property(&win->base.base, vop->plane_feature_prop,
30166 + drm_object_attach_property(&win->base.base, private->eotf_prop, 0);
30167 + drm_object_attach_property(&win->base.base,
30168 + private->color_space_prop, 0);
30170 + drm_plane_create_alpha_property(&win->base);
30171 + drm_object_attach_property(&win->base.base,
30172 + private->async_commit_prop, 0);
30174 + if (win->parent)
30175 + drm_object_attach_property(&win->base.base, private->share_id_prop,
30176 + win->parent->base.base.id);
30178 + drm_object_attach_property(&win->base.base, private->share_id_prop,
30179 + win->base.base.id);
30181 + drm_plane_create_blend_mode_property(&win->base, blend_caps);
30182 + drm_plane_create_zpos_property(&win->base, win->win_id, 0, vop->num_wins - 1);
30186 + win->input_width_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30187 + "INPUT_WIDTH", 0, vop_data->max_input.width);
30188 + win->input_height_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30189 + "INPUT_HEIGHT", 0, vop_data->max_input.height);
30191 + win->output_width_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30192 + "OUTPUT_WIDTH", 0, vop_data->max_input.width);
30193 + win->output_height_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30194 + "OUTPUT_HEIGHT", 0, vop_data->max_input.height);
30196 + win->scale_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30203 + win->color_key_prop = drm_property_create_range(vop->drm_dev, 0,
30205 + if (!win->input_width_prop || !win->input_height_prop ||
30206 + !win->scale_prop || !win->color_key_prop) {
30208 + return -ENOMEM;
30211 + drm_object_attach_property(&win->base.base, win->input_width_prop, 0);
30212 + drm_object_attach_property(&win->base.base, win->input_height_prop, 0);
30213 + drm_object_attach_property(&win->base.base, win->output_width_prop, 0);
30214 + drm_object_attach_property(&win->base.base, win->output_height_prop, 0);
30215 + drm_object_attach_property(&win->base.base, win->scale_prop, 0);
30216 + drm_object_attach_property(&win->base.base, win->color_key_prop, 0);
30223 + struct device_node *node = vop->dev->of_node;
30225 + u32 lut_len = vop->lut_len;
30230 + if (!vop->lut)
30231 + return -ENOMEM;
30233 + dsp_lut = of_parse_phandle(node, "dsp-lut", 0);
30235 + return -ENXIO;
30237 + prop = of_find_property(dsp_lut, "gamma-lut", &length);
30239 + dev_err(vop->dev, "failed to find gamma_lut\n");
30240 + return -ENXIO;
30250 + return -ENOMEM;
30251 + ret = of_property_read_u32_array(dsp_lut, "gamma-lut", lut,
30254 + dev_err(vop->dev, "load gamma-lut failed\n");
30256 + return -EINVAL;
30265 + vop->lut[i] = r * lut_len * lut_len + g * lut_len + b;
30270 + of_property_read_u32_array(dsp_lut, "gamma-lut",
30271 + vop->lut, vop->lut_len);
30273 + vop->lut_active = true;
30289 + prop = drm_property_create_bitmask(vop->drm_dev,
30294 + DRM_DEV_ERROR(vop->dev, "create plane_mask prop for vp%d failed\n", vop->id);
30295 + return -ENOMEM;
30298 + vop->plane_mask_prop = prop;
30299 + drm_object_attach_property(&crtc->base, vop->plane_mask_prop, vop->plane_mask);
30306 const struct vop_data *vop_data = vop->data;
30317 + if (vop_data->feature & VOP_FEATURE_ALPHA_SCALE)
30319 + if (vop_data->feature & VOP_FEATURE_HDR10)
30321 + if (vop_data->feature & VOP_FEATURE_NEXT_HDR)
30324 + prop = drm_property_create_bitmask(vop->drm_dev,
30329 + DRM_DEV_ERROR(vop->dev, "create FEATURE prop for vop%d failed\n", vop->id);
30330 + return -ENOMEM;
30333 + vop->feature_prop = prop;
30334 + drm_object_attach_property(&crtc->base, vop->feature_prop, feature);
30341 struct device *dev = vop->dev;
30342 struct drm_device *drm_dev = vop->drm_dev;
30343 + struct rockchip_drm_private *private = drm_dev->dev_private;
30345 - struct drm_crtc *crtc = &vop->crtc;
30346 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30348 - int ret;
30353 @@ -1761,29 +4559,19 @@ static int vop_create_crtc(struct vop *vop)
30357 - for (i = 0; i < vop_data->win_size; i++) {
30358 - struct vop_win *vop_win = &vop->win[i];
30359 - const struct vop_win_data *win_data = vop_win->data;
30360 + for (i = 0; i < vop->num_wins; i++) {
30361 + struct vop_win *win = &vop->win[i];
30363 - if (win_data->type != DRM_PLANE_TYPE_PRIMARY &&
30364 - win_data->type != DRM_PLANE_TYPE_CURSOR)
30365 + if (win->type != DRM_PLANE_TYPE_PRIMARY &&
30366 + win->type != DRM_PLANE_TYPE_CURSOR)
30369 - ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
30370 - 0, &vop_plane_funcs,
30371 - win_data->phy->data_formats,
30372 - win_data->phy->nformats,
30373 - win_data->phy->format_modifiers,
30374 - win_data->type, NULL);
30375 - if (ret) {
30376 - DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
30377 - ret);
30379 + DRM_DEV_ERROR(vop->dev, "failed to init plane\n");
30383 - plane = &vop_win->base;
30384 - drm_plane_helper_add(plane, &plane_helper_funcs);
30385 - vop_plane_add_properties(plane, win_data);
30386 + plane = &win->base;
30387 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
30389 else if (plane->type == DRM_PLANE_TYPE_CURSOR)
30390 @@ -1796,37 +4584,23 @@ static int vop_create_crtc(struct vop *vop)
30394 - if (vop->lut_regs) {
30395 - drm_mode_crtc_set_gamma_size(crtc, vop_data->lut_size);
30396 - drm_crtc_enable_color_mgmt(crtc, 0, false, vop_data->lut_size);
30397 - }
30403 - for (i = 0; i < vop_data->win_size; i++) {
30404 - struct vop_win *vop_win = &vop->win[i];
30405 - const struct vop_win_data *win_data = vop_win->data;
30406 + for (i = 0; i < vop->num_wins; i++) {
30407 + struct vop_win *win = &vop->win[i];
30410 - if (win_data->type != DRM_PLANE_TYPE_OVERLAY)
30411 + if (win->type != DRM_PLANE_TYPE_OVERLAY)
30414 - ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
30415 - possible_crtcs,
30416 - &vop_plane_funcs,
30417 - win_data->phy->data_formats,
30418 - win_data->phy->nformats,
30419 - win_data->phy->format_modifiers,
30420 - win_data->type, NULL);
30421 - if (ret) {
30422 - DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
30423 - ret);
30425 + DRM_DEV_ERROR(vop->dev, "failed to init overlay\n");
30428 - drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
30429 - vop_plane_add_properties(&vop_win->base, win_data);
30430 + vop_plane_add_properties(vop, &win->base, win);
30433 port = of_get_child_by_name(dev->of_node, "port");
30434 @@ -1843,15 +4617,65 @@ static int vop_create_crtc(struct vop *vop)
30435 init_completion(&vop->dsp_hold_completion);
30436 init_completion(&vop->line_flag_completion);
30437 crtc->port = port;
30438 -
30441 + drm_object_attach_property(&crtc->base, private->soc_id_prop, vop->soc_id);
30442 + drm_object_attach_property(&crtc->base, private->port_id_prop, vop->id);
30443 + drm_object_attach_property(&crtc->base, private->aclk_prop, 0);
30444 + drm_object_attach_property(&crtc->base, private->bg_prop, 0);
30445 + drm_object_attach_property(&crtc->base, private->line_flag_prop, 0);
30448 + drm_object_attach_property(&crtc->base, drm_dev->mode_config.prop, v)
30459 DRM_DEV_DEBUG_KMS(vop->dev,
30460 - "Failed to init %s with SR helpers %d, ignoring\n",
30461 - crtc->name, ret);
30463 + crtc->name, ret);
30465 + if (vop->lut_regs) {
30467 + u32 lut_len = vop->lut_len;
30469 + vop->lut = devm_kmalloc_array(dev, lut_len, sizeof(*vop->lut),
30471 + if (!vop->lut)
30480 + vop->lut[i] = r | g | b;
30486 + r_base = crtc->gamma_store;
30487 + g_base = r_base + crtc->gamma_size;
30488 + b_base = g_base + crtc->gamma_size;
30503 @@ -1863,7 +4687,7 @@ static int vop_create_crtc(struct vop *vop)
30507 - struct drm_crtc *crtc = &vop->crtc;
30508 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30509 struct drm_device *drm_dev = vop->drm_dev;
30512 @@ -1891,187 +4715,130 @@ static void vop_destroy_crtc(struct vop *vop)
30513 drm_flip_work_cleanup(&vop->fb_unref_work);
30516 -static int vop_initial(struct vop *vop)
30526 - struct reset_control *ahb_rst;
30527 - int i, ret;
30528 -
30529 - vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
30530 - if (IS_ERR(vop->hclk)) {
30531 - DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n");
30532 - return PTR_ERR(vop->hclk);
30533 - }
30534 - vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
30535 - if (IS_ERR(vop->aclk)) {
30536 - DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n");
30537 - return PTR_ERR(vop->aclk);
30538 - }
30539 - vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
30540 - if (IS_ERR(vop->dclk)) {
30541 - DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n");
30542 - return PTR_ERR(vop->dclk);
30543 - }
30544 -
30545 - ret = pm_runtime_get_sync(vop->dev);
30546 - if (ret < 0) {
30547 - DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
30548 - return ret;
30549 - }
30550 -
30551 - ret = clk_prepare(vop->dclk);
30552 - if (ret < 0) {
30553 - DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n");
30554 - goto err_put_pm_runtime;
30555 - }
30556 -
30557 - /* Enable both the hclk and aclk to setup the vop */
30558 - ret = clk_prepare_enable(vop->hclk);
30559 - if (ret < 0) {
30560 - DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n");
30561 - goto err_unprepare_dclk;
30562 - }
30563 -
30564 - ret = clk_prepare_enable(vop->aclk);
30565 - if (ret < 0) {
30566 - DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n");
30567 - goto err_disable_hclk;
30568 - }
30569 -
30570 - /*
30571 - * do hclk_reset, reset all vop registers.
30572 - */
30573 - ahb_rst = devm_reset_control_get(vop->dev, "ahb");
30574 - if (IS_ERR(ahb_rst)) {
30575 - DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n");
30576 - ret = PTR_ERR(ahb_rst);
30577 - goto err_disable_aclk;
30578 - }
30579 - reset_control_assert(ahb_rst);
30580 - usleep_range(10, 20);
30581 - reset_control_deassert(ahb_rst);
30582 -
30583 - VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
30584 - VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);
30585 -
30586 - for (i = 0; i < vop->len; i += sizeof(u32))
30587 - vop->regsbak[i / 4] = readl_relaxed(vop->regs + i);
30588 -
30589 - VOP_REG_SET(vop, misc, global_regdone_en, 1);
30590 - VOP_REG_SET(vop, common, dsp_blank, 0);
30591 -
30592 - for (i = 0; i < vop->data->win_size; i++) {
30593 - struct vop_win *vop_win = &vop->win[i];
30594 - const struct vop_win_data *win = vop_win->data;
30595 - int channel = i * 2 + 1;
30596 -
30597 - VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
30598 - vop_win_disable(vop, vop_win);
30599 - VOP_WIN_SET(vop, win, gate, 1);
30600 - }
30601 -
30602 - vop_cfg_done(vop);
30603 -
30604 - /*
30605 - * do dclk_reset, let all config take affect.
30606 - */
30607 - vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk");
30608 - if (IS_ERR(vop->dclk_rst)) {
30609 - DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n");
30610 - ret = PTR_ERR(vop->dclk_rst);
30611 - goto err_disable_aclk;
30618 + return size - 1;
30620 - reset_control_assert(vop->dclk_rst);
30621 - usleep_range(10, 20);
30622 - reset_control_deassert(vop->dclk_rst);
30623 -
30624 - clk_disable(vop->hclk);
30625 - clk_disable(vop->aclk);
30626 -
30627 - vop->is_enabled = false;
30628 -
30629 - pm_runtime_put_sync(vop->dev);
30630 -
30632 -
30633 -err_disable_aclk:
30634 - clk_disable_unprepare(vop->aclk);
30635 -err_disable_hclk:
30636 - clk_disable_unprepare(vop->hclk);
30637 -err_unprepare_dclk:
30638 - clk_unprepare(vop->dclk);
30639 -err_put_pm_runtime:
30640 - pm_runtime_put_sync(vop->dev);
30641 - return ret;
30645 * Initialize the vop->win array elements.
30647 -static void vop_win_init(struct vop *vop)
30650 const struct vop_data *vop_data = vop->data;
30651 - unsigned int i;
30665 for (i = 0; i < vop_data->win_size; i++) {
30666 - struct vop_win *vop_win = &vop->win[i];
30667 + struct vop_win *vop_win = &vop->win[num_wins];
30668 const struct vop_win_data *win_data = &vop_data->win[i];
30670 - vop_win->data = win_data;
30671 - vop_win->vop = vop;
30672 + if (!win_data->phy)
30675 - if (vop_data->win_yuv2yuv)
30676 - vop_win->yuv2yuv_data = &vop_data->win_yuv2yuv[i];
30677 - }
30678 -}
30679 + vop_win->phy = win_data->phy;
30680 + vop_win->csc = win_data->csc;
30681 + vop_win->offset = win_data->base;
30682 + vop_win->type = win_data->type;
30683 + vop_win->data_formats = win_data->phy->data_formats;
30684 + vop_win->nformats = win_data->phy->nformats;
30685 + vop_win->format_modifiers = win_data->format_modifiers;
30686 + vop_win->feature = win_data->feature;
30687 + vop_win->vop = vop;
30688 + vop_win->win_id = i;
30689 + vop_win->area_id = 0;
30690 + vop_win->plane_id = plane_id++;
30691 + snprintf(name, sizeof(name), "VOP%d-win%d-%d", vop->id, vop_win->win_id, vop_win->area_id);
30692 + vop_win->name = devm_kstrdup(vop->dev, name, GFP_KERNEL);
30693 + vop_win->zpos = vop_plane_get_zpos(win_data->type,
30694 + vop_data->win_size);
30696 -/**
30697 - * rockchip_drm_wait_vact_end
30698 - * @crtc: CRTC to enable line flag
30699 - * @mstimeout: millisecond for timeout
30700 - *
30701 - * Wait for vact_end line flag irq or timeout.
30702 - *
30703 - * Returns:
30704 - * Zero on success, negative errno on failure.
30705 - */
30706 -int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
30707 -{
30708 - struct vop *vop = to_vop(crtc);
30709 - unsigned long jiffies_left;
30710 - int ret = 0;
30713 - if (!crtc || !vop->is_enabled)
30714 - return -ENODEV;
30715 + if (!vop->support_multi_area)
30718 - mutex_lock(&vop->vop_lock);
30719 - if (mstimeout <= 0) {
30720 - ret = -EINVAL;
30721 - goto out;
30722 + for (j = 0; j < win_data->area_size; j++) {
30723 + struct vop_win *vop_area = &vop->win[num_wins];
30724 + const struct vop_win_phy *area = win_data->area[j];
30726 + vop_area->parent = vop_win;
30727 + vop_area->offset = vop_win->offset;
30728 + vop_area->phy = area;
30729 + vop_area->type = DRM_PLANE_TYPE_OVERLAY;
30730 + vop_area->data_formats = vop_win->data_formats;
30731 + vop_area->nformats = vop_win->nformats;
30732 + vop_area->format_modifiers = win_data->format_modifiers;
30733 + vop_area->vop = vop;
30734 + vop_area->win_id = i;
30735 + vop_area->area_id = j + 1;
30736 + vop_area->plane_id = plane_id++;
30737 + snprintf(name, sizeof(name), "VOP%d-win%d-%d", vop->id, vop_area->win_id, vop_area->area_id);
30738 + vop_area->name = devm_kstrdup(vop->dev, name, GFP_KERNEL);
30741 + vop->plane_mask |= BIT(vop_win->win_id);
30744 - if (vop_line_flag_irq_is_enabled(vop)) {
30745 - ret = -EBUSY;
30746 - goto out;
30747 + vop->num_wins = num_wins;
30749 + vop->plane_feature_prop = drm_property_create_bitmask(vop->drm_dev,
30757 + if (!vop->plane_feature_prop) {
30759 + return -EINVAL;
30762 - reinit_completion(&vop->line_flag_completion);
30763 - vop_line_flag_irq_enable(vop);
30764 + plane_name_list = devm_kzalloc(vop->dev,
30765 + vop->num_wins * sizeof(*plane_name_list),
30768 + DRM_DEV_ERROR(vop->dev, "failed to alloc memory for plane_name_list\n");
30769 + return -ENOMEM;
30772 - jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
30773 - msecs_to_jiffies(mstimeout));
30774 - vop_line_flag_irq_disable(vop);
30775 + for (i = 0; i < vop->num_wins; i++) {
30776 + struct vop_win *vop_win = &vop->win[i];
30778 - if (jiffies_left == 0) {
30779 - DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
30780 - ret = -ETIMEDOUT;
30781 - goto out;
30782 + plane_name_list[i].type = vop_win->plane_id;
30783 + plane_name_list[i].name = vop_win->name;
30786 -out:
30787 - mutex_unlock(&vop->vop_lock);
30788 - return ret;
30789 + vop->plane_name_list = plane_name_list;
30793 -EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
30797 @@ -2080,46 +4847,97 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
30801 - int ret, irq;
30810 return -ENODEV;
30812 + for (i = 0; i < vop_data->win_size; i++) {
30813 + const struct vop_win_data *win_data = &vop_data->win[i];
30815 + num_wins += win_data->area_size + 1;
30819 - vop = devm_kzalloc(dev, struct_size(vop, win, vop_data->win_size),
30820 - GFP_KERNEL);
30821 + alloc_size = sizeof(*vop) + sizeof(*vop->win) * num_wins;
30824 return -ENOMEM;
30826 vop->dev = dev;
30827 vop->data = vop_data;
30828 vop->drm_dev = drm_dev;
30829 + vop->num_wins = num_wins;
30830 + vop->version = vop_data->version;
30831 + vop->soc_id = vop_data->soc_id;
30832 + vop->id = vop_data->vop_id;
30834 + vop->support_multi_area = of_property_read_bool(dev->of_node, "support-multi-area");
30836 - vop_win_init(vop);
30841 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
30844 + dev_warn(vop->dev, "failed to get vop register byname\n");
30847 vop->regs = devm_ioremap_resource(dev, res);
30848 if (IS_ERR(vop->regs))
30849 return PTR_ERR(vop->regs);
30850 vop->len = resource_size(res);
30852 - res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
30853 + vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
30854 + if (!vop->regsbak)
30855 + return -ENOMEM;
30859 - if (!vop_data->lut_size) {
30860 - DRM_DEV_ERROR(dev, "no gamma LUT size defined\n");
30861 + vop->lut_len = resource_size(res) / sizeof(*vop->lut);
30862 + if (vop->lut_len != 256 && vop->lut_len != 1024) {
30863 + dev_err(vop->dev, "unsupported lut sizes %d\n",
30864 + vop->lut_len);
30865 return -EINVAL;
30868 vop->lut_regs = devm_ioremap_resource(dev, res);
30869 if (IS_ERR(vop->lut_regs))
30870 return PTR_ERR(vop->lut_regs);
30872 -
30873 - vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
30874 - if (!vop->regsbak)
30875 - return -ENOMEM;
30876 -
30877 + vop->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
30879 + if (IS_ERR(vop->grf))
30881 + vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
30882 + if (IS_ERR(vop->hclk)) {
30883 + dev_err(vop->dev, "failed to get hclk source\n");
30884 + return PTR_ERR(vop->hclk);
30886 + vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
30887 + if (IS_ERR(vop->aclk)) {
30888 + dev_err(vop->dev, "failed to get aclk source\n");
30889 + return PTR_ERR(vop->aclk);
30891 + vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
30892 + if (IS_ERR(vop->dclk)) {
30893 + dev_err(vop->dev, "failed to get dclk source\n");
30894 + return PTR_ERR(vop->dclk);
30896 + vop->dclk_source = devm_clk_get(vop->dev, "dclk_source");
30897 + if (PTR_ERR(vop->dclk_source) == -ENOENT) {
30898 + vop->dclk_source = NULL;
30899 + } else if (PTR_ERR(vop->dclk_source) == -EPROBE_DEFER) {
30900 + return -EPROBE_DEFER;
30901 + } else if (IS_ERR(vop->dclk_source)) {
30902 + dev_err(vop->dev, "failed to get dclk source parent\n");
30903 + return PTR_ERR(vop->dclk_source);
30908 @@ -2131,53 +4949,51 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
30909 spin_lock_init(&vop->irq_lock);
30910 mutex_init(&vop->vop_lock);
30912 + ret = devm_request_irq(dev, vop->irq, vop_isr,
30920 pm_runtime_enable(&pdev->dev);
30922 - ret = vop_initial(vop);
30923 - if (ret < 0) {
30924 - DRM_DEV_ERROR(&pdev->dev,
30925 - "cannot initial vop dev - err %d\n", ret);
30926 - goto err_disable_pm_runtime;
30927 - }
30928 -
30929 - ret = devm_request_irq(dev, vop->irq, vop_isr,
30930 - IRQF_SHARED, dev_name(dev), vop);
30931 - if (ret)
30932 - goto err_disable_pm_runtime;
30934 - if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) {
30935 - vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev);
30936 - if (IS_ERR(vop->rgb)) {
30937 - ret = PTR_ERR(vop->rgb);
30938 - goto err_disable_pm_runtime;
30939 - }
30940 + mcu = of_get_child_by_name(dev->of_node, "mcu-timing");
30942 + dev_dbg(dev, "no mcu-timing node found in %s\n",
30943 + dev->of_node->full_name);
30947 + if (!of_property_read_u32(mcu, "mcu-pix-total", &val))
30948 + vop->mcu_timing.mcu_pix_total = val;
30949 + if (!of_property_read_u32(mcu, "mcu-cs-pst", &val))
30950 + vop->mcu_timing.mcu_cs_pst = val;
30951 + if (!of_property_read_u32(mcu, "mcu-cs-pend", &val))
30952 + vop->mcu_timing.mcu_cs_pend = val;
30953 + if (!of_property_read_u32(mcu, "mcu-rw-pst", &val))
30954 + vop->mcu_timing.mcu_rw_pst = val;
30955 + if (!of_property_read_u32(mcu, "mcu-rw-pend", &val))
30956 + vop->mcu_timing.mcu_rw_pend = val;
30957 + if (!of_property_read_u32(mcu, "mcu-hold-mode", &val))
30958 + vop->mcu_timing.mcu_hold_mode = val;
30961 - return 0;
30962 + dual_channel_swap = of_property_read_bool(dev->of_node,
30963 + "rockchip,dual-channel-swap");
30964 + vop->dual_channel_swap = dual_channel_swap;
30966 -err_disable_pm_runtime:
30967 - pm_runtime_disable(&pdev->dev);
30968 - vop_destroy_crtc(vop);
30969 - return ret;
30977 - if (vop->rgb)
30978 - rockchip_rgb_fini(vop->rgb);
30979 -
30982 -
30983 - clk_unprepare(vop->aclk);
30984 - clk_unprepare(vop->hclk);
30985 - clk_unprepare(vop->dclk);
30989 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vo…
30991 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
30993 @@ -7,6 +7,9 @@
31003 @@ -15,104 +18,343 @@
31007 -#define NUM_YUV2YUV_COEFFICIENTS 12
31011 -/* AFBC supports a number of configurable modes. Relevant to us is block size
31012 - * (16x16 or 32x8), storage modifiers (SPARSE, SPLIT), and the YUV-like
31013 - * colourspace transform (YTR). 16x16 SPARSE mode is always used. SPLIT mode
31014 - * could be enabled via the hreg_block_split register, but is not currently
31015 - * handled. The colourspace transform is implicitly always assumed by the
31016 - * decoder, so consumers must use this transform as well.
31017 - *
31018 - * Failure to match modifiers will cause errors displaying AFBC buffers
31019 - * produced by conformant AFBC producers, including Mesa.
31052 + * Cluster1---->Cluster0
31053 + * Esmart1 ---->Esmart0
31054 + * Smart1 ---->Smart0
31070 + ROCKCHIP_VOP_PHY_ID_INVALID = -1,
31112 -#define ROCKCHIP_AFBC_MOD \
31113 - DRM_FORMAT_MOD_ARM_AFBC( \
31114 - AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE \
31115 - | AFBC_FORMAT_MOD_YTR \
31116 - )
31159 - VOP_FMT_RGB565,
31181 - uint16_t offset;
31182 - uint8_t shift;
31183 - bool write_mask;
31184 - bool relaxed;
31194 -struct vop_afbc {
31195 - struct vop_reg enable;
31196 - struct vop_reg win_sel;
31197 - struct vop_reg format;
31198 - struct vop_reg hreg_block_split;
31199 - struct vop_reg pic_size;
31200 - struct vop_reg hdr_ptr;
31201 - struct vop_reg rstn;
31218 -struct vop_modeset {
31227 - struct vop_reg hpost_st_end;
31234 -};
31235 -
31236 -struct vop_output {
31237 - struct vop_reg pin_pol;
31238 - struct vop_reg dp_pin_pol;
31239 - struct vop_reg dp_dclk_pol;
31240 - struct vop_reg edp_pin_pol;
31241 - struct vop_reg edp_dclk_pol;
31242 - struct vop_reg hdmi_pin_pol;
31243 - struct vop_reg hdmi_dclk_pol;
31244 - struct vop_reg mipi_pin_pol;
31245 - struct vop_reg mipi_dclk_pol;
31246 - struct vop_reg rgb_pin_pol;
31247 - struct vop_reg rgb_dclk_pol;
31248 - struct vop_reg dp_en;
31269 - struct vop_reg rgb_en;
31270 -};
31271 -
31272 -struct vop_common {
31273 - struct vop_reg cfg_done;
31274 - struct vop_reg dsp_blank;
31275 - struct vop_reg data_blank;
31276 - struct vop_reg pre_dither_down;
31295 - struct vop_reg dither_up;
31315 - struct vop_reg gate_en;
31316 - struct vop_reg mmu_en;
31319 - struct vop_reg standby;
31320 -};
31322 -struct vop_misc {
31323 - struct vop_reg global_regdone_en;
31404 -
31408 @@ -152,19 +394,129 @@ struct vop_scl_regs {
31412 -struct vop_yuv2yuv_phy {
31413 - struct vop_reg y2r_coefficients[NUM_YUV2YUV_COEFFICIENTS];
31528 - const uint64_t *format_modifiers;
31530 - struct vop_reg enable;
31542 @@ -173,56 +525,615 @@ struct vop_win_phy {
31546 - struct vop_reg y_mir_en;
31547 - struct vop_reg x_mir_en;
31552 - struct vop_reg alpha_pre_mul;
31555 - struct vop_reg channel;
31562 -struct vop_win_yuv2yuv_data {
31565 - const struct vop_yuv2yuv_phy *phy;
31639 -struct vop_win_data {
31843 - const struct vop_win_phy *phy;
31920 + * struct vop2_layer_data - The logic graphic layer in vop2
31924 + * LAYERn-1
31935 + * Each layer can select a unused window as input than feed to
31940 + * win-->layer-->mixer-->vp--->connector(RGB/LVDS/HDMI/MIPI)
31963 - uint32_t version;
31968 - const struct vop_common *common;
31969 - const struct vop_misc *misc;
31970 - const struct vop_modeset *modeset;
31971 - const struct vop_output *output;
31972 - const struct vop_afbc *afbc;
31973 - const struct vop_win_yuv2yuv_data *win_yuv2yuv;
31979 - unsigned int lut_size;
31980 -
31981 -#define VOP_FEATURE_OUTPUT_RGB10 BIT(0)
31982 -#define VOP_FEATURE_INTERNAL_RGB BIT(1)
32144 -#define DSP_HOLD_VALID_INTR (1 << 0)
32145 -#define FS_INTR (1 << 1)
32146 -#define LINE_FLAG_INTR (1 << 2)
32147 -#define BUS_ERROR_INTR (1 << 3)
32170 - LINE_FLAG_INTR | BUS_ERROR_INTR)
32171 -
32183 @@ -256,14 +1167,19 @@ struct vop_data {
32187 -#define ROCKCHIP_OUT_MODE_P888 0
32188 -#define ROCKCHIP_OUT_MODE_P666 1
32189 -#define ROCKCHIP_OUT_MODE_P565 2
32199 -#define ROCKCHIP_OUT_MODE_AAAA 15
32202 -/* output flags */
32203 -#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0)
32209 @@ -292,6 +1208,25 @@ enum factor_mode {
32235 @@ -319,6 +1254,18 @@ enum scale_down_mode {
32254 @@ -332,9 +1279,11 @@ enum dither_down_mode_sel {
32258 - DEN_NEGATIVE = 2
32267 @@ -359,7 +1308,7 @@ static inline uint16_t scl_get_bili_dn_vskip(int src_h, int dst_h,
32271 - act_height = DIV_ROUND_UP(src_h, vskiplines);
32272 + act_height = (src_h + vskiplines - 1) / vskiplines;
32276 @@ -409,5 +1358,16 @@ static inline int scl_vop_cal_lb_mode(int width, bool is_yuv)
32282 + return us * mode->clock / mode->htotal / 1000;
32287 + return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
32293 diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
32295 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
32297 @@ -6,98 +6,141 @@
32298 * Sandy Huang <hjc@rock-chips.com>
32301 -#include <linux/clk.h>
32306 -#include <linux/pinctrl/devinfo.h>
32307 -#include <linux/platform_device.h>
32308 -#include <linux/pm_runtime.h>
32311 -#include <linux/reset.h>
32312 -
32315 -#include <drm/drm_dp_helper.h>
32325 -#include "rockchip_lvds.h"
32327 -#define DISPLAY_OUTPUT_RGB 0
32328 -#define DISPLAY_OUTPUT_LVDS 1
32329 -#define DISPLAY_OUTPUT_DUAL_LVDS 2
32394 -#define connector_to_lvds(c) \
32395 - container_of(c, struct rockchip_lvds, connector)
32396 -
32397 -#define encoder_to_lvds(c) \
32398 - container_of(c, struct rockchip_lvds, encoder)
32399 -
32400 -/**
32401 - * rockchip_lvds_soc_data - rockchip lvds Soc private data
32402 - * @probe: LVDS platform probe function
32403 - * @helper_funcs: LVDS connector helper functions
32404 - */
32405 -struct rockchip_lvds_soc_data {
32406 - int (*probe)(struct platform_device *pdev, struct rockchip_lvds *lvds);
32407 - const struct drm_encoder_helper_funcs *helper_funcs;
32417 - void __iomem *regs;
32420 - struct clk *pclk;
32421 - struct phy *dphy;
32422 - const struct rockchip_lvds_soc_data *soc_data;
32423 - int output; /* rgb lvds or dual lvds output */
32424 - int format; /* vesa or jeida format */
32425 - struct drm_device *drm_dev;
32439 - struct dev_pin_info *pins;
32444 -static inline void rk3288_writel(struct rockchip_lvds *lvds, u32 offset,
32445 - u32 val)
32448 - writel_relaxed(val, lvds->regs + offset);
32449 - if (lvds->output == DISPLAY_OUTPUT_LVDS)
32450 - return;
32451 - writel_relaxed(val, lvds->regs + offset + RK3288_LVDS_CH1_OFFSET);
32455 -static inline int rockchip_lvds_name_to_format(const char *s)
32458 - if (strncmp(s, "jeida-18", 8) == 0)
32459 - return LVDS_JEIDA_18;
32460 - else if (strncmp(s, "jeida-24", 8) == 0)
32461 - return LVDS_JEIDA_24;
32462 - else if (strncmp(s, "vesa-24", 7) == 0)
32463 - return LVDS_VESA_24;
32464 -
32465 - return -EINVAL;
32469 -static inline int rockchip_lvds_name_to_output(const char *s)
32476 - if (strncmp(s, "rgb", 3) == 0)
32477 - return DISPLAY_OUTPUT_RGB;
32478 - else if (strncmp(s, "lvds", 4) == 0)
32479 - return DISPLAY_OUTPUT_LVDS;
32480 - else if (strncmp(s, "duallvds", 8) == 0)
32481 - return DISPLAY_OUTPUT_DUAL_LVDS;
32483 + struct rockchip_drm_private *private = connector->dev->dev_private;
32485 + if (property == private->connector_id_prop) {
32486 + *val = lvds->id;
32491 return -EINVAL;
32494 @@ -107,6 +150,7 @@ static const struct drm_connector_funcs rockchip_lvds_connector_funcs = {
32502 @@ -122,500 +166,235 @@ struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = {
32506 -static int
32507 -rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder,
32508 - struct drm_crtc_state *crtc_state,
32509 - struct drm_connector_state *conn_state)
32510 -{
32511 - struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
32512 -
32513 - s->output_mode = ROCKCHIP_OUT_MODE_P888;
32514 - s->output_type = DRM_MODE_CONNECTOR_LVDS;
32515 -
32516 - return 0;
32517 -}
32518 -
32519 -static int rk3288_lvds_poweron(struct rockchip_lvds *lvds)
32525 - int ret;
32526 - u32 val;
32527 -
32528 - ret = clk_enable(lvds->pclk);
32529 - if (ret < 0) {
32530 - DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
32531 - return ret;
32532 - }
32533 - ret = pm_runtime_get_sync(lvds->dev);
32534 - if (ret < 0) {
32535 - DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
32536 - clk_disable(lvds->pclk);
32537 - return ret;
32538 - }
32539 - val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN |
32540 - RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN |
32541 - RK3288_LVDS_CH0_REG0_LANE0_EN;
32542 - if (lvds->output == DISPLAY_OUTPUT_RGB) {
32543 - val |= RK3288_LVDS_CH0_REG0_TTL_EN |
32544 - RK3288_LVDS_CH0_REG0_LANECK_EN;
32545 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val);
32546 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG2,
32547 - RK3288_LVDS_PLL_FBDIV_REG2(0x46));
32548 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG4,
32549 - RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE |
32550 - RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE |
32551 - RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE |
32552 - RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE |
32553 - RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE |
32554 - RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE);
32555 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG5,
32556 - RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA |
32557 - RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA |
32558 - RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA |
32559 - RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA |
32560 - RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA |
32561 - RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA);
32562 - } else {
32563 - val |= RK3288_LVDS_CH0_REG0_LVDS_EN |
32564 - RK3288_LVDS_CH0_REG0_LANECK_EN;
32565 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val);
32566 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG1,
32567 - RK3288_LVDS_CH0_REG1_LANECK_BIAS |
32568 - RK3288_LVDS_CH0_REG1_LANE4_BIAS |
32569 - RK3288_LVDS_CH0_REG1_LANE3_BIAS |
32570 - RK3288_LVDS_CH0_REG1_LANE2_BIAS |
32571 - RK3288_LVDS_CH0_REG1_LANE1_BIAS |
32572 - RK3288_LVDS_CH0_REG1_LANE0_BIAS);
32573 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG2,
32574 - RK3288_LVDS_CH0_REG2_RESERVE_ON |
32575 - RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE |
32576 - RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE |
32577 - RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE |
32578 - RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE |
32579 - RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE |
32580 - RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE |
32581 - RK3288_LVDS_PLL_FBDIV_REG2(0x46));
32582 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00);
32583 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00);
32585 + struct drm_connector *connector = &lvds->connector;
32586 + struct drm_display_info *info = &connector->display_info;
32589 + if (info->num_bus_formats)
32590 + bus_format = info->bus_formats[0];
32593 + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* jeida-24 */
32594 + lvds->format = LVDS_8BIT_MODE_FORMAT_2;
32596 + case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA: /* jeida-30 */
32597 + lvds->format = LVDS_10BIT_MODE_FORMAT_2;
32599 + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* vesa-18 */
32600 + lvds->format = LVDS_8BIT_MODE_FORMAT_3;
32602 + case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG: /* vesa-30 */
32603 + lvds->format = LVDS_10BIT_MODE_FORMAT_1;
32605 + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* vesa-24 */
32607 + lvds->format = LVDS_8BIT_MODE_FORMAT_1;
32610 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG3,
32611 - RK3288_LVDS_PLL_FBDIV_REG3(0x46));
32612 - rk3288_writel(lvds, RK3288_LVDS_CH0_REGD,
32613 - RK3288_LVDS_PLL_PREDIV_REGD(0x0a));
32614 - rk3288_writel(lvds, RK3288_LVDS_CH0_REG20,
32615 - RK3288_LVDS_CH0_REG20_LSB);
32616 -
32617 - rk3288_writel(lvds, RK3288_LVDS_CFG_REGC,
32618 - RK3288_LVDS_CFG_REGC_PLL_ENABLE);
32619 - rk3288_writel(lvds, RK3288_LVDS_CFG_REG21,
32620 - RK3288_LVDS_CFG_REG21_TX_ENABLE);
32621 -
32622 - return 0;
32623 -}
32625 -static void rk3288_lvds_poweroff(struct rockchip_lvds *lvds)
32626 -{
32627 - int ret;
32628 - u32 val;
32629 + if (lvds->secondary)
32630 + lvds->secondary->format = lvds->format;
32632 - rk3288_writel(lvds, RK3288_LVDS_CFG_REG21,
32633 - RK3288_LVDS_CFG_REG21_TX_ENABLE);
32634 - rk3288_writel(lvds, RK3288_LVDS_CFG_REGC,
32635 - RK3288_LVDS_CFG_REGC_PLL_ENABLE);
32636 - val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN;
32637 - val |= val << 16;
32638 - ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val);
32639 - if (ret != 0)
32640 - DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret);
32641 -
32642 - pm_runtime_put(lvds->dev);
32643 - clk_disable(lvds->pclk);
32644 + drm_mode_copy(&lvds->mode, &crtc_state->adjusted_mode);
32647 -static int rk3288_lvds_grf_config(struct drm_encoder *encoder,
32648 - struct drm_display_mode *mode)
32656 - u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0;
32657 - u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0;
32658 - u32 val;
32659 - int ret;
32660 -
32661 - /* iomux to LCD data/sync mode */
32662 - if (lvds->output == DISPLAY_OUTPUT_RGB)
32663 - if (lvds->pins && !IS_ERR(lvds->pins->default_state))
32664 - pinctrl_select_state(lvds->pins->p,
32665 - lvds->pins->default_state);
32666 - val = lvds->format | LVDS_CH0_EN;
32667 - if (lvds->output == DISPLAY_OUTPUT_RGB)
32668 - val |= LVDS_TTL_EN | LVDS_CH1_EN;
32669 - else if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS)
32670 - val |= LVDS_DUAL | LVDS_CH1_EN;
32671 -
32672 - if ((mode->htotal - mode->hsync_start) & 0x01)
32673 - val |= LVDS_START_PHASE_RST_1;
32674 -
32675 - val |= (pin_dclk << 8) | (pin_hsync << 9);
32676 - val |= (0xffff << 16);
32677 - ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val);
32678 - if (ret)
32679 - DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret);
32680 -
32681 - return ret;
32682 -}
32683 + struct drm_connector *connector = conn_state->connector;
32684 + struct drm_display_info *info = &connector->display_info;
32686 -static int rk3288_lvds_set_vop_source(struct rockchip_lvds *lvds,
32687 - struct drm_encoder *encoder)
32688 -{
32689 - u32 val;
32690 - int ret;
32691 + if (info->num_bus_formats)
32692 + s->bus_format = info->bus_formats[0];
32694 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
32696 - ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder);
32697 - if (ret < 0)
32698 - return ret;
32699 + s->output_mode = ROCKCHIP_OUT_MODE_P888;
32701 - val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16;
32702 - if (ret)
32703 - val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT;
32704 + if (s->bus_format == MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG ||
32705 + s->bus_format == MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA)
32706 + s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
32708 - ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON6, val);
32709 - if (ret < 0)
32710 - return ret;
32711 + s->output_type = DRM_MODE_CONNECTOR_LVDS;
32712 + s->bus_flags = info->bus_flags;
32713 + s->tv_state = &conn_state->tv;
32714 + s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
32715 + s->color_space = V4L2_COLORSPACE_DEFAULT;
32717 + switch (lvds->pixel_order) {
32719 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
32720 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32723 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
32724 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
32725 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32732 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
32733 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32736 + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
32737 + s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
32738 + s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
32742 + if (lvds->id)
32743 + s->output_if |= VOP_OUTPUT_IF_LVDS1;
32745 + s->output_if |= VOP_OUTPUT_IF_LVDS0;
32752 -static void rk3288_lvds_encoder_enable(struct drm_encoder *encoder)
32755 - struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
32756 - struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
32759 - drm_panel_prepare(lvds->panel);
32760 -
32761 - ret = rk3288_lvds_poweron(lvds);
32762 - if (ret < 0) {
32763 - DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret);
32764 - drm_panel_unprepare(lvds->panel);
32765 - return;
32766 - }
32767 -
32768 - ret = rk3288_lvds_grf_config(encoder, mode);
32769 - if (ret) {
32770 - DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret);
32771 - drm_panel_unprepare(lvds->panel);
32772 - return;
32773 - }
32774 + if (lvds->funcs->enable)
32775 + lvds->funcs->enable(lvds);
32777 - ret = rk3288_lvds_set_vop_source(lvds, encoder);
32778 + ret = phy_set_mode(lvds->phy, PHY_MODE_LVDS);
32780 - DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret);
32781 - drm_panel_unprepare(lvds->panel);
32782 + DRM_DEV_ERROR(lvds->dev, "failed to set phy mode: %d\n", ret);
32786 - drm_panel_enable(lvds->panel);
32787 -}
32788 -
32789 -static void rk3288_lvds_encoder_disable(struct drm_encoder *encoder)
32790 -{
32791 - struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
32792 + phy_power_on(lvds->phy);
32794 - drm_panel_disable(lvds->panel);
32795 - rk3288_lvds_poweroff(lvds);
32796 - drm_panel_unprepare(lvds->panel);
32797 + if (lvds->secondary)
32798 + rockchip_lvds_enable(lvds->secondary);
32801 -static int px30_lvds_poweron(struct rockchip_lvds *lvds)
32804 - int ret;
32805 -
32806 - ret = pm_runtime_get_sync(lvds->dev);
32807 - if (ret < 0) {
32808 - DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
32809 - return ret;
32810 - }
32811 -
32812 - /* Enable LVDS mode */
32813 - return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
32814 - PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1),
32815 - PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1));
32816 -}
32817 + if (lvds->funcs->disable)
32818 + lvds->funcs->disable(lvds);
32820 -static void px30_lvds_poweroff(struct rockchip_lvds *lvds)
32821 -{
32822 - regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
32823 - PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1),
32824 - PX30_LVDS_MODE_EN(0) | PX30_LVDS_P2S_EN(0));
32825 + phy_power_off(lvds->phy);
32827 - pm_runtime_put(lvds->dev);
32828 + if (lvds->secondary)
32829 + rockchip_lvds_disable(lvds->secondary);
32832 -static int px30_lvds_grf_config(struct drm_encoder *encoder,
32833 - struct drm_display_mode *mode)
32838 - if (lvds->output != DISPLAY_OUTPUT_LVDS) {
32839 - DRM_DEV_ERROR(lvds->dev, "Unsupported display output %d\n",
32840 - lvds->output);
32841 - return -EINVAL;
32842 - }
32843 -
32844 - /* Set format */
32845 - return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
32846 - PX30_LVDS_FORMAT(lvds->format),
32847 - PX30_LVDS_FORMAT(lvds->format));
32848 -}
32849 -
32850 -static int px30_lvds_set_vop_source(struct rockchip_lvds *lvds,
32851 - struct drm_encoder *encoder)
32852 -{
32853 - int vop;
32854 -
32855 - vop = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder);
32856 - if (vop < 0)
32857 - return vop;
32858 -
32859 - return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
32860 - PX30_LVDS_VOP_SEL(1),
32861 - PX30_LVDS_VOP_SEL(vop));
32862 + if (lvds->panel)
32863 + drm_panel_prepare(lvds->panel);
32865 + if (lvds->panel)
32866 + drm_panel_enable(lvds->panel);
32869 -static void px30_lvds_encoder_enable(struct drm_encoder *encoder)
32873 - struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
32874 - int ret;
32875 -
32876 - drm_panel_prepare(lvds->panel);
32877 -
32878 - ret = px30_lvds_poweron(lvds);
32879 - if (ret) {
32880 - DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret);
32881 - drm_panel_unprepare(lvds->panel);
32882 - return;
32883 - }
32884 -
32885 - ret = px30_lvds_grf_config(encoder, mode);
32886 - if (ret) {
32887 - DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret);
32888 - drm_panel_unprepare(lvds->panel);
32889 - return;
32890 - }
32892 - ret = px30_lvds_set_vop_source(lvds, encoder);
32893 - if (ret) {
32894 - DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret);
32895 + if (lvds->panel)
32896 + drm_panel_disable(lvds->panel);
32898 + if (lvds->panel)
32899 drm_panel_unprepare(lvds->panel);
32900 - return;
32901 - }
32902 -
32903 - drm_panel_enable(lvds->panel);
32906 -static void px30_lvds_encoder_disable(struct drm_encoder *encoder)
32912 - drm_panel_disable(lvds->panel);
32913 - px30_lvds_poweroff(lvds);
32914 - drm_panel_unprepare(lvds->panel);
32915 + if (lvds->panel)
32916 + panel_simple_loader_protect(lvds->panel);
32920 -struct drm_encoder_helper_funcs rk3288_lvds_encoder_helper_funcs = {
32921 - .enable = rk3288_lvds_encoder_enable,
32922 - .disable = rk3288_lvds_encoder_disable,
32930 -static const
32931 -struct drm_encoder_helper_funcs px30_lvds_encoder_helper_funcs = {
32932 - .enable = px30_lvds_encoder_enable,
32933 - .disable = px30_lvds_encoder_disable,
32934 - .atomic_check = rockchip_lvds_encoder_atomic_check,
32939 -static int rk3288_lvds_probe(struct platform_device *pdev,
32940 - struct rockchip_lvds *lvds)
32943 - struct resource *res;
32944 - int ret;
32945 -
32946 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
32947 - lvds->regs = devm_ioremap_resource(lvds->dev, res);
32948 - if (IS_ERR(lvds->regs))
32949 - return PTR_ERR(lvds->regs);
32950 -
32951 - lvds->pclk = devm_clk_get(lvds->dev, "pclk_lvds");
32952 - if (IS_ERR(lvds->pclk)) {
32953 - DRM_DEV_ERROR(lvds->dev, "could not get pclk_lvds\n");
32954 - return PTR_ERR(lvds->pclk);
32955 - }
32956 -
32957 - lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins),
32958 - GFP_KERNEL);
32959 - if (!lvds->pins)
32960 - return -ENOMEM;
32961 -
32962 - lvds->pins->p = devm_pinctrl_get(lvds->dev);
32963 - if (IS_ERR(lvds->pins->p)) {
32964 - DRM_DEV_ERROR(lvds->dev, "no pinctrl handle\n");
32965 - devm_kfree(lvds->dev, lvds->pins);
32966 - lvds->pins = NULL;
32967 - } else {
32968 - lvds->pins->default_state =
32969 - pinctrl_lookup_state(lvds->pins->p, "lcdc");
32970 - if (IS_ERR(lvds->pins->default_state)) {
32971 - DRM_DEV_ERROR(lvds->dev, "no default pinctrl state\n");
32972 - devm_kfree(lvds->dev, lvds->pins);
32973 - lvds->pins = NULL;
32974 - }
32975 - }
32976 -
32977 - ret = clk_prepare(lvds->pclk);
32978 - if (ret < 0) {
32979 - DRM_DEV_ERROR(lvds->dev, "failed to prepare pclk_lvds\n");
32980 - return ret;
32981 - }
32985 - return 0;
32986 + return lvds->id == *id;
32989 -static int px30_lvds_probe(struct platform_device *pdev,
32990 - struct rockchip_lvds *lvds)
32994 - int ret;
32995 -
32996 - /* MSB */
32997 - ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
32998 - PX30_LVDS_MSBSEL(1),
32999 - PX30_LVDS_MSBSEL(1));
33000 - if (ret)
33001 - return ret;
33002 -
33003 - /* PHY */
33004 - lvds->dphy = devm_phy_get(&pdev->dev, "dphy");
33005 - if (IS_ERR(lvds->dphy))
33006 - return PTR_ERR(lvds->dphy);
33007 -
33008 - ret = phy_init(lvds->dphy);
33009 - if (ret)
33010 - return ret;
33013 - ret = phy_set_mode(lvds->dphy, PHY_MODE_LVDS);
33014 - if (ret)
33015 - return ret;
33020 - return phy_power_on(lvds->dphy);
33024 -static const struct rockchip_lvds_soc_data rk3288_lvds_data = {
33025 - .probe = rk3288_lvds_probe,
33026 - .helper_funcs = &rk3288_lvds_encoder_helper_funcs,
33027 -};
33028 -
33029 -static const struct rockchip_lvds_soc_data px30_lvds_data = {
33030 - .probe = px30_lvds_probe,
33031 - .helper_funcs = &px30_lvds_encoder_helper_funcs,
33032 -};
33033 -
33034 -static const struct of_device_id rockchip_lvds_dt_ids[] = {
33035 - {
33036 - .compatible = "rockchip,rk3288-lvds",
33037 - .data = &rk3288_lvds_data
33038 - },
33039 - {
33040 - .compatible = "rockchip,px30-lvds",
33041 - .data = &px30_lvds_data
33042 - },
33043 - {}
33044 -};
33045 -MODULE_DEVICE_TABLE(of, rockchip_lvds_dt_ids);
33046 -
33052 - struct drm_encoder *encoder;
33053 - struct drm_connector *connector;
33054 - struct device_node *remote = NULL;
33055 - struct device_node *port, *endpoint;
33056 - int ret = 0, child_count = 0;
33057 - const char *name;
33058 - u32 endpoint_id = 0;
33059 -
33060 - lvds->drm_dev = drm_dev;
33061 - port = of_graph_get_port_by_id(dev->of_node, 1);
33062 - if (!port) {
33063 - DRM_DEV_ERROR(dev,
33064 - "can't found port point, please init lvds panel port!\n");
33065 - return -EINVAL;
33066 - }
33067 - for_each_child_of_node(port, endpoint) {
33068 - child_count++;
33069 - of_property_read_u32(endpoint, "reg", &endpoint_id);
33070 - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id,
33071 - &lvds->panel, &lvds->bridge);
33072 - if (!ret) {
33073 - of_node_put(endpoint);
33074 - break;
33075 - }
33076 - }
33077 - if (!child_count) {
33078 - DRM_DEV_ERROR(dev, "lvds port does not have any children\n");
33079 - ret = -EINVAL;
33080 - goto err_put_port;
33081 - } else if (ret) {
33082 - DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n");
33083 - ret = -EPROBE_DEFER;
33084 - goto err_put_port;
33085 - }
33086 - if (lvds->panel)
33087 - remote = lvds->panel->dev->of_node;
33088 - else
33089 - remote = lvds->bridge->of_node;
33090 - if (of_property_read_string(dev->of_node, "rockchip,output", &name))
33091 - /* default set it as output rgb */
33092 - lvds->output = DISPLAY_OUTPUT_RGB;
33093 - else
33094 - lvds->output = rockchip_lvds_name_to_output(name);
33095 -
33096 - if (lvds->output < 0) {
33097 - DRM_DEV_ERROR(dev, "invalid output type [%s]\n", name);
33098 - ret = lvds->output;
33099 - goto err_put_remote;
33100 - }
33101 + struct drm_encoder *encoder = &lvds->encoder;
33102 + struct drm_connector *connector = &lvds->connector;
33105 - if (of_property_read_string(remote, "data-mapping", &name))
33106 - /* default set it as format vesa 18 */
33107 - lvds->format = LVDS_VESA_18;
33108 - else
33109 - lvds->format = rockchip_lvds_name_to_format(name);
33113 + if (lvds->primary)
33116 - if (lvds->format < 0) {
33117 - DRM_DEV_ERROR(dev, "invalid data-mapping format [%s]\n", name);
33118 - ret = lvds->format;
33119 - goto err_put_remote;
33120 - }
33121 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
33122 + &lvds->panel, &lvds->bridge);
33126 - encoder = &lvds->encoder;
33127 - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
33128 - dev->of_node);
33129 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
33130 + dev->of_node);
33132 - ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_LVDS);
33136 - DRM_DEV_ERROR(drm_dev->dev,
33137 + DRM_DEV_ERROR(lvds->dev,
33139 - goto err_put_remote;
33143 - drm_encoder_helper_add(encoder, lvds->soc_data->helper_funcs);
33146 if (lvds->panel) {
33147 - connector = &lvds->connector;
33148 - connector->dpms = DRM_MODE_DPMS_OFF;
33149 + struct rockchip_drm_private *private = drm_dev->dev_private;
33154 @@ -630,34 +409,31 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
33158 - DRM_DEV_ERROR(drm_dev->dev,
33159 + DRM_DEV_ERROR(lvds->dev,
33164 + lvds->sub_dev.connector = &lvds->connector;
33165 + lvds->sub_dev.of_node = lvds->dev->of_node;
33166 + lvds->sub_dev.loader_protect = rockchip_lvds_encoder_loader_protect;
33167 + rockchip_drm_register_sub_dev(&lvds->sub_dev);
33168 + drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
33170 ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);
33172 - DRM_DEV_ERROR(drm_dev->dev,
33173 + DRM_DEV_ERROR(lvds->dev,
33179 - pm_runtime_enable(dev);
33180 - of_node_put(remote);
33181 - of_node_put(port);
33182 -
33189 -err_put_remote:
33190 - of_node_put(remote);
33191 -err_put_port:
33192 - of_node_put(port);
33193 -
33197 @@ -665,13 +441,14 @@ static void rockchip_lvds_unbind(struct device *dev, struct device *master,
33201 - const struct drm_encoder_helper_funcs *encoder_funcs;
33203 - encoder_funcs = lvds->soc_data->helper_funcs;
33204 - encoder_funcs->disable(&lvds->encoder);
33205 - pm_runtime_disable(dev);
33206 - drm_connector_cleanup(&lvds->connector);
33207 - drm_encoder_cleanup(&lvds->encoder);
33208 + if (lvds->sub_dev.connector)
33209 + rockchip_drm_unregister_sub_dev(&lvds->sub_dev);
33210 + if (lvds->panel)
33211 + drm_connector_cleanup(&lvds->connector);
33213 + if (lvds->encoder.dev)
33214 + drm_encoder_cleanup(&lvds->encoder);
33218 @@ -683,56 +460,219 @@ static int rockchip_lvds_probe(struct platform_device *pdev)
33220 struct device *dev = &pdev->dev;
33222 - const struct of_device_id *match;
33225 if (!dev->of_node)
33226 return -ENODEV;
33228 - lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
33231 return -ENOMEM;
33233 + lvds->id = of_alias_get_id(dev->of_node, "lvds");
33234 + if (lvds->id < 0)
33235 + lvds->id = 0;
33237 lvds->dev = dev;
33238 - match = of_match_node(rockchip_lvds_dt_ids, dev->of_node);
33239 - if (!match)
33240 - return -ENODEV;
33241 - lvds->soc_data = match->data;
33242 + lvds->funcs = of_device_get_match_data(dev);
33245 + lvds->dual_channel = of_property_read_bool(dev->of_node,
33246 + "dual-channel");
33247 + lvds->data_swap = of_property_read_bool(dev->of_node,
33248 + "rockchip,data-swap");
33250 + lvds->phy = devm_phy_get(dev, "phy");
33251 + if (IS_ERR(lvds->phy)) {
33252 + ret = PTR_ERR(lvds->phy);
33257 - lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
33258 - "rockchip,grf");
33259 + lvds->grf = syscon_node_to_regmap(dev->parent->of_node);
33260 if (IS_ERR(lvds->grf)) {
33261 - DRM_DEV_ERROR(dev, "missing rockchip,grf property\n");
33262 - return PTR_ERR(lvds->grf);
33263 + ret = PTR_ERR(lvds->grf);
33268 - ret = lvds->soc_data->probe(pdev, lvds);
33269 - if (ret) {
33270 - DRM_DEV_ERROR(dev, "Platform initialization failed\n");
33271 - return ret;
33272 + lvds->pixel_order = -1;
33273 + if (lvds->funcs->probe) {
33274 + ret = lvds->funcs->probe(lvds);
33279 - dev_set_drvdata(dev, lvds);
33285 + component_del(&pdev->dev, &rockchip_lvds_component_ops);
33290 - ret = component_add(&pdev->dev, &rockchip_lvds_component_ops);
33291 - if (ret < 0) {
33292 - DRM_DEV_ERROR(dev, "failed to add component\n");
33293 - clk_unprepare(lvds->pclk);
33296 + int pipe = drm_of_encoder_active_endpoint_id(lvds->dev->of_node,
33297 + &lvds->encoder);
33299 + regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1,
33300 + PX30_LVDS_SELECT(lvds->format) |
33307 + regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1,
33318 + regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0,
33320 + RK3126_LVDS_MSBSEL(1) | RK3126_LVDS_SELECT(lvds->format));
33325 + regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0,
33336 + struct drm_display_mode *mode = &lvds->mode;
33340 + pipe = drm_of_encoder_active_endpoint_id(lvds->dev->of_node,
33341 + &lvds->encoder);
33342 + regmap_write(lvds->grf, RK3288_GRF_SOC_CON6,
33346 + RK3288_LVDS_CON_CHASEL(lvds->dual_channel) |
33347 + RK3288_LVDS_CON_SELECT(lvds->format);
33349 + if (lvds->dual_channel) {
33350 + u32 h_bp = mode->htotal - mode->hsync_start;
33354 + RK3288_LVDS_CON_STARTSEL(lvds->data_swap);
33366 - return ret;
33367 + regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, val);
33369 + phy_set_bus_width(lvds->phy, lvds->dual_channel ? 2 : 1);
33372 -static int rockchip_lvds_remove(struct platform_device *pdev)
33375 - struct rockchip_lvds *lvds = dev_get_drvdata(&pdev->dev);
33376 + regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, RK3288_LVDS_PWRDWN(1));
33379 - component_del(&pdev->dev, &rockchip_lvds_component_ops);
33380 - clk_unprepare(lvds->pclk);
33388 + regmap_write(lvds->grf, RK3368_GRF_SOC_CON7,
33389 + RK3368_LVDS_SELECT(lvds->format) |
33396 + regmap_write(lvds->grf, RK3368_GRF_SOC_CON7,
33407 + if (lvds->dual_channel) {
33412 + secondary = rockchip_lvds_find_by_id(lvds->dev->driver, 1);
33414 + return -EPROBE_DEFER;
33416 + port0 = of_graph_get_port_by_id(lvds->dev->of_node, 1);
33417 + port1 = of_graph_get_port_by_id(secondary->dev->of_node, 1);
33422 + secondary->primary = lvds;
33423 + lvds->secondary = secondary;
33424 + lvds->pixel_order = pixel_order >= 0 ? pixel_order : 0;
33432 + regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
33435 + regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
33436 + RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1));
33441 + regmap_write(lvds->grf, RK3568_GRF_VO_CON2, RK3568_LVDS0_MODE_EN(0));
33450 + { .compatible = "rockchip,px30-lvds", .data = &px30_lvds_funcs },
33451 + { .compatible = "rockchip,rk3126-lvds", .data = &rk3126_lvds_funcs },
33452 + { .compatible = "rockchip,rk3288-lvds", .data = &rk3288_lvds_funcs },
33453 + { .compatible = "rockchip,rk3368-lvds", .data = &rk3368_lvds_funcs },
33454 + { .compatible = "rockchip,rk3568-lvds", .data = &rk3568_lvds_funcs },
33462 diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c
33464 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
33466 @@ -6,29 +6,183 @@
33478 -#include <drm/drm_bridge.h>
33484 -#include <drm/drm_simple_kms_helper.h>
33491 -#define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder)
33537 - struct drm_device *drm_dev;
33542 - int output_mode;
33573 + struct rockchip_drm_private *private = connector->dev->dev_private;
33575 + if (property == private->connector_id_prop) {
33576 + *val = rgb->id;
33581 + return -EINVAL;
33597 + struct drm_panel *panel = rgb->panel;
33607 + return &rgb->encoder;
33620 + pinctrl_pm_select_default_state(rgb->dev);
33622 + if (rgb->funcs && rgb->funcs->enable)
33623 + rgb->funcs->enable(rgb);
33625 + if (rgb->phy)
33626 + phy_power_on(rgb->phy);
33628 + if (rgb->panel) {
33629 + drm_panel_prepare(rgb->panel);
33630 + drm_panel_enable(rgb->panel);
33638 + if (rgb->panel) {
33639 + drm_panel_disable(rgb->panel);
33640 + drm_panel_unprepare(rgb->panel);
33643 + if (rgb->phy)
33644 + phy_power_off(rgb->phy);
33646 + if (rgb->funcs && rgb->funcs->disable)
33647 + rgb->funcs->disable(rgb);
33649 + pinctrl_pm_select_sleep_state(rgb->dev);
33655 @@ -37,128 +191,369 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder,
33657 struct drm_connector *connector = conn_state->connector;
33658 struct drm_display_info *info = &connector->display_info;
33659 - u32 bus_format;
33661 if (info->num_bus_formats)
33662 - bus_format = info->bus_formats[0];
33663 + s->bus_format = info->bus_formats[0];
33665 - bus_format = MEDIA_BUS_FMT_RGB888_1X24;
33666 + s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
33668 - switch (bus_format) {
33669 + switch (s->bus_format) {
33671 s->output_mode = ROCKCHIP_OUT_MODE_P666;
33672 + s->output_if = VOP_OUTPUT_IF_RGB;
33675 s->output_mode = ROCKCHIP_OUT_MODE_P565;
33676 + s->output_if = VOP_OUTPUT_IF_RGB;
33679 + s->output_mode = ROCKCHIP_OUT_MODE_S888;
33680 + s->output_if = VOP_OUTPUT_IF_RGB;
33683 + s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY;
33684 + s->output_if = VOP_OUTPUT_IF_RGB;
33690 + s->output_mode = ROCKCHIP_OUT_MODE_BT656;
33691 + s->output_if = VOP_OUTPUT_IF_BT656;
33697 + s->output_mode = ROCKCHIP_OUT_MODE_BT1120;
33698 + s->output_if = VOP_OUTPUT_IF_BT1120;
33703 s->output_mode = ROCKCHIP_OUT_MODE_P888;
33704 + s->output_if = VOP_OUTPUT_IF_RGB;
33708 - s->output_type = DRM_MODE_CONNECTOR_LVDS;
33709 + s->output_type = DRM_MODE_CONNECTOR_DPI;
33710 + s->bus_flags = info->bus_flags;
33711 + s->tv_state = &conn_state->tv;
33712 + s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
33713 + s->color_space = V4L2_COLORSPACE_DEFAULT;
33723 + if (rgb->panel)
33724 + panel_simple_loader_protect(rgb->panel);
33732 + u32 request_clock = mode->clock;
33733 + u32 max_clock = rgb->max_dclk_rate;
33735 + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
33761 + struct drm_encoder *encoder = &rgb->encoder;
33765 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
33766 + &rgb->panel, &rgb->bridge);
33772 + encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
33773 + dev->of_node);
33784 + if (rgb->panel) {
33785 + struct rockchip_drm_private *private = drm_dev->dev_private;
33787 + connector = &rgb->connector;
33788 + connector->interlace_allowed = true;
33808 + rgb->sub_dev.connector = &rgb->connector;
33809 + rgb->sub_dev.of_node = rgb->dev->of_node;
33810 + rgb->sub_dev.loader_protect = rockchip_rgb_encoder_loader_protect;
33811 + drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
33812 + rockchip_drm_register_sub_dev(&rgb->sub_dev);
33814 + rgb->bridge->encoder = encoder;
33815 + ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
33837 + if (rgb->sub_dev.connector)
33838 + rockchip_drm_register_sub_dev(&rgb->sub_dev);
33839 + if (rgb->panel)
33840 + drm_connector_cleanup(&rgb->connector);
33842 + drm_encoder_cleanup(&rgb->encoder);
33850 -struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
33851 - struct drm_crtc *crtc,
33852 - struct drm_device *drm_dev)
33855 + struct device *dev = &pdev->dev;
33857 - struct drm_encoder *encoder;
33858 - struct device_node *port, *endpoint;
33859 - u32 endpoint_id;
33860 - int ret = 0, child_count = 0;
33861 - struct drm_panel *panel;
33862 - struct drm_bridge *bridge;
33866 - rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL);
33867 + rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL);
33869 - return ERR_PTR(-ENOMEM);
33870 + return -ENOMEM;
33872 + id = of_alias_get_id(dev->of_node, "rgb");
33877 + rgb->id = id;
33878 rgb->dev = dev;
33879 - rgb->drm_dev = drm_dev;
33880 -
33881 - port = of_graph_get_port_by_id(dev->of_node, 0);
33882 - if (!port)
33883 - return ERR_PTR(-EINVAL);
33884 -
33885 - for_each_child_of_node(port, endpoint) {
33886 - if (of_property_read_u32(endpoint, "reg", &endpoint_id))
33887 - endpoint_id = 0;
33888 -
33889 - /* if subdriver (> 0) or error case (< 0), ignore entry */
33890 - if (rockchip_drm_endpoint_is_subdriver(endpoint) != 0)
33891 - continue;
33892 -
33893 - child_count++;
33894 - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id,
33895 - &panel, &bridge);
33896 - if (!ret) {
33897 - of_node_put(endpoint);
33898 - break;
33899 + rgb->max_dclk_rate = rgb_data->max_dclk_rate;
33900 + rgb->funcs = rgb_data->funcs;
33903 + rgb->data_sync_bypass =
33904 + of_property_read_bool(dev->of_node, "rockchip,data-sync-bypass");
33906 + if (dev->parent && dev->parent->of_node) {
33907 + rgb->grf = syscon_node_to_regmap(dev->parent->of_node);
33908 + if (IS_ERR(rgb->grf)) {
33909 + ret = PTR_ERR(rgb->grf);
33915 - of_node_put(port);
33916 + rgb->phy = devm_phy_optional_get(dev, "phy");
33917 + if (IS_ERR(rgb->phy)) {
33918 + ret = PTR_ERR(rgb->phy);
33923 - /* if the rgb output is not connected to anything, just return */
33924 - if (!child_count)
33925 - return NULL;
33929 - if (ret < 0) {
33930 - if (ret != -EPROBE_DEFER)
33931 - DRM_DEV_ERROR(dev, "failed to find panel or bridge %d\n", ret);
33932 - return ERR_PTR(ret);
33933 - }
33936 + component_del(&pdev->dev, &rockchip_rgb_component_ops);
33938 - encoder = &rgb->encoder;
33939 - encoder->possible_crtcs = drm_crtc_mask(crtc);
33943 - ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_NONE);
33944 - if (ret < 0) {
33945 - DRM_DEV_ERROR(drm_dev->dev,
33946 - "failed to initialize encoder: %d\n", ret);
33947 - return ERR_PTR(ret);
33948 - }
33951 + int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node,
33952 + &rgb->encoder);
33954 - drm_encoder_helper_add(encoder, &rockchip_rgb_encoder_helper_funcs);
33955 + regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, PX30_RGB_VOP_SEL(pipe) |
33956 + PX30_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
33959 - if (panel) {
33960 - bridge = drm_panel_bridge_add_typed(panel,
33961 - DRM_MODE_CONNECTOR_LVDS);
33962 - if (IS_ERR(bridge))
33963 - return ERR_CAST(bridge);
33964 - }
33969 - rgb->bridge = bridge;
33974 - ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
33975 - if (ret) {
33976 - DRM_DEV_ERROR(drm_dev->dev,
33977 - "failed to attach bridge: %d\n", ret);
33978 - goto err_free_encoder;
33979 - }
33982 + regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
33983 + RK1808_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
33986 - return rgb;
33991 -err_free_encoder:
33992 - drm_encoder_cleanup(encoder);
33993 - return ERR_PTR(ret);
34000 + int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node,
34001 + &rgb->encoder);
34003 + regmap_write(rgb->grf, RK3288_GRF_SOC_CON6, RK3288_LVDS_LCDC_SEL(pipe));
34004 + regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
34009 -EXPORT_SYMBOL_GPL(rockchip_rgb_init);
34011 -void rockchip_rgb_fini(struct rockchip_rgb *rgb)
34014 - drm_panel_bridge_remove(rgb->bridge);
34015 - drm_encoder_cleanup(&rgb->encoder);
34016 + regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
34032 + regmap_write(rgb->grf, RK3568_GRF_VO_CON1,
34033 + RK3568_RGB_DATA_BYPASS(rgb->data_sync_bypass));
34046 + regmap_write(rgb->grf, RV1126_GRF_IOFUNC_CON3,
34047 + RV1126_LCDC_IO_BYPASS(rgb->data_sync_bypass));
34049 -EXPORT_SYMBOL_GPL(rockchip_rgb_fini);
34061 + regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER,
34062 + RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass) ? 0x3 : 0x0);
34063 + regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS,
34064 + RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass) ? 0x3 : 0x0);
34077 + { .compatible = "rockchip,px30-rgb", .data = &px30_rgb },
34078 + { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb },
34079 + { .compatible = "rockchip,rk3066-rgb", },
34080 + { .compatible = "rockchip,rk3128-rgb", },
34081 + { .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb },
34082 + { .compatible = "rockchip,rk3308-rgb", },
34083 + { .compatible = "rockchip,rk3368-rgb", },
34084 + { .compatible = "rockchip,rk3568-rgb", .data = &rk3568_rgb },
34085 + { .compatible = "rockchip,rk3588-rgb", },
34086 + { .compatible = "rockchip,rv1106-rgb", .data = &rv1106_rgb},
34087 + { .compatible = "rockchip,rv1108-rgb", },
34088 + { .compatible = "rockchip,rv1126-rgb", .data = &rv1126_rgb},
34097 + .name = "rockchip-rgb",
34101 diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.h b/drivers/gpu/drm/rockchip/rockchip_rgb.h
34103 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.h
34105 @@ -8,12 +8,14 @@
34109 - struct drm_device *drm_dev);
34116 - struct drm_device *drm_dev)
34122 diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_re…
34124 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
34126 @@ -5,36 +5,36 @@
34130 -#include <linux/mod_devicetable.h>
34131 -#include <linux/module.h>
34137 -#include <drm/drm_plane.h>
34142 -#include "rockchip_drm_drv.h"
34144 -#define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
34145 - { \
34146 - .offset = off, \
34151 - .shift = _shift, \
34154 - .relaxed = _relaxed, \
34155 - }
34160 -#define VOP_REG(off, _mask, _shift) \
34161 - _VOP_REG(off, _mask, _shift, false, true)
34163 + VOP_REG_VER_MASK(off, _mask, s, false, 0, 0, -1)
34165 -#define VOP_REG_SYNC(off, _mask, _shift) \
34166 - _VOP_REG(off, _mask, _shift, false, false)
34168 + VOP_REG_VER_MASK(off, _mask, s, true, 0, 0, -1)
34174 -#define VOP_REG_MASK_SYNC(off, _mask, _shift) \
34175 - _VOP_REG(off, _mask, _shift, true, false)
34179 @@ -50,15 +50,46 @@ static const uint32_t formats_win_full[] = {
34183 -static const uint64_t format_modifiers_win_full[] = {
34184 - DRM_FORMAT_MOD_LINEAR,
34185 - DRM_FORMAT_MOD_INVALID,
34205 -static const uint64_t format_modifiers_win_full_afbc[] = {
34206 - ROCKCHIP_AFBC_MOD,
34207 - DRM_FORMAT_MOD_LINEAR,
34208 - DRM_FORMAT_MOD_INVALID,
34226 + DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode or non-Linear mode */
34227 + DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode or non-Linear mode */
34228 + DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode or non-Linear mode */
34229 + DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode or non-Linear mode */
34233 @@ -72,524 +103,571 @@ static const uint32_t formats_win_lite[] = {
34237 -static const uint64_t format_modifiers_win_lite[] = {
34243 -static const struct vop_scl_regs rk3036_win_scl = {
34244 - .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
34245 - .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
34246 - .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
34247 - .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
34287 -static const struct vop_win_phy rk3036_win0_data = {
34288 - .scl = &rk3036_win_scl,
34289 - .data_formats = formats_win_full,
34290 - .nformats = ARRAY_SIZE(formats_win_full),
34291 - .format_modifiers = format_modifiers_win_full,
34292 - .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
34293 - .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
34294 - .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
34295 - .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
34296 - .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
34297 - .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
34298 - .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
34299 - .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
34300 - .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
34301 - .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
34326 -static const struct vop_win_phy rk3036_win1_data = {
34342 + .csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
34344 + .xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1),
34345 + .ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1),
34362 - .format_modifiers = format_modifiers_win_lite,
34363 - .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
34364 - .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
34365 - .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
34366 - .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
34367 - .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
34368 - .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
34369 - .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
34370 - .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
34384 -static const struct vop_win_data rk3036_vop_win_data[] = {
34385 - { .base = 0x00, .phy = &rk3036_win0_data,
34386 - .type = DRM_PLANE_TYPE_PRIMARY },
34387 - { .base = 0x00, .phy = &rk3036_win1_data,
34388 - .type = DRM_PLANE_TYPE_CURSOR },
34397 -static const int rk3036_vop_intrs[] = {
34398 - DSP_HOLD_VALID_INTR,
34399 - FS_INTR,
34400 - LINE_FLAG_INTR,
34401 - BUS_ERROR_INTR,
34410 -static const struct vop_intr rk3036_intr = {
34411 - .intrs = rk3036_vop_intrs,
34412 - .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
34413 - .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
34414 - .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
34415 - .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
34416 - .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
34425 -static const struct vop_modeset rk3036_modeset = {
34426 - .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
34427 - .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
34428 - .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
34429 - .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
34436 -static const struct vop_output rk3036_output = {
34437 - .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
34444 + .reg_done_frm = VOP_REG_VER(RK3288_SYS_CTRL1, 0x1, 24, 3, 5, -1),
34460 + .post_lb_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 18, 3, 2, -1),
34461 + .global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
34462 + .overlay_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 16, 3, 2, -1),
34463 + .core_dclk_div = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 4, 3, 4, -1),
34464 + .p2i_en = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 5, 3, 4, -1),
34465 + .dclk_ddr = VOP_REG_VER(RK3288_DSP_CTRL0, 0x1, 8, 3, 1, -1),
34466 + .dp_en = VOP_REG_VER(RK3399_SYS_CTRL, 0x1, 11, 3, 5, -1),
34473 + .data01_swap = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 17, 3, 5, -1),
34476 + .dp_dclk_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0x1, 19, 3, 5, -1),
34477 + .dp_pin_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0x7, 16, 3, 5, -1),
34478 + .rgb_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 19, 3, 2, -1),
34479 + .rgb_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 16, 3, 2, -1),
34485 + .hdmi_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 23, 3, 2, -1),
34486 + .hdmi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 20, 3, 2, -1),
34487 + .edp_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 27, 3, 2, -1),
34488 + .edp_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 24, 3, 2, -1),
34489 + .mipi_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 31, 3, 2, -1),
34490 + .mipi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 28, 3, 2, -1),
34498 + .dsp_out_yuv = VOP_REG_VER(RK3399_POST_SCL_CTRL, 0x1, 2, 3, 5, -1),
34502 + .update_gamma_lut = VOP_REG_VER(RK3288_DSP_CTRL1, 0x1, 7, 3, 5, -1),
34503 + .lut_buffer_index = VOP_REG_VER(RK3399_DBG_POST_REG1, 0x1, 1, 3, 5, -1),
34507 + .afbdc_rstn = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1, 3, 3, 5, -1),
34508 + .afbdc_en = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1, 0, 3, 5, -1),
34509 + .afbdc_sel = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x3, 1, 3, 5, -1),
34510 + .afbdc_format = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1f, 16, 3, 5, -1),
34512 + 0x1, 21, 3, 5, -1),
34514 + 0, 3, 5, -1),
34516 + 0, 3, 5, -1),
34523 + .bcsh_r2y_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 6, 3, 1, -1),
34524 + .bcsh_r2y_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 4, 3, 1, -1),
34525 + .bcsh_y2r_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x3, 2, 3, 1, -1),
34526 + .bcsh_y2r_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 0, 3, 1, -1),
34538 -static const struct vop_common rk3036_common = {
34539 - .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
34540 - .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
34541 - .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
34542 - .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
34543 - .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
34544 - .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
34545 - .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
34567 -static const struct vop_data rk3036_vop = {
34568 - .intr = &rk3036_intr,
34569 - .common = &rk3036_common,
34570 - .modeset = &rk3036_modeset,
34571 - .output = &rk3036_output,
34572 - .win = rk3036_vop_win_data,
34573 - .win_size = ARRAY_SIZE(rk3036_vop_win_data),
34581 -static const struct vop_win_phy rk3126_win1_data = {
34582 - .data_formats = formats_win_lite,
34583 - .nformats = ARRAY_SIZE(formats_win_lite),
34584 - .format_modifiers = format_modifiers_win_lite,
34585 - .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
34586 - .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
34587 - .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
34588 - .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
34589 - .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
34590 - .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
34591 - .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
34601 -static const struct vop_win_data rk3126_vop_win_data[] = {
34602 - { .base = 0x00, .phy = &rk3036_win0_data,
34603 - .type = DRM_PLANE_TYPE_PRIMARY },
34604 - { .base = 0x00, .phy = &rk3126_win1_data,
34605 - .type = DRM_PLANE_TYPE_CURSOR },
34610 -static const struct vop_data rk3126_vop = {
34611 - .intr = &rk3036_intr,
34612 - .common = &rk3036_common,
34613 - .modeset = &rk3036_modeset,
34614 - .output = &rk3036_output,
34615 - .win = rk3126_vop_win_data,
34616 - .win_size = ARRAY_SIZE(rk3126_vop_win_data),
34649 -static const int px30_vop_intrs[] = {
34652 - 0, 0,
34656 - 0,
34659 - 0, 0,
34670 -static const struct vop_intr px30_intr = {
34671 - .intrs = px30_vop_intrs,
34672 - .nintrs = ARRAY_SIZE(px30_vop_intrs),
34673 - .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
34674 - .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
34675 - .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
34676 - .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
34687 -static const struct vop_common px30_common = {
34688 - .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
34689 - .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
34690 - .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
34691 - .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
34692 - .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
34693 - .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
34694 - .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
34712 -static const struct vop_modeset px30_modeset = {
34713 - .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
34714 - .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
34715 - .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
34716 - .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
34727 -static const struct vop_output px30_output = {
34728 - .rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1),
34729 - .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2),
34730 - .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
34731 - .mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25),
34732 - .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26),
34733 - .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
34744 -static const struct vop_scl_regs px30_win_scl = {
34745 - .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
34746 - .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
34747 - .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
34748 - .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
34759 -static const struct vop_win_phy px30_win0_data = {
34760 - .scl = &px30_win_scl,
34761 - .data_formats = formats_win_full,
34762 - .nformats = ARRAY_SIZE(formats_win_full),
34763 - .format_modifiers = format_modifiers_win_full,
34764 - .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
34765 - .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
34766 - .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
34767 - .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
34768 - .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
34769 - .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
34770 - .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
34771 - .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
34772 - .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
34773 - .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
34774 - .alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2),
34775 - .alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1),
34776 - .alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0),
34777 -};
34778 -
34779 -static const struct vop_win_phy px30_win1_data = {
34780 - .data_formats = formats_win_lite,
34781 - .nformats = ARRAY_SIZE(formats_win_lite),
34782 - .format_modifiers = format_modifiers_win_lite,
34783 - .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
34784 - .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
34785 - .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
34786 - .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
34787 - .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
34788 - .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
34789 - .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
34790 - .alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2),
34791 - .alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1),
34792 - .alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0),
34793 -};
34794 -
34795 -static const struct vop_win_phy px30_win2_data = {
34796 - .data_formats = formats_win_lite,
34797 - .nformats = ARRAY_SIZE(formats_win_lite),
34798 - .format_modifiers = format_modifiers_win_lite,
34799 - .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
34800 - .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
34801 - .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
34802 - .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
34803 - .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
34804 - .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
34805 - .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
34806 - .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
34807 - .alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2),
34808 - .alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1),
34809 - .alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0),
34816 -static const struct vop_win_data px30_vop_big_win_data[] = {
34817 - { .base = 0x00, .phy = &px30_win0_data,
34821 - { .base = 0x00, .phy = &px30_win1_data,
34824 - { .base = 0x00, .phy = &px30_win2_data,
34825 - .type = DRM_PLANE_TYPE_CURSOR },
34836 -static const struct vop_data px30_vop_big = {
34837 - .intr = &px30_intr,
34838 - .feature = VOP_FEATURE_INTERNAL_RGB,
34839 - .common = &px30_common,
34840 - .modeset = &px30_modeset,
34841 - .output = &px30_output,
34842 - .win = px30_vop_big_win_data,
34843 - .win_size = ARRAY_SIZE(px30_vop_big_win_data),
34857 -static const struct vop_win_data px30_vop_lit_win_data[] = {
34858 - { .base = 0x00, .phy = &px30_win1_data,
34859 - .type = DRM_PLANE_TYPE_PRIMARY },
34870 -static const struct vop_data px30_vop_lit = {
34871 - .intr = &px30_intr,
34872 - .feature = VOP_FEATURE_INTERNAL_RGB,
34873 - .common = &px30_common,
34874 - .modeset = &px30_modeset,
34875 - .output = &px30_output,
34876 - .win = px30_vop_lit_win_data,
34877 - .win_size = ARRAY_SIZE(px30_vop_lit_win_data),
34882 -static const struct vop_scl_regs rk3066_win_scl = {
34883 - .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
34884 - .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
34885 - .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
34886 - .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
34901 -static const struct vop_win_phy rk3066_win0_data = {
34902 - .scl = &rk3066_win_scl,
34903 - .data_formats = formats_win_full,
34904 - .nformats = ARRAY_SIZE(formats_win_full),
34905 - .format_modifiers = format_modifiers_win_full,
34906 - .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
34907 - .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4),
34908 - .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19),
34909 - .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
34910 - .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
34911 - .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
34912 - .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
34913 - .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
34914 - .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
34915 - .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
34921 -static const struct vop_win_phy rk3066_win1_data = {
34922 - .data_formats = formats_win_full,
34923 - .nformats = ARRAY_SIZE(formats_win_full),
34924 - .format_modifiers = format_modifiers_win_full,
34925 - .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
34926 - .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7),
34927 - .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23),
34928 - .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
34929 - .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
34930 - .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
34931 - .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
34932 - .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
34933 - .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
34934 - .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
34940 -static const struct vop_win_phy rk3066_win2_data = {
34941 - .data_formats = formats_win_lite,
34942 - .nformats = ARRAY_SIZE(formats_win_lite),
34943 - .format_modifiers = format_modifiers_win_lite,
34944 - .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
34945 - .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10),
34946 - .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27),
34947 - .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
34948 - .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
34949 - .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
34950 - .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
34956 -static const struct vop_modeset rk3066_modeset = {
34957 - .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
34958 - .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
34959 - .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
34960 - .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
34966 -static const struct vop_output rk3066_output = {
34967 - .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
34973 -static const struct vop_common rk3066_common = {
34974 - .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
34975 - .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
34976 - .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
34977 - .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
34978 - .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
34979 - .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
34980 - .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9),
34981 - .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31),
34982 - .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25),
34988 -static const struct vop_win_data rk3066_vop_win_data[] = {
34989 - { .base = 0x00, .phy = &rk3066_win0_data,
34990 - .type = DRM_PLANE_TYPE_PRIMARY },
34991 - { .base = 0x00, .phy = &rk3066_win1_data,
34992 - .type = DRM_PLANE_TYPE_OVERLAY },
34993 - { .base = 0x00, .phy = &rk3066_win2_data,
34994 - .type = DRM_PLANE_TYPE_CURSOR },
35000 -static const int rk3066_vop_intrs[] = {
35001 - /*
35002 - * hs_start interrupt fires at frame-start, so serves
35003 - * the same purpose as dsp_hold in the driver.
35004 - */
35005 - DSP_HOLD_VALID_INTR,
35006 - FS_INTR,
35007 - LINE_FLAG_INTR,
35008 - BUS_ERROR_INTR,
35014 -static const struct vop_intr rk3066_intr = {
35015 - .intrs = rk3066_vop_intrs,
35016 - .nintrs = ARRAY_SIZE(rk3066_vop_intrs),
35017 - .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
35018 - .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
35019 - .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
35020 - .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
35026 -static const struct vop_data rk3066_vop = {
35027 - .version = VOP_VERSION(2, 1),
35028 - .intr = &rk3066_intr,
35029 - .common = &rk3066_common,
35030 - .modeset = &rk3066_modeset,
35031 - .output = &rk3066_output,
35032 - .win = rk3066_vop_win_data,
35033 - .win_size = ARRAY_SIZE(rk3066_vop_win_data),
35039 -static const struct vop_scl_regs rk3188_win_scl = {
35040 - .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
35041 - .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
35042 - .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
35043 - .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
35044 -};
35051 -static const struct vop_win_phy rk3188_win0_data = {
35052 - .scl = &rk3188_win_scl,
35053 - .data_formats = formats_win_full,
35054 - .nformats = ARRAY_SIZE(formats_win_full),
35055 - .format_modifiers = format_modifiers_win_full,
35056 - .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
35057 - .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
35058 - .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
35059 - .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
35060 - .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
35061 - .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
35062 - .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
35063 - .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
35064 - .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
35065 -};
35066 -
35067 -static const struct vop_win_phy rk3188_win1_data = {
35068 - .data_formats = formats_win_lite,
35069 - .nformats = ARRAY_SIZE(formats_win_lite),
35070 - .format_modifiers = format_modifiers_win_lite,
35071 - .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
35072 - .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
35073 - .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
35074 - /* no act_info on window1 */
35075 - .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
35076 - .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
35077 - .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
35078 - .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
35079 -};
35080 -
35081 -static const struct vop_modeset rk3188_modeset = {
35082 - .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
35083 - .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
35084 - .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
35085 - .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
35086 -};
35087 -
35088 -static const struct vop_output rk3188_output = {
35089 - .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
35090 -};
35091 -
35092 -static const struct vop_common rk3188_common = {
35093 - .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
35094 - .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
35095 - .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
35096 - .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
35097 - .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
35098 - .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
35099 - .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
35100 - .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24),
35101 - .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9),
35102 - .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28),
35103 - .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25),
35104 -};
35105 -
35106 -static const struct vop_win_data rk3188_vop_win_data[] = {
35107 - { .base = 0x00, .phy = &rk3188_win0_data,
35108 - .type = DRM_PLANE_TYPE_PRIMARY },
35109 - { .base = 0x00, .phy = &rk3188_win1_data,
35110 - .type = DRM_PLANE_TYPE_CURSOR },
35111 -};
35115 -static const int rk3188_vop_intrs[] = {
35116 - /*
35117 - * hs_start interrupt fires at frame-start, so serves
35118 - * the same purpose as dsp_hold in the driver.
35119 - */
35120 - DSP_HOLD_VALID_INTR,
35121 - FS_INTR,
35122 - LINE_FLAG_INTR,
35123 - BUS_ERROR_INTR,
35131 -static const struct vop_intr rk3188_vop_intr = {
35132 - .intrs = rk3188_vop_intrs,
35133 - .nintrs = ARRAY_SIZE(rk3188_vop_intrs),
35134 - .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
35135 - .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
35136 - .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
35137 - .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
35147 -static const struct vop_data rk3188_vop = {
35148 - .intr = &rk3188_vop_intr,
35149 - .common = &rk3188_common,
35150 - .modeset = &rk3188_modeset,
35151 - .output = &rk3188_output,
35152 - .win = rk3188_vop_win_data,
35153 - .win_size = ARRAY_SIZE(rk3188_vop_win_data),
35154 - .feature = VOP_FEATURE_INTERNAL_RGB,
35164 -static const struct vop_scl_extension rk3288_win_full_scl_ext = {
35165 - .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
35166 - .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
35167 - .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
35168 - .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
35169 - .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
35170 - .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
35171 - .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
35172 - .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
35173 - .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
35174 - .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
35175 - .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
35176 - .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
35177 - .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
35178 - .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
35179 - .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
35180 - .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
35181 - .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
35182 - .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
35183 - .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
35184 - .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
35185 - .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
35193 -static const struct vop_scl_regs rk3288_win_full_scl = {
35194 - .ext = &rk3288_win_full_scl_ext,
35195 - .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
35196 - .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
35197 - .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
35198 - .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
35206 -static const struct vop_win_phy rk3288_win01_data = {
35209 - .data_formats = formats_win_full,
35210 - .nformats = ARRAY_SIZE(formats_win_full),
35211 - .format_modifiers = format_modifiers_win_full,
35218 + .csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
35220 + .xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1),
35221 + .ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1),
35225 @@ -597,478 +675,1318 @@ static const struct vop_win_phy rk3288_win01_data = {
35229 - .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
35230 - .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
35231 - .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
35238 -static const struct vop_win_phy rk3288_win23_data = {
35239 - .data_formats = formats_win_lite,
35240 - .nformats = ARRAY_SIZE(formats_win_lite),
35241 - .format_modifiers = format_modifiers_win_lite,
35242 - .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
35243 - .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
35244 - .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
35245 - .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
35246 - .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
35247 - .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
35248 - .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
35249 - .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
35250 - .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
35251 - .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
35275 -static const struct vop_modeset rk3288_modeset = {
35276 - .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
35277 - .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
35278 - .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
35279 - .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
35280 - .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
35281 - .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
35296 -static const struct vop_output rk3288_output = {
35297 - .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
35298 - .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
35299 - .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
35300 - .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
35301 - .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
35317 -static const struct vop_common rk3288_common = {
35318 - .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
35319 - .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
35320 - .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
35321 - .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
35322 - .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
35323 - .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
35324 - .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
35325 - .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
35326 - .dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0),
35327 - .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
35328 - .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
35329 - .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
35330 - .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
35346 -/*
35347 - * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
35348 - * special support to get alpha blending working. For now, just use overlay
35349 - * window 3 for the drm cursor.
35350 - *
35351 - */
35352 -static const struct vop_win_data rk3288_vop_win_data[] = {
35357 - .type = DRM_PLANE_TYPE_OVERLAY },
35358 - { .base = 0x00, .phy = &rk3288_win23_data,
35359 - .type = DRM_PLANE_TYPE_OVERLAY },
35360 - { .base = 0x50, .phy = &rk3288_win23_data,
35364 -static const int rk3288_vop_intrs[] = {
35365 - DSP_HOLD_VALID_INTR,
35366 - FS_INTR,
35367 - LINE_FLAG_INTR,
35368 - BUS_ERROR_INTR,
35369 -};
35370 -
35371 -static const struct vop_intr rk3288_vop_intr = {
35372 - .intrs = rk3288_vop_intrs,
35373 - .nintrs = ARRAY_SIZE(rk3288_vop_intrs),
35374 - .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
35375 - .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
35376 - .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
35377 - .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
35391 -static const struct vop_data rk3288_vop = {
35392 - .version = VOP_VERSION(3, 1),
35393 - .feature = VOP_FEATURE_OUTPUT_RGB10,
35394 - .intr = &rk3288_vop_intr,
35395 - .common = &rk3288_common,
35396 - .modeset = &rk3288_modeset,
35397 - .output = &rk3288_output,
35398 - .win = rk3288_vop_win_data,
35399 - .win_size = ARRAY_SIZE(rk3288_vop_win_data),
35400 - .lut_size = 1024,
35603 -static const int rk3368_vop_intrs[] = {
35604 - FS_INTR,
35605 - 0, 0,
35606 - LINE_FLAG_INTR,
35609 - BUS_ERROR_INTR,
35610 - 0, 0, 0, 0, 0, 0, 0,
35611 - DSP_HOLD_VALID_INTR,
35748 -static const struct vop_intr rk3368_vop_intr = {
35752 - .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
35753 - .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
35754 - .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
35755 - .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
35756 - .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
35764 -static const struct vop_win_phy rk3368_win01_data = {
35765 - .scl = &rk3288_win_full_scl,
35766 - .data_formats = formats_win_full,
35767 - .nformats = ARRAY_SIZE(formats_win_full),
35768 - .format_modifiers = format_modifiers_win_full,
35769 - .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
35770 - .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
35771 - .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
35772 - .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
35773 - .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
35774 - .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
35775 - .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
35776 - .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
35777 - .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
35778 - .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
35779 - .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
35780 - .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
35781 - .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
35782 - .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
35783 - .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
35790 -static const struct vop_win_phy rk3368_win23_data = {
35791 - .data_formats = formats_win_lite,
35792 - .nformats = ARRAY_SIZE(formats_win_lite),
35793 - .format_modifiers = format_modifiers_win_lite,
35794 - .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
35795 - .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
35796 - .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
35797 - .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
35798 - .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
35799 - .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
35800 - .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
35801 - .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
35802 - .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
35803 - .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
35804 - .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
35811 -static const struct vop_win_data rk3368_vop_win_data[] = {
35812 - { .base = 0x00, .phy = &rk3368_win01_data,
35813 - .type = DRM_PLANE_TYPE_PRIMARY },
35814 - { .base = 0x40, .phy = &rk3368_win01_data,
35815 - .type = DRM_PLANE_TYPE_OVERLAY },
35816 - { .base = 0x00, .phy = &rk3368_win23_data,
35817 - .type = DRM_PLANE_TYPE_OVERLAY },
35818 - { .base = 0x50, .phy = &rk3368_win23_data,
35819 - .type = DRM_PLANE_TYPE_CURSOR },
35826 -static const struct vop_output rk3368_output = {
35827 - .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
35828 - .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
35829 - .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
35830 - .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
35831 - .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
35832 - .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
35833 - .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
35834 - .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
35835 - .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
35836 - .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
35837 - .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
35838 - .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
35851 -static const struct vop_misc rk3368_misc = {
35852 - .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
35868 -static const struct vop_data rk3368_vop = {
35869 - .version = VOP_VERSION(3, 2),
35870 - .intr = &rk3368_vop_intr,
35871 - .common = &rk3288_common,
35872 - .modeset = &rk3288_modeset,
35873 - .output = &rk3368_output,
35874 - .misc = &rk3368_misc,
35875 - .win = rk3368_vop_win_data,
35876 - .win_size = ARRAY_SIZE(rk3368_vop_win_data),
35884 -static const struct vop_intr rk3366_vop_intr = {
35885 - .intrs = rk3368_vop_intrs,
35886 - .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
35887 - .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
35888 - .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
35889 - .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
35890 - .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
35891 - .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
35897 -static const struct vop_data rk3366_vop = {
35898 - .version = VOP_VERSION(3, 4),
35899 - .intr = &rk3366_vop_intr,
35900 - .common = &rk3288_common,
35901 - .modeset = &rk3288_modeset,
35902 - .output = &rk3368_output,
35903 - .misc = &rk3368_misc,
35904 - .win = rk3368_vop_win_data,
35905 - .win_size = ARRAY_SIZE(rk3368_vop_win_data),
35925 -static const struct vop_output rk3399_output = {
35926 - .dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19),
35927 - .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
35928 - .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
35929 - .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
35930 - .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
35931 - .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16),
35932 - .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
35933 - .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
35934 - .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
35935 - .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
35936 - .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
35937 - .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
35938 - .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
35939 - .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
35940 - .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
35941 - .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
35958 -static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
35959 - .y2r_coefficients = {
35960 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
35961 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
35962 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
35963 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
35964 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
35965 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
35966 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
35967 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
35968 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
35969 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
35970 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
35971 - VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
35972 - },
35980 -static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
35988 -static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
35989 - { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
35990 - .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
35991 - { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
35992 - .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
35993 - { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
35994 - { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
36043 -static const struct vop_win_phy rk3399_win01_data = {
36044 - .scl = &rk3288_win_full_scl,
36056 - .format_modifiers = format_modifiers_win_full_afbc,
36057 - .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
36058 - .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
36059 - .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
36060 - .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21),
36061 - .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
36062 - .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
36063 - .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
36064 - .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
36065 - .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
36066 - .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
36067 - .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
36068 - .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
36069 - .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
36070 - .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
36071 - .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
36086 -/*
36087 - * rk3399 vop big windows register layout is same as rk3288, but we
36088 - * have a separate rk3399 win data array here so that we can advertise
36089 - * AFBC on the primary plane.
36090 - */
36091 -static const struct vop_win_data rk3399_vop_win_data[] = {
36092 - { .base = 0x00, .phy = &rk3399_win01_data,
36128 - { .base = 0x40, .phy = &rk3368_win01_data,
36129 - .type = DRM_PLANE_TYPE_OVERLAY },
36130 - { .base = 0x00, .phy = &rk3368_win23_data,
36133 - { .base = 0x50, .phy = &rk3368_win23_data,
36138 -static const struct vop_afbc rk3399_vop_afbc = {
36139 - .rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
36140 - .enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
36141 - .win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
36142 - .format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
36143 - .hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
36144 - .hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
36145 - .pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
36153 -static const struct vop_data rk3399_vop_big = {
36154 - .version = VOP_VERSION(3, 5),
36155 - .feature = VOP_FEATURE_OUTPUT_RGB10,
36156 - .intr = &rk3366_vop_intr,
36157 - .common = &rk3288_common,
36158 - .modeset = &rk3288_modeset,
36159 - .output = &rk3399_output,
36160 - .afbc = &rk3399_vop_afbc,
36161 - .misc = &rk3368_misc,
36162 - .win = rk3399_vop_win_data,
36163 - .win_size = ARRAY_SIZE(rk3399_vop_win_data),
36164 - .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
36174 -static const struct vop_win_data rk3399_vop_lit_win_data[] = {
36175 - { .base = 0x00, .phy = &rk3368_win01_data,
36176 - .type = DRM_PLANE_TYPE_PRIMARY },
36177 - { .base = 0x00, .phy = &rk3368_win23_data,
36178 - .type = DRM_PLANE_TYPE_CURSOR},
36193 -static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
36194 - { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
36195 - .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
36196 - { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
36209 -static const struct vop_data rk3399_vop_lit = {
36210 - .version = VOP_VERSION(3, 6),
36211 - .intr = &rk3366_vop_intr,
36212 - .common = &rk3288_common,
36213 - .modeset = &rk3288_modeset,
36214 - .output = &rk3399_output,
36215 - .misc = &rk3368_misc,
36216 - .win = rk3399_vop_lit_win_data,
36217 - .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
36218 - .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
36234 -static const struct vop_win_data rk3228_vop_win_data[] = {
36235 - { .base = 0x00, .phy = &rk3288_win01_data,
36290 - { .base = 0x40, .phy = &rk3288_win01_data,
36295 -static const struct vop_data rk3228_vop = {
36296 - .version = VOP_VERSION(3, 7),
36297 - .feature = VOP_FEATURE_OUTPUT_RGB10,
36298 - .intr = &rk3366_vop_intr,
36299 - .common = &rk3288_common,
36300 - .modeset = &rk3288_modeset,
36301 - .output = &rk3399_output,
36302 - .misc = &rk3368_misc,
36303 - .win = rk3228_vop_win_data,
36304 - .win_size = ARRAY_SIZE(rk3228_vop_win_data),
36315 -static const struct vop_modeset rk3328_modeset = {
36316 - .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
36317 - .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
36318 - .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
36319 - .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
36320 - .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
36321 - .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
36337 -static const struct vop_output rk3328_output = {
36338 - .rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19),
36339 - .hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23),
36340 - .edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27),
36341 - .mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31),
36342 - .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
36343 - .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
36344 - .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
36345 - .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
36346 - .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16),
36347 - .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20),
36348 - .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24),
36349 - .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28),
36357 -static const struct vop_misc rk3328_misc = {
36358 - .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
36371 -static const struct vop_common rk3328_common = {
36372 - .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
36373 - .dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
36374 - .dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
36375 - .dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
36376 - .pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
36377 - .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
36378 - .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
36379 - .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
36380 - .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
36383 + * so we set the PX30 VOPB win2 base = 0x190 - 0xb0 = 0xe0
36483 -static const struct vop_intr rk3328_vop_intr = {
36484 - .intrs = rk3368_vop_intrs,
36485 - .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
36486 - .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
36487 - .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
36488 - .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
36489 - .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
36490 - .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
36503 -static const struct vop_win_data rk3328_vop_win_data[] = {
36504 - { .base = 0xd0, .phy = &rk3368_win01_data,
36509 - { .base = 0x1d0, .phy = &rk3368_win01_data,
36717 - { .base = 0x2d0, .phy = &rk3368_win01_data,
36718 - .type = DRM_PLANE_TYPE_CURSOR },
36810 -static const struct vop_data rk3328_vop = {
36811 - .version = VOP_VERSION(3, 8),
36812 - .feature = VOP_FEATURE_OUTPUT_RGB10,
36813 - .intr = &rk3328_vop_intr,
36814 - .common = &rk3328_common,
36815 - .modeset = &rk3328_modeset,
36816 - .output = &rk3328_output,
36817 - .misc = &rk3328_misc,
36818 - .win = rk3328_vop_win_data,
36819 - .win_size = ARRAY_SIZE(rk3328_vop_win_data),
36839 { .compatible = "rockchip,rk3036-vop",
36843 + { .compatible = "rockchip,rk3066-vop",
36847 { .compatible = "rockchip,rk3126-vop",
36849 - { .compatible = "rockchip,px30-vop-big",
36850 - .data = &px30_vop_big },
36853 { .compatible = "rockchip,px30-vop-lit",
36855 - { .compatible = "rockchip,rk3066-vop",
36856 - .data = &rk3066_vop },
36857 - { .compatible = "rockchip,rk3188-vop",
36858 - .data = &rk3188_vop },
36859 - { .compatible = "rockchip,rk3288-vop",
36860 - .data = &rk3288_vop },
36861 + { .compatible = "rockchip,px30-vop-big",
36865 + { .compatible = "rockchip,rk3308-vop",
36869 + { .compatible = "rockchip,rv1106-vop",
36873 + { .compatible = "rockchip,rv1126-vop",
36877 + { .compatible = "rockchip,rk3288-vop-big",
36879 + { .compatible = "rockchip,rk3288-vop-lit",
36883 { .compatible = "rockchip,rk3368-vop",
36885 { .compatible = "rockchip,rk3366-vop",
36889 { .compatible = "rockchip,rk3399-vop-big",
36891 { .compatible = "rockchip,rk3399-vop-lit",
36895 { .compatible = "rockchip,rk3228-vop",
36899 { .compatible = "rockchip,rk3328-vop",
36905 diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_re…
36907 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
36909 @@ -113,6 +113,11 @@
36921 @@ -300,6 +305,7 @@
36929 @@ -628,6 +634,7 @@
36937 @@ -798,6 +805,21 @@
36959 @@ -830,6 +852,7 @@
36967 @@ -870,112 +893,6 @@
36971 -/* rk3126 register definition */
36972 -#define RK3126_WIN1_MST 0x4c
36973 -#define RK3126_WIN1_DSP_INFO 0x50
36974 -#define RK3126_WIN1_DSP_ST 0x54
36975 -/* rk3126 register definition end */
36976 -
36977 -/* px30 register definition */
36978 -#define PX30_REG_CFG_DONE 0x00000
36979 -#define PX30_VERSION 0x00004
36980 -#define PX30_DSP_BG 0x00008
36981 -#define PX30_MCU_CTRL 0x0000c
36982 -#define PX30_SYS_CTRL0 0x00010
36983 -#define PX30_SYS_CTRL1 0x00014
36984 -#define PX30_SYS_CTRL2 0x00018
36985 -#define PX30_DSP_CTRL0 0x00020
36986 -#define PX30_DSP_CTRL2 0x00028
36987 -#define PX30_VOP_STATUS 0x0002c
36988 -#define PX30_LINE_FLAG 0x00030
36989 -#define PX30_INTR_EN 0x00034
36990 -#define PX30_INTR_CLEAR 0x00038
36991 -#define PX30_INTR_STATUS 0x0003c
36992 -#define PX30_WIN0_CTRL0 0x00050
36993 -#define PX30_WIN0_CTRL1 0x00054
36994 -#define PX30_WIN0_COLOR_KEY 0x00058
36995 -#define PX30_WIN0_VIR 0x0005c
36996 -#define PX30_WIN0_YRGB_MST0 0x00060
36997 -#define PX30_WIN0_CBR_MST0 0x00064
36998 -#define PX30_WIN0_ACT_INFO 0x00068
36999 -#define PX30_WIN0_DSP_INFO 0x0006c
37000 -#define PX30_WIN0_DSP_ST 0x00070
37001 -#define PX30_WIN0_SCL_FACTOR_YRGB 0x00074
37002 -#define PX30_WIN0_SCL_FACTOR_CBR 0x00078
37003 -#define PX30_WIN0_SCL_OFFSET 0x0007c
37004 -#define PX30_WIN0_ALPHA_CTRL 0x00080
37005 -#define PX30_WIN1_CTRL0 0x00090
37006 -#define PX30_WIN1_CTRL1 0x00094
37007 -#define PX30_WIN1_VIR 0x00098
37008 -#define PX30_WIN1_MST 0x000a0
37009 -#define PX30_WIN1_DSP_INFO 0x000a4
37010 -#define PX30_WIN1_DSP_ST 0x000a8
37011 -#define PX30_WIN1_COLOR_KEY 0x000ac
37012 -#define PX30_WIN1_ALPHA_CTRL 0x000bc
37013 -#define PX30_HWC_CTRL0 0x000e0
37014 -#define PX30_HWC_CTRL1 0x000e4
37015 -#define PX30_HWC_MST 0x000e8
37016 -#define PX30_HWC_DSP_ST 0x000ec
37017 -#define PX30_HWC_ALPHA_CTRL 0x000f0
37018 -#define PX30_DSP_HTOTAL_HS_END 0x00100
37019 -#define PX30_DSP_HACT_ST_END 0x00104
37020 -#define PX30_DSP_VTOTAL_VS_END 0x00108
37021 -#define PX30_DSP_VACT_ST_END 0x0010c
37022 -#define PX30_DSP_VS_ST_END_F1 0x00110
37023 -#define PX30_DSP_VACT_ST_END_F1 0x00114
37024 -#define PX30_BCSH_CTRL 0x00160
37025 -#define PX30_BCSH_COL_BAR 0x00164
37026 -#define PX30_BCSH_BCS 0x00168
37027 -#define PX30_BCSH_H 0x0016c
37028 -#define PX30_FRC_LOWER01_0 0x00170
37029 -#define PX30_FRC_LOWER01_1 0x00174
37030 -#define PX30_FRC_LOWER10_0 0x00178
37031 -#define PX30_FRC_LOWER10_1 0x0017c
37032 -#define PX30_FRC_LOWER11_0 0x00180
37033 -#define PX30_FRC_LOWER11_1 0x00184
37034 -#define PX30_MCU_RW_BYPASS_PORT 0x0018c
37035 -#define PX30_WIN2_CTRL0 0x00190
37036 -#define PX30_WIN2_CTRL1 0x00194
37037 -#define PX30_WIN2_VIR0_1 0x00198
37038 -#define PX30_WIN2_VIR2_3 0x0019c
37039 -#define PX30_WIN2_MST0 0x001a0
37040 -#define PX30_WIN2_DSP_INFO0 0x001a4
37041 -#define PX30_WIN2_DSP_ST0 0x001a8
37042 -#define PX30_WIN2_COLOR_KEY 0x001ac
37043 -#define PX30_WIN2_ALPHA_CTRL 0x001bc
37044 -#define PX30_BLANKING_VALUE 0x001f4
37045 -#define PX30_FLAG_REG_FRM_VALID 0x001f8
37046 -#define PX30_FLAG_REG 0x001fc
37047 -#define PX30_HWC_LUT_ADDR 0x00600
37048 -#define PX30_GAMMA_LUT_ADDR 0x00a00
37049 -/* px30 register definition end */
37050 -
37051 -/* rk3188 register definition */
37052 -#define RK3188_SYS_CTRL 0x00
37053 -#define RK3188_DSP_CTRL0 0x04
37054 -#define RK3188_DSP_CTRL1 0x08
37055 -#define RK3188_INT_STATUS 0x10
37056 -#define RK3188_WIN0_YRGB_MST0 0x20
37057 -#define RK3188_WIN0_CBR_MST0 0x24
37058 -#define RK3188_WIN0_YRGB_MST1 0x28
37059 -#define RK3188_WIN0_CBR_MST1 0x2c
37060 -#define RK3188_WIN_VIR 0x30
37061 -#define RK3188_WIN0_ACT_INFO 0x34
37062 -#define RK3188_WIN0_DSP_INFO 0x38
37063 -#define RK3188_WIN0_DSP_ST 0x3c
37064 -#define RK3188_WIN0_SCL_FACTOR_YRGB 0x40
37065 -#define RK3188_WIN0_SCL_FACTOR_CBR 0x44
37066 -#define RK3188_WIN1_MST 0x4c
37067 -#define RK3188_WIN1_DSP_INFO 0x50
37068 -#define RK3188_WIN1_DSP_ST 0x54
37069 -#define RK3188_DSP_HTOTAL_HS_END 0x6c
37070 -#define RK3188_DSP_HACT_ST_END 0x70
37071 -#define RK3188_DSP_VTOTAL_VS_END 0x74
37072 -#define RK3188_DSP_VACT_ST_END 0x78
37073 -#define RK3188_REG_CFG_DONE 0x90
37074 -/* rk3188 register definition end */
37075 -
37076 -/* rk3066 register definition */
37080 @@ -1026,6 +943,693 @@
37084 -/* rk3066 register definition end */
37775 diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
37777 --- a/drivers/i2c/busses/i2c-rk3x.c
37778 +++ b/drivers/i2c/busses/i2c-rk3x.c
37779 @@ -23,6 +23,8 @@
37788 @@ -35,6 +37,7 @@
37796 @@ -62,6 +65,15 @@ enum {
37812 @@ -73,7 +85,14 @@ enum {
37816 -#define REG_INT_ALL 0x7f
37828 @@ -152,7 +171,6 @@ struct rk3x_i2c_calced_timings {
37832 - STATE_START,
37836 @@ -189,6 +207,8 @@ struct rk3x_i2c_soc_data {
37845 @@ -200,6 +220,7 @@ struct rk3x_i2c {
37853 @@ -219,8 +240,21 @@ struct rk3x_i2c {
37868 + if (!i2c->system_restarting)
37869 + wake_up(&i2c->wait);
37875 @@ -238,14 +272,75 @@ static inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c)
37895 + if (!i2c->autostop_supported)
37898 + if (!(i2c->msg->flags & I2C_M_IGNORE_NAK))
37901 + if (!i2c->is_last_msg)
37904 + len = i2c->msg->len - i2c->processed;
37909 + i2c->state = STATE_STOP;
37934 - i2c_writel(i2c, REG_INT_START, REG_IEN);
37936 + if (i2c->mode == REG_CON_MOD_TX) {
37939 + i2c->state = STATE_WRITE;
37946 + i2c->state = STATE_READ;
37951 val |= REG_CON_EN | REG_CON_MOD(i2c->mode) | REG_CON_START;
37952 @@ -255,6 +350,12 @@ static void rk3x_i2c_start(struct rk3x_i2c *i2c)
37958 + if (i2c->mode == REG_CON_MOD_TX)
37965 @@ -278,6 +379,7 @@ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error)
37973 @@ -293,7 +395,7 @@ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error)
37977 - wake_up(&i2c->wait);
37982 @@ -322,6 +424,8 @@ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
37983 if (i2c->processed != 0) {
37991 @@ -331,7 +435,7 @@ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
37993 * Fill the transmit buffer with data from i2c->msg
37995 -static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c)
38000 @@ -359,40 +463,15 @@ static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c)
38004 - i2c_writel(i2c, cnt, REG_MTXCNT);
38014 -static void rk3x_i2c_handle_start(struct rk3x_i2c *i2c, unsigned int ipd)
38015 -{
38016 - if (!(ipd & REG_INT_START)) {
38017 - rk3x_i2c_stop(i2c, -EIO);
38018 - dev_warn(i2c->dev, "unexpected irq in START: 0x%x\n", ipd);
38019 - rk3x_i2c_clean_ipd(i2c);
38020 - return;
38021 - }
38022 -
38023 - /* ack interrupt */
38024 - i2c_writel(i2c, REG_INT_START, REG_IPD);
38025 -
38026 - /* disable start bit */
38027 - i2c_writel(i2c, i2c_readl(i2c, REG_CON) & ~REG_CON_START, REG_CON);
38028 -
38029 - /* enable appropriate interrupts and transition */
38030 - if (i2c->mode == REG_CON_MOD_TX) {
38031 - i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN);
38032 - i2c->state = STATE_WRITE;
38033 - rk3x_i2c_fill_transmit_buf(i2c);
38034 - } else {
38035 - /* in any other case, we are going to be reading. */
38036 - i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN);
38037 - i2c->state = STATE_READ;
38038 - rk3x_i2c_prepare_read(i2c);
38039 - }
38040 -}
38041 -
38045 @@ -405,27 +484,21 @@ static void rk3x_i2c_handle_write(struct rk3x_i2c *i2c, unsigned int ipd)
38051 if (i2c->processed == i2c->msg->len)
38052 rk3x_i2c_stop(i2c, i2c->error);
38054 - rk3x_i2c_fill_transmit_buf(i2c);
38058 -static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
38062 unsigned int len = i2c->msg->len - i2c->processed;
38066 - /* we only care for MBRF here. */
38067 - if (!(ipd & REG_INT_MBRF))
38068 - return;
38069 -
38070 - /* ack interrupt (read also produces a spurious START flag, clear it too) */
38071 - i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD);
38072 -
38076 @@ -438,7 +511,21 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
38078 i2c->msg->buf[i2c->processed++] = byte;
38096 if (i2c->processed == i2c->msg->len)
38097 rk3x_i2c_stop(i2c, i2c->error);
38098 @@ -457,19 +544,31 @@ static void rk3x_i2c_handle_stop(struct rk3x_i2c *i2c, unsigned int ipd)
38102 + if (i2c->autostop_supported && !i2c->error) {
38103 + if (i2c->mode != REG_CON_MOD_TX && i2c->msg) {
38104 + if ((i2c->msg->len - i2c->processed) > 0)
38108 + i2c->processed = 0;
38109 + i2c->msg = NULL;
38118 + if (i2c->autostop_supported)
38122 i2c->busy = false;
38123 i2c->state = STATE_IDLE;
38126 - wake_up(&i2c->wait);
38131 @@ -481,7 +580,9 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
38134 if (i2c->state == STATE_IDLE) {
38135 - dev_warn(i2c->dev, "irq in STATE_IDLE, ipd = 0x%x\n", ipd);
38136 + dev_warn_ratelimited(i2c->dev,
38142 @@ -501,8 +602,15 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
38146 - if (!(i2c->msg->flags & I2C_M_IGNORE_NAK))
38147 - rk3x_i2c_stop(i2c, -ENXIO);
38148 + if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
38149 + if (i2c->autostop_supported) {
38150 + i2c->error = -ENXIO;
38151 + i2c->state = STATE_STOP;
38153 + rk3x_i2c_stop(i2c, -ENXIO);
38160 @@ -510,9 +618,6 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
38163 switch (i2c->state) {
38164 - case STATE_START:
38165 - rk3x_i2c_handle_start(i2c, ipd);
38166 - break;
38170 @@ -1032,11 +1137,12 @@ static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int n…
38172 i2c->addr = msgs[0].addr;
38173 i2c->busy = true;
38174 - i2c->state = STATE_START;
38175 i2c->processed = 0;
38176 i2c->error = 0;
38179 + if (i2c->autostop_supported)
38184 @@ -1063,6 +1169,9 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38188 + if (i2c->suspended)
38189 + return -EACCES;
38191 spin_lock_irqsave(&i2c->lock, flags);
38193 clk_enable(i2c->clk);
38194 @@ -1085,10 +1194,10 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38196 i2c->is_last_msg = true;
38198 - spin_unlock_irqrestore(&i2c->lock, flags);
38199 -
38202 + spin_unlock_irqrestore(&i2c->lock, flags);
38205 timeout = wait_event_timeout(i2c->wait, !i2c->busy,
38207 @@ -1103,7 +1212,7 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38208 i2c_readl(i2c, REG_IPD), i2c->state);
38211 - i2c_writel(i2c, 0, REG_IEN);
38216 @@ -1120,6 +1229,9 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
38223 clk_disable(i2c->pclk);
38224 clk_disable(i2c->clk);
38226 @@ -1140,12 +1252,81 @@ static int rk3x_i2c_xfer_polling(struct i2c_adapter *adap,
38230 -static __maybe_unused int rk3x_i2c_resume(struct device *dev)
38239 + if (i2c->state != STATE_IDLE) {
38240 + i2c->system_restarting = true;
38242 + while (tmo-- && i2c->busy) {
38249 + dev_err(i2c->dev, "restart timeout, ipd: 0x%02x, state: %d\n",
38250 + i2c_readl(i2c, REG_IPD), i2c->state);
38259 + i2c->state = STATE_IDLE;
38269 + clk_enable(i2c->pclk);
38271 + clk_disable(i2c->pclk);
38284 + * is trying to use I2C bus - this may cause i2c timeout.
38286 + * So forbid access to I2C device using i2c->suspended flag.
38288 + i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38289 + i2c->suspended = 1;
38290 + i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38299 rk3x_i2c_adapt_div(i2c, clk_get_rate(i2c->clk));
38302 + i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38303 + i2c->suspended = 0;
38304 + i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
38309 @@ -1161,7 +1342,12 @@ static const struct i2c_algorithm rk3x_i2c_algorithm = {
38313 - .grf_offset = -1,
38323 @@ -1195,6 +1381,10 @@ static const struct of_device_id rk3x_i2c_match[] = {
38324 .compatible = "rockchip,rv1108-i2c",
38328 + .compatible = "rockchip,rv1126-i2c",
38332 .compatible = "rockchip,rk3066-i2c",
38334 @@ -1225,7 +1415,6 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38338 - int bus_nr;
38342 @@ -1253,13 +1442,18 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38343 spin_lock_init(&i2c->lock);
38344 init_waitqueue_head(&i2c->wait);
38346 + i2c->i2c_restart_nb.notifier_call = rk3x_i2c_restart_notify;
38347 + i2c->i2c_restart_nb.priority = 128;
38348 + ret = register_pre_restart_handler(&i2c->i2c_restart_nb);
38350 + dev_err(&pdev->dev, "failed to setup i2c restart handler.\n");
38354 i2c->regs = devm_platform_ioremap_resource(pdev, 0);
38355 if (IS_ERR(i2c->regs))
38356 return PTR_ERR(i2c->regs);
38358 - /* Try to set the I2C adapter number from dt */
38359 - bus_nr = of_alias_get_id(np, "i2c");
38360 -
38364 @@ -1268,24 +1462,34 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38368 - if (IS_ERR(grf)) {
38369 - dev_err(&pdev->dev,
38370 - "rk3x-i2c needs 'rockchip,grf' property\n");
38371 - return PTR_ERR(grf);
38372 - }
38373 -
38374 - if (bus_nr < 0) {
38375 - dev_err(&pdev->dev, "rk3x-i2c needs i2cX alias");
38376 - return -EINVAL;
38377 - }
38378 -
38379 - /* 27+i: write mask, 11+i: value */
38380 - value = BIT(27 + bus_nr) | BIT(11 + bus_nr);
38381 -
38382 - ret = regmap_write(grf, i2c->soc_data->grf_offset, value);
38383 - if (ret != 0) {
38384 - dev_err(i2c->dev, "Could not write to GRF: %d\n", ret);
38385 - return ret;
38392 + dev_err(&pdev->dev, "rk3x-i2c needs i2cX alias");
38393 + return -EINVAL;
38396 + if (i2c->soc_data == &rv1108_soc_data && bus_nr == 2)
38397 + /* rv1108 i2c2 set grf offset-0x408, bit-10 */
38399 + else if (i2c->soc_data == &rv1126_soc_data &&
38401 + /* rv1126 i2c2 set pmugrf offset-0x118, bit-4 */
38407 + ret = regmap_write(grf, i2c->soc_data->grf_offset,
38410 + dev_err(i2c->dev, "Could not write to GRF: %d\n",
38417 @@ -1341,6 +1545,9 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
38418 clk_rate = clk_get_rate(i2c->clk);
38422 + i2c->autostop_supported = true;
38424 ret = i2c_add_adapter(&i2c->adap);
38427 @@ -1363,13 +1570,17 @@ static int rk3x_i2c_remove(struct platform_device *pdev)
38428 i2c_del_adapter(&i2c->adap);
38430 clk_notifier_unregister(i2c->clk, &i2c->clk_rate_nb);
38431 + unregister_pre_restart_handler(&i2c->i2c_restart_nb);
38432 clk_unprepare(i2c->pclk);
38433 clk_unprepare(i2c->clk);
38438 -static SIMPLE_DEV_PM_OPS(rk3x_i2c_pm_ops, NULL, rk3x_i2c_resume);
38446 @@ -1381,7 +1592,21 @@ static struct platform_driver rk3x_i2c_driver = {
38468 diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
38470 --- a/drivers/i2c/i2c-core-base.c
38471 +++ b/drivers/i2c/i2c-core-base.c
38472 @@ -61,6 +61,7 @@
38480 @@ -808,7 +809,8 @@ static void i2c_adapter_unlock_bus(struct i2c_adapter *adapter,
38484 - struct i2c_board_info const *info)
38488 struct acpi_device *adev = ACPI_COMPANION(&client->dev);
38490 @@ -822,8 +824,12 @@ static void i2c_dev_set_name(struct i2c_adapter *adap,
38494 - dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
38495 - i2c_encode_flags_to_addr(client));
38497 + dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
38500 + dev_set_name(&client->dev, "%d-%04x-%01x", i2c_adapter_id(adap),
38505 @@ -899,9 +905,11 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *i…
38509 - status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client));
38512 - goto out_err;
38513 + dev_err(&adap->dev,
38515 + status, client->addr);
38517 client->dev.parent = &client->adapter->dev;
38518 client->dev.bus = &i2c_bus_type;
38519 @@ -909,7 +917,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
38520 client->dev.of_node = of_node_get(info->of_node);
38521 client->dev.fwnode = info->fwnode;
38523 - i2c_dev_set_name(adap, client, info);
38526 if (info->properties) {
38527 status = device_add_properties(&client->dev, info->properties);
38528 @@ -935,10 +943,6 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *i…
38529 device_remove_properties(&client->dev);
38531 of_node_put(info->of_node);
38532 -out_err:
38533 - dev_err(&adap->dev,
38534 - "Failed to register i2c client %s at 0x%02x (%d)\n",
38535 - client->name, client->addr, status);
38539 @@ -1838,6 +1842,33 @@ EXPORT_SYMBOL(i2c_del_driver);
38541 /* ------------------------------------------------------------------------- */
38552 + int addr = addrinfo->addr;
38554 + if (client && client->addr == addr)
38555 + addrinfo->cnt++;
38566 + device_for_each_child(&adapter->dev, &addrinfo, __i2c_check_addr_ex);
38573 diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
38575 --- a/drivers/iio/adc/Kconfig
38577 @@ -876,6 +876,13 @@ config ROCKCHIP_SARADC
38591 diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
38593 --- a/drivers/iio/adc/rockchip_saradc.c
38595 @@ -35,7 +35,7 @@
38599 -#define SARADC_MAX_CHANNELS 6
38604 @@ -49,10 +49,17 @@ struct rockchip_saradc {
38622 @@ -90,6 +97,10 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
38627 + if (info->test)
38632 mutex_lock(&indio_dev->mlock);
38633 @@ -105,13 +116,11 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
38634 mutex_unlock(&indio_dev->mlock);
38637 - ret = regulator_get_voltage(info->vref);
38638 - if (ret < 0) {
38639 - dev_err(&indio_dev->dev, "failed to get voltage\n");
38640 - return ret;
38641 - }
38643 + if (info->uv_vref < 0)
38644 + return info->uv_vref;
38646 - *val = ret / 1000;
38647 + *val = info->uv_vref / 1000;
38648 *val2 = chan->scan_type.realbits;
38651 @@ -122,6 +131,9 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
38660 info->last_val = readl_relaxed(info->regs + SARADC_DATA);
38661 @@ -130,7 +142,14 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id)
38664 complete(&info->completion);
38665 -
38667 + spin_lock_irqsave(&info->lock, flags);
38668 + if (info->test) {
38669 + pr_info("chn[%d] val = %d\n", info->chn, info->last_val);
38670 + mod_timer(&info->timer, jiffies + HZ/1000);
38672 + spin_unlock_irqrestore(&info->lock, flags);
38677 @@ -192,6 +211,23 @@ static const struct rockchip_saradc_data rk3399_saradc_data = {
38701 @@ -202,6 +238,9 @@ static const struct of_device_id rockchip_saradc_match[] = {
38703 .compatible = "rockchip,rk3399-saradc",
38706 + .compatible = "rockchip,rk3568-saradc",
38711 @@ -278,6 +317,72 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
38721 + writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
38723 + /* Select the channel to be used and trigger conversion */
38724 + writel(SARADC_CTRL_POWER_CTRL | (info->chn & SARADC_CTRL_CHN_MASK) |
38725 + SARADC_CTRL_IRQ_ENABLE, info->regs + SARADC_CTRL);
38742 + spin_lock_irqsave(&info->lock, flags);
38744 + if (val > SARADC_CTRL_CHN_MASK && info->test) {
38745 + info->test = false;
38746 + del_timer_sync(&info->timer);
38747 + spin_unlock_irqrestore(&info->lock, flags);
38751 + if (!info->test && val < SARADC_CTRL_CHN_MASK) {
38752 + info->test = true;
38753 + info->chn = val;
38754 + mod_timer(&info->timer, jiffies + HZ/1000);
38757 + spin_unlock_irqrestore(&info->lock, flags);
38777 + sysfs_remove_group(&pdev->dev.kobj, &rockchip_saradc_attr_group);
38784 @@ -390,6 +495,13 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
38788 + info->uv_vref = regulator_get_voltage(info->vref);
38789 + if (info->uv_vref < 0) {
38790 + dev_err(&pdev->dev, "failed to get voltage\n");
38791 + ret = info->uv_vref;
38795 ret = clk_prepare_enable(info->pclk);
38797 dev_err(&pdev->dev, "failed to enable pclk\n");
38798 @@ -430,6 +542,21 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
38803 + spin_lock_init(&info->lock);
38804 + timer_setup(&info->timer, rockchip_saradc_timer, 0);
38805 + ret = sysfs_create_group(&pdev->dev.kobj, &rockchip_saradc_attr_group);
38809 + ret = devm_add_action_or_reset(&pdev->dev,
38812 + dev_err(&pdev->dev, "failed to register devm action, %d\n",
38817 return devm_iio_device_register(&pdev->dev, indio_dev);
38820 diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
38822 --- a/drivers/input/Kconfig
38824 @@ -197,6 +197,8 @@ source "drivers/input/tablet/Kconfig"
38833 diff --git a/drivers/input/Makefile b/drivers/input/Makefile
38835 --- a/drivers/input/Makefile
38837 @@ -24,6 +24,7 @@ obj-$(CONFIG_INPUT_MOUSE) += mouse/
38838 obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
38839 obj-$(CONFIG_INPUT_TABLET) += tablet/
38840 obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
38841 +obj-$(CONFIG_ROCKCHIP_REMOTECTL)+= remotectl/
38842 obj-$(CONFIG_INPUT_MISC) += misc/
38844 obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
38845 diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
38847 --- a/drivers/input/touchscreen/Kconfig
38849 @@ -404,6 +404,15 @@ config TOUCHSCREEN_GOODIX
38858 + on Rockchip platform, and your board-specific initialization
38865 diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
38867 --- a/drivers/input/touchscreen/Makefile
38869 @@ -45,6 +45,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
38870 obj-$(CONFIG_TOUCHSCREEN_EXC3000) += exc3000.o
38871 obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
38872 obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
38873 +obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/
38874 obj-$(CONFIG_TOUCHSCREEN_HIDEEP) += hideep.o
38875 obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
38876 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o
38877 diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
38879 --- a/drivers/iommu/Kconfig
38881 @@ -160,7 +160,8 @@ config OMAP_IOMMU_DEBUG
38885 - bool "Rockchip IOMMU Support"
38889 select IOMMU_API
38890 select ARM_DMA_USE_IOMMU
38891 diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
38893 --- a/drivers/iommu/dma-iommu.c
38894 +++ b/drivers/iommu/dma-iommu.c
38895 @@ -372,6 +372,52 @@ static int iommu_dma_deferred_attach(struct device *dev,
38900 + * Should be called prior to using dma-apis
38911 + if (!domain || !domain->iova_cookie)
38912 + return -EINVAL;
38914 + cookie = domain->iova_cookie;
38915 + iovad = &cookie->iovad;
38919 + pfn_hi = iova_pfn(iovad, base + size - 1);
38921 + return -EINVAL;
38928 + * Should be called prior to using dma-apis.
38936 + if (!domain || !domain->iova_cookie)
38937 + return -EINVAL;
38939 + iovad = &((struct iommu_dma_cookie *)domain->iova_cookie)->iovad;
38940 + iovad->best_fit = true;
38946 * dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API
38948 @@ -388,6 +434,10 @@ static int dma_info_to_prot(enum dma_data_direction dir, bool coherent,
38959 diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
38961 --- a/drivers/iommu/iommu.c
38963 @@ -8,6 +8,7 @@
38971 @@ -2203,7 +2204,8 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
38974 mutex_lock(&group->mutex);
38975 - if (iommu_group_device_count(group) != 1) {
38981 @@ -2337,38 +2339,85 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
38985 -static size_t iommu_pgsize(struct iommu_domain *domain,
38986 - unsigned long addr_merge, size_t size)
38990 - unsigned int pgsize_idx;
38991 - size_t pgsize;
38997 - /* Max page size that still fits into 'size' */
38998 - pgsize_idx = __fls(size);
39000 + pgsizes = domain->pgsize_bitmap & GENMASK(__fls(size), 0);
39002 - /* need to consider alignment requirements ? */
39003 - if (likely(addr_merge)) {
39004 - /* Max page size allowed by address */
39005 - unsigned int align_pgsize_idx = __ffs(addr_merge);
39006 - pgsize_idx = min(pgsize_idx, align_pgsize_idx);
39007 - }
39023 + pgsizes = domain->pgsize_bitmap & ~GENMASK(pgsize_idx, 0);
39027 - /* build a mask of acceptable page sizes */
39028 - pgsize = (1UL << (pgsize_idx + 1)) - 1;
39032 - /* throw away page sizes not supported by the hardware */
39033 - pgsize &= domain->pgsize_bitmap;
39038 + if ((iova ^ paddr) & (pgsize_next - 1))
39041 - /* make sure we're still sane */
39042 - BUG_ON(!pgsize);
39044 + offset = pgsize_next - (addr_merge & (pgsize_next - 1));
39046 - /* pick the biggest page */
39047 - pgsize_idx = __fls(pgsize);
39048 - pgsize = 1UL << pgsize_idx;
39065 + const struct iommu_ops *ops = domain->ops;
39074 + if (ops->map_pages) {
39075 + ret = ops->map_pages(domain, iova, paddr, pgsize, count, prot,
39078 + ret = ops->map(domain, iova, paddr, pgsize, prot, gfp);
39088 @@ -2379,7 +2428,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova,
39092 - if (unlikely(ops->map == NULL ||
39093 + if (unlikely(!(ops->map || ops->map_pages) ||
39094 domain->pgsize_bitmap == 0UL))
39095 return -ENODEV;
39097 @@ -2403,18 +2452,21 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova,
39101 - size_t pgsize = iommu_pgsize(domain, iova | paddr, size);
39104 - pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n",
39105 - iova, &paddr, pgsize);
39106 - ret = ops->map(domain, iova, paddr, pgsize, prot, gfp);
39113 + size -= mapped;
39118 - iova += pgsize;
39119 - paddr += pgsize;
39120 - size -= pgsize;
39126 @@ -2434,7 +2486,7 @@ static int _iommu_map(struct iommu_domain *domain, unsigned long iova,
39129 if (ret == 0 && ops->iotlb_sync_map)
39130 - ops->iotlb_sync_map(domain);
39131 + ops->iotlb_sync_map(domain, iova, size);
39135 @@ -2454,6 +2506,19 @@ int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova,
39143 + const struct iommu_ops *ops = domain->ops;
39147 + return ops->unmap_pages ?
39148 + ops->unmap_pages(domain, iova, pgsize, count, iotlb_gather) :
39149 + ops->unmap(domain, iova, pgsize, iotlb_gather);
39155 @@ -2463,7 +2528,7 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
39159 - if (unlikely(ops->unmap == NULL ||
39160 + if (unlikely(!(ops->unmap || ops->unmap_pages) ||
39161 domain->pgsize_bitmap == 0UL))
39164 @@ -2491,9 +2556,9 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
39168 - size_t pgsize = iommu_pgsize(domain, iova, size - unmapped);
39169 -
39170 - unmapped_page = ops->unmap(domain, iova, pgsize, iotlb_gather);
39172 + size - unmapped,
39177 @@ -2540,6 +2605,18 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
39181 + if (ops->map_sg) {
39182 + ret = ops->map_sg(domain, iova, sg, nents, prot, gfp, &mapped);
39184 + if (ops->iotlb_sync_map)
39185 + ops->iotlb_sync_map(domain, iova, mapped);
39196 @@ -2566,7 +2643,13 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
39199 if (ops->iotlb_sync_map)
39200 - ops->iotlb_sync_map(domain);
39201 + ops->iotlb_sync_map(domain, iova, mapped);
39204 + if (domain->ops->flush_iotlb_all && (prot & IOMMU_TLB_SHOT_ENTIRE))
39205 + domain->ops->flush_iotlb_all(domain);
39211 diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
39213 --- a/drivers/iommu/rockchip-iommu.c
39214 +++ b/drivers/iommu/rockchip-iommu.c
39215 @@ -19,6 +19,7 @@
39223 @@ -27,6 +28,7 @@
39231 @@ -75,25 +77,53 @@
39266 +#define PAGE_DESC_HI_SHIFT1 (PAGE_DESC_HI1_LOWER - DTE_HI1_LOWER)
39267 +#define PAGE_DESC_HI_SHIFT2 (PAGE_DESC_HI2_LOWER - DTE_HI2_LOWER)
39280 -/* list of clocks required by IOMMU */
39281 -static const char * const rk_iommu_clocks[] = {
39282 - "aclk", "iface",
39288 @@ -104,15 +134,21 @@ struct rk_iommu {
39310 @@ -174,11 +210,32 @@ static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
39316 + * 31:12 - PT address bit 31:0
39317 + * 11: 8 - PT address bit 35:32
39318 + * 7: 4 - PT address bit 39:36
39319 + * 3: 1 - Reserved
39320 + * 0 - 1 if PT @ PT address is valid
39343 @@ -189,6 +246,15 @@ static inline u32 rk_mk_dte(dma_addr_t pt_dma)
39358 * +---------------------+---+-------+-+
39359 @@ -215,11 +281,37 @@ static inline u32 rk_mk_dte(dma_addr_t pt_dma)
39365 + * 31:12 - Page address bit 31:0
39366 + * 11:9 - Page address bit 34:32
39367 + * 8:4 - Page address bit 39:35
39368 + * 3 - Security
39369 + * 2 - Writable
39370 + * 1 - Readable
39371 + * 0 - 1 if Page @ Page address is valid
39397 @@ -235,6 +327,20 @@ static u32 rk_mk_pte(phys_addr_t page, int prot)
39418 @@ -350,6 +456,10 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
39424 + if (iommu->skip_read)
39429 @@ -358,15 +468,22 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
39435 + if (iommu->skip_read)
39441 - if (ret)
39443 for (i = 0; i < iommu->num_mmu; i++)
39444 - dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n",
39445 + dev_err(iommu->dev, "Enable stall request timed out, retry_count = %d, status: %#08x\n",
39447 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39448 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39454 @@ -375,19 +492,30 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu)
39460 + if (iommu->skip_read)
39468 + if (iommu->skip_read)
39474 - if (ret)
39476 for (i = 0; i < iommu->num_mmu; i++)
39477 - dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n",
39478 + dev_err(iommu->dev, "Disable stall request timed out, retry_count = %d, status: %#08x\n",
39480 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39481 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39487 @@ -396,19 +524,30 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu)
39493 + if (iommu->skip_read)
39501 + if (iommu->skip_read)
39507 - if (ret)
39509 for (i = 0; i < iommu->num_mmu; i++)
39510 - dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n",
39511 + dev_err(iommu->dev, "Enable paging request timed out, retry_count = %d, status: %#08x\n",
39513 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39514 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39520 @@ -417,19 +556,30 @@ static int rk_iommu_disable_paging(struct rk_iommu *iommu)
39526 + if (iommu->skip_read)
39534 + if (iommu->skip_read)
39540 - if (ret)
39542 for (i = 0; i < iommu->num_mmu; i++)
39543 - dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n",
39544 + dev_err(iommu->dev, "Disable paging request timed out, retry_count = %d, status: %#08x\n",
39546 rk_iommu_read(iommu->bases[i], RK_MMU_STATUS));
39547 + if (iommu->cmd_retry && (retry_count++ < CMD_RETRY_COUNT))
39553 @@ -439,25 +589,40 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
39559 if (iommu->reset_disabled)
39562 + if (iommu->skip_read)
39573 for (i = 0; i < iommu->num_mmu; i++) {
39574 rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, DTE_ADDR_DUMMY);
39576 + if (iommu->version >= 0x2)
39580 dte_addr = rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR);
39581 - if (dte_addr != (DTE_ADDR_DUMMY & RK_DTE_PT_ADDRESS_MASK)) {
39583 dev_err(iommu->dev, "Error during raw reset. MMU_DTE_ADDR is not functioning\n");
39584 return -EFAULT;
39590 + if (iommu->skip_read)
39595 @@ -490,6 +655,10 @@ static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova)
39599 + if (iommu->version >= 0x2) {
39606 @@ -498,14 +667,20 @@ static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova)
39610 - pte_addr_phys = rk_dte_pt_address(dte) + (pte_index * 4);
39611 + if (iommu->version >= 0x2)
39621 - page_addr_phys = rk_pte_page_address(pte) + page_offset;
39622 + if (iommu->version >= 0x2)
39629 @@ -522,6 +697,7 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
39637 @@ -561,12 +737,20 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
39639 if (iommu->domain)
39640 report_iommu_fault(iommu->domain, iommu->dev, iova,
39641 - flags);
39644 dev_err(iommu->dev, "Page fault while iommu not attached to domain?\n");
39646 rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
39647 - rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_PAGE_FAULT_DONE);
39651 + * re-enter interrupt when mapping. So we postpone
39654 + int_mask = rk_iommu_read(iommu->bases[i], RK_MMU_INT_MASK);
39656 + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_PAGE_FAULT_DONE);
39660 @@ -614,6 +798,34 @@ static phys_addr_t rk_iommu_iova_to_phys(struct iommu_domain *domain,
39673 + spin_lock_irqsave(&rk_domain->dt_lock, flags);
39675 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
39687 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
39695 @@ -690,6 +902,44 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
39707 + assert_spin_locked(&rk_domain->dt_lock);
39710 + dte_addr = &rk_domain->dt[dte_index];
39717 + return ERR_PTR(-ENOMEM);
39723 + return ERR_PTR(-ENOMEM);
39731 + rk_domain->dt_dma + dte_index * sizeof(u32), 1);
39740 @@ -741,7 +991,9 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
39744 - rk_iommu_zap_iova_first_last(rk_domain, iova, size);
39746 + if (!rk_domain->shootdown_entire)
39751 @@ -757,6 +1009,53 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
39752 return -EADDRINUSE;
39763 + assert_spin_locked(&rk_domain->dt_lock);
39785 + if (!rk_domain->shootdown_entire)
39799 + return -EADDRINUSE;
39805 @@ -764,7 +1063,7 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
39809 - u32 dte_index, pte_index;
39813 spin_lock_irqsave(&rk_domain->dt_lock, flags);
39814 @@ -782,10 +1081,10 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
39818 - dte_index = rk_domain->dt[rk_iova_dte_index(iova)];
39819 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
39822 - pte_dma = rk_dte_pt_address(dte_index) + pte_index * sizeof(u32);
39827 @@ -794,6 +1093,43 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
39841 + spin_lock_irqsave(&rk_domain->dt_lock, flags);
39845 + * (1024 4-KiB pages = 4 MiB).
39852 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
39856 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
39863 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
39871 @@ -834,6 +1170,77 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
39886 + spin_lock_irqsave(&rk_domain->dt_lock, flags);
39890 + * (1024 4-KiB pages = 4 MiB).
39895 + dte = rk_domain->dt[rk_iova_dte_index(iova)];
39898 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
39907 + spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
39911 + if (!rk_domain->shootdown_entire)
39924 + spin_lock_irqsave(&rk_domain->iommus_lock, flags);
39925 + list_for_each(pos, &rk_domain->iommus) {
39931 + ret = pm_runtime_get_if_in_use(iommu->dev);
39935 + WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
39936 + for (i = 0; i < iommu->num_mmu; i++)
39937 + rk_iommu_write(iommu->bases[i], RK_MMU_COMMAND,
39939 + clk_bulk_disable(iommu->num_clocks, iommu->clocks);
39940 + pm_runtime_put(iommu->dev);
39943 + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
39949 @@ -858,12 +1265,28 @@ static void rk_iommu_disable(struct rk_iommu *iommu)
39950 clk_bulk_disable(iommu->num_clocks, iommu->clocks);
39959 + return -ENODEV;
39970 struct iommu_domain *domain = iommu->domain;
39976 ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
39978 @@ -878,10 +1301,21 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
39981 for (i = 0; i < iommu->num_mmu; i++) {
39982 - rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
39983 - rk_domain->dt_dma);
39984 + if (iommu->version >= 0x2) {
39985 + dt_v2 = (rk_domain->dt_dma & DT_LO_MASK) |
39986 + ((rk_domain->dt_dma & DT_HI_MASK) >> DT_SHIFT);
39987 + rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, dt_v2);
39989 + rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
39990 + rk_domain->dt_dma);
39992 rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
39993 rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
39996 + auto_gate = rk_iommu_read(iommu->bases[i], RK_MMU_AUTO_GATING);
39998 + rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, auto_gate);
40002 @@ -893,6 +1327,18 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
40012 + return -ENODEV;
40021 @@ -908,8 +1354,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
40025 - /* iommu already detached */
40026 - if (iommu->domain != domain)
40027 + if (!iommu->domain)
40030 iommu->domain = NULL;
40031 @@ -944,19 +1389,20 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
40035 - /* iommu already attached */
40036 - if (iommu->domain == domain)
40037 - return 0;
40038 -
40039 if (iommu->domain)
40040 rk_iommu_detach_device(iommu->domain, dev);
40042 iommu->domain = domain;
40048 spin_lock_irqsave(&rk_domain->iommus_lock, flags);
40049 list_add_tail(&iommu->node, &rk_domain->iommus);
40050 spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
40052 + rk_domain->shootdown_entire = iommu->shootdown_entire;
40053 ret = pm_runtime_get_if_in_use(iommu->dev);
40056 @@ -1054,6 +1500,35 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
40065 + WARN_ON(!list_empty(&rk_domain->iommus));
40068 + u32 dte = rk_domain->dt[i];
40080 + dma_unmap_single(dma_dev, rk_domain->dt_dma,
40082 + free_page((unsigned long)rk_domain->dt);
40084 + if (domain->type == IOMMU_DOMAIN_DMA)
40085 + iommu_put_dma_cookie(&rk_domain->domain);
40092 @@ -1068,6 +1543,16 @@ static struct iommu_device *rk_iommu_probe_device(struct device *dev)
40093 data->link = device_link_add(dev, iommu->dev,
40096 + data->defer_attach = false;
40099 + if (!dev->dma_parms)
40100 + dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL);
40101 + if (!dev->dma_parms)
40102 + return ERR_PTR(-ENOMEM);
40106 return &iommu->iommu;
40109 @@ -1087,6 +1572,14 @@ static struct iommu_group *rk_iommu_device_group(struct device *dev)
40110 return iommu_group_ref_get(iommu->group);
40118 + return data->defer_attach;
40124 @@ -1100,6 +1593,10 @@ static int rk_iommu_of_xlate(struct device *dev,
40125 iommu_dev = of_find_device_by_node(args->np);
40127 data->iommu = platform_get_drvdata(iommu_dev);
40130 + data->defer_attach = true;
40135 @@ -1107,21 +1604,90 @@ static int rk_iommu_of_xlate(struct device *dev,
40139 -static const struct iommu_ops rk_iommu_ops = {
40148 + for (i = 0; i < iommu->num_mmu; i++)
40149 + rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
40161 + for (i = 0; i < iommu->num_mmu; i++) {
40163 + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
40164 + rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
40166 + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_PAGE_FAULT_DONE);
40218 + .compatible = "rockchip,iommu-v2",
40226 struct device *dev = &pdev->dev;
40227 @@ -1129,11 +1695,21 @@ static int rk_iommu_probe(struct platform_device *pdev)
40229 int num_res = pdev->num_resources;
40236 return -ENOMEM;
40240 + return -EINVAL;
40242 + data = (struct rockchip_iommu_data *)match->data;
40243 + iommu->version = data->version;
40244 + dev_info(dev, "version = %x\n", iommu->version);
40247 iommu->dev = dev;
40248 iommu->num_mmu = 0;
40249 @@ -1161,26 +1737,30 @@ static int rk_iommu_probe(struct platform_device *pdev)
40251 iommu->reset_disabled = device_property_read_bool(dev,
40252 "rockchip,disable-mmu-reset");
40253 -
40254 - iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
40255 - iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
40256 - sizeof(*iommu->clocks), GFP_KERNEL);
40257 - if (!iommu->clocks)
40258 - return -ENOMEM;
40259 -
40260 - for (i = 0; i < iommu->num_clocks; ++i)
40261 - iommu->clocks[i].id = rk_iommu_clocks[i];
40262 + iommu->skip_read = device_property_read_bool(dev,
40263 + "rockchip,skip-mmu-read");
40264 + iommu->dlr_disable = device_property_read_bool(dev,
40265 + "rockchip,disable-device-link-resume");
40266 + iommu->shootdown_entire = device_property_read_bool(dev,
40267 + "rockchip,shootdown-entire");
40271 + iommu->cmd_retry = device_property_read_bool(dev,
40272 + "rockchip,enable-cmd-retry");
40279 - err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks);
40280 + err = devm_clk_bulk_get_all(dev, &iommu->clocks);
40281 if (err == -ENOENT)
40282 iommu->num_clocks = 0;
40283 - else if (err)
40287 + iommu->num_clocks = err;
40289 err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);
40291 @@ -1196,7 +1776,10 @@ static int rk_iommu_probe(struct platform_device *pdev)
40295 - iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
40296 + if (iommu->version >= 0x2)
40297 + iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops_v2);
40299 + iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
40300 iommu_device_set_fwnode(&iommu->iommu, &dev->of_node->fwnode);
40302 err = iommu_device_register(&iommu->iommu);
40303 @@ -1211,10 +1794,16 @@ static int rk_iommu_probe(struct platform_device *pdev)
40305 dma_dev = &pdev->dev;
40307 - bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
40308 + if (iommu->version >= 0x2)
40315 + if (iommu->skip_read)
40318 for (i = 0; i < iommu->num_irq; i++) {
40321 @@ -1229,6 +1818,7 @@ static int rk_iommu_probe(struct platform_device *pdev)
40328 iommu_device_sysfs_remove(&iommu->iommu);
40329 @@ -1260,6 +1850,9 @@ static int __maybe_unused rk_iommu_suspend(struct device *dev)
40330 if (!iommu->domain)
40333 + if (iommu->dlr_disable)
40339 @@ -1271,6 +1864,9 @@ static int __maybe_unused rk_iommu_resume(struct device *dev)
40340 if (!iommu->domain)
40343 + if (iommu->dlr_disable)
40349 @@ -1280,11 +1876,6 @@ static const struct dev_pm_ops rk_iommu_pm_ops = {
40353 -static const struct of_device_id rk_iommu_dt_ids[] = {
40354 - { .compatible = "rockchip,iommu" },
40355 - { /* sentinel */ }
40356 -};
40357 -
40361 @@ -1301,3 +1892,8 @@ static int __init rk_iommu_init(void)
40367 +MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
40368 +MODULE_ALIAS("platform:rockchip-iommu");
40370 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
40372 --- a/drivers/irqchip/Kconfig
40374 @@ -417,8 +417,9 @@ config IRQ_UNIPHIER_AIDET
40378 - bool "Meson GPIO Interrupt Multiplexer"
40379 - depends on ARCH_MESON
40383 select IRQ_DOMAIN_HIERARCHY
40386 diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
40388 --- a/drivers/irqchip/irq-gic-v3-its.c
40389 +++ b/drivers/irqchip/irq-gic-v3-its.c
40390 @@ -2167,6 +2167,8 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
40399 @@ -2290,6 +2292,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
40405 psz = baser->psz;
40407 @@ -2301,7 +2304,10 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
40411 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
40415 + page = alloc_pages_node(its->numa_node, gfp_flags, order);
40417 return -ENOMEM;
40419 @@ -2348,6 +2354,14 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
40421 tmp = baser->val;
40434 @@ -2930,6 +2944,8 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
40443 @@ -3077,6 +3093,10 @@ static void its_cpu_init_lpis(void)
40454 @@ -3101,6 +3121,10 @@ static void its_cpu_init_lpis(void)
40464 * The HW reports non-shareable, we must remove the
40465 @@ -3263,7 +3287,11 @@ static bool its_alloc_table_entry(struct its_node *its,
40469 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
40474 + page = alloc_pages_node(its->numa_node, gfp_flags,
40475 get_order(baser->psz));
40478 @@ -3352,6 +3380,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
40486 @@ -3367,7 +3396,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
40488 sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
40489 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
40490 - itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
40494 + itt = kzalloc_node(sz, gfp_flags, its->numa_node);
40498 @@ -3841,8 +3873,6 @@ static void its_vpe_schedule(struct its_vpe *vpe)
40499 val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
40502 -
40503 - its_wait_vpt_parse_complete();
40507 @@ -3890,6 +3920,10 @@ static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
40518 @@ -4051,8 +4085,6 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe,
40519 val |= FIELD_PREP(GICR_VPENDBASER_4_1_VPEID, vpe->vpe_id);
40522 -
40523 - its_wait_vpt_parse_complete();
40527 @@ -4127,6 +4159,10 @@ static int its_vpe_4_1_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
40538 @@ -4945,6 +4981,7 @@ static int __init its_probe_one(struct resource *res,
40544 its_base = ioremap(res->start, SZ_64K);
40546 @@ -5013,7 +5050,10 @@ static int __init its_probe_one(struct resource *res,
40548 its->numa_node = numa_node;
40550 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
40554 + page = alloc_pages_node(its->numa_node, gfp_flags,
40557 err = -ENOMEM;
40558 @@ -5044,6 +5084,10 @@ static int __init its_probe_one(struct resource *res,
40559 gits_write_cbaser(baser, its->base + GITS_CBASER);
40560 tmp = gits_read_cbaser(its->base + GITS_CBASER);
40569 diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
40571 --- a/drivers/irqchip/irq-gic-v3.c
40572 +++ b/drivers/irqchip/irq-gic-v3.c
40573 @@ -18,6 +18,9 @@
40582 #include <linux/irqchip/arm-gic-common.h>
40583 @@ -725,6 +728,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
40591 @@ -1325,6 +1329,27 @@ static void gic_cpu_pm_init(void)
40619 @@ -1787,6 +1812,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
40627 diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
40629 --- a/drivers/irqchip/irq-gic-v4.c
40630 +++ b/drivers/irqchip/irq-gic-v4.c
40631 @@ -232,6 +232,8 @@ int its_make_vpe_non_resident(struct its_vpe *vpe, bool db)
40633 vpe->resident = false;
40635 + vpe->ready = false;
40640 @@ -258,6 +260,23 @@ int its_make_vpe_resident(struct its_vpe *vpe, bool g0en, bool g1en)
40655 + vpe->ready = true;
40664 diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
40666 --- a/drivers/irqchip/irq-meson-gpio.c
40667 +++ b/drivers/irqchip/irq-meson-gpio.c
40668 @@ -15,6 +15,7 @@
40676 @@ -136,6 +137,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
40684 @@ -436,8 +438,8 @@ static const struct irq_domain_ops meson_gpio_irq_domain_ops = {
40688 -static int __init meson_gpio_irq_parse_dt(struct device_node *node,
40689 - struct meson_gpio_irq_controller *ctl)
40695 @@ -463,63 +465,84 @@ static int __init meson_gpio_irq_parse_dt(struct device_node *node,
40699 -static int __init meson_gpio_irq_of_init(struct device_node *node,
40700 - struct device_node *parent)
40703 - struct irq_domain *domain, *parent_domain;
40704 + struct device_node *node = pdev->dev.of_node, *parent;
40712 - pr_err("missing parent interrupt node\n");
40713 + dev_err(&pdev->dev, "missing parent interrupt node\n");
40714 return -ENODEV;
40719 - pr_err("unable to obtain parent domain\n");
40720 + dev_err(&pdev->dev, "unable to obtain parent domain\n");
40721 return -ENXIO;
40724 - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
40725 + ctl = devm_kzalloc(&pdev->dev, sizeof(*ctl), GFP_KERNEL);
40727 return -ENOMEM;
40729 spin_lock_init(&ctl->lock);
40731 - ctl->base = of_iomap(node, 0);
40732 - if (!ctl->base) {
40733 - ret = -ENOMEM;
40734 - goto free_ctl;
40735 - }
40737 + ctl->base = devm_ioremap_resource(&pdev->dev, res);
40738 + if (IS_ERR(ctl->base))
40739 + return PTR_ERR(ctl->base);
40743 - goto free_channel_irqs;
40744 -
40745 - domain = irq_domain_create_hierarchy(parent_domain, 0,
40746 - ctl->params->nr_hwirq,
40747 - of_node_to_fwnode(node),
40748 - &meson_gpio_irq_domain_ops,
40749 - ctl);
40750 - if (!domain) {
40751 - pr_err("failed to add domain\n");
40752 - ret = -ENODEV;
40753 - goto free_channel_irqs;
40756 + ctl->domain = irq_domain_create_hierarchy(parent_domain, 0,
40757 + ctl->params->nr_hwirq,
40761 + if (!ctl->domain) {
40762 + dev_err(&pdev->dev, "failed to add domain\n");
40763 + return -ENODEV;
40766 - pr_info("%d to %d gpio interrupt mux initialized\n",
40767 - ctl->params->nr_hwirq, NUM_CHANNEL);
40770 + dev_info(&pdev->dev, "%d to %d gpio interrupt mux initialized\n",
40771 + ctl->params->nr_hwirq, NUM_CHANNEL);
40776 -free_channel_irqs:
40777 - iounmap(ctl->base);
40778 -free_ctl:
40779 - kfree(ctl);
40784 - return ret;
40785 + irq_domain_remove(ctl->domain);
40790 -IRQCHIP_DECLARE(meson_gpio_intc, "amlogic,meson-gpio-intc",
40791 - meson_gpio_irq_of_init);
40793 + { .compatible = "amlogic,meson-gpio-intc", },
40802 + .name = "meson-gpio-intc",
40810 +MODULE_ALIAS("platform:meson-gpio-intc");
40811 diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c
40813 --- a/drivers/mailbox/rockchip-mailbox.c
40814 +++ b/drivers/mailbox/rockchip-mailbox.c
40815 @@ -11,6 +11,7 @@
40823 @@ -24,7 +25,7 @@
40827 - int rx_size;
40832 @@ -34,17 +35,13 @@ struct rockchip_mbox_data {
40836 - struct rockchip_mbox_msg *msg;
40837 - struct rockchip_mbox *mb;
40844 -
40845 - /* The maximum size of buf for each channel */
40846 - u32 buf_size;
40851 @@ -53,24 +50,23 @@ static int rockchip_mbox_send_data(struct mbox_chan *chan, void *data)
40853 struct rockchip_mbox *mb = dev_get_drvdata(chan->mbox->dev);
40855 - struct rockchip_mbox_chan *chans = mb->chans;
40856 + struct rockchip_mbox_chan *chans = chan->con_priv;
40860 return -EINVAL;
40862 - if (msg->rx_size > mb->buf_size) {
40863 - dev_err(mb->mbox.dev, "Transmit size over buf size(%d)\n",
40864 - mb->buf_size);
40865 - return -EINVAL;
40866 + status = readl_relaxed(mb->mbox_base + MAILBOX_A2B_STATUS);
40867 + if (status & (1U << chans->idx)) {
40868 + dev_err(mb->mbox.dev, "The mailbox channel is busy\n");
40869 + return -EBUSY;
40872 - dev_dbg(mb->mbox.dev, "Chan[%d]: A2B message, cmd 0x%08x\n",
40873 - chans->idx, msg->cmd);
40874 -
40875 - mb->chans[chans->idx].msg = msg;
40876 + dev_dbg(mb->mbox.dev, "Chan[%d]: A2B message, cmd 0x%08x, data 0x%08x\n",
40877 + chans->idx, msg->cmd, msg->data);
40879 writel_relaxed(msg->cmd, mb->mbox_base + MAILBOX_A2B_CMD(chans->idx));
40880 - writel_relaxed(msg->rx_size, mb->mbox_base +
40881 + writel_relaxed(msg->data, mb->mbox_base +
40882 MAILBOX_A2B_DAT(chans->idx));
40885 @@ -79,10 +75,15 @@ static int rockchip_mbox_send_data(struct mbox_chan *chan, void *data)
40888 struct rockchip_mbox *mb = dev_get_drvdata(chan->mbox->dev);
40889 + struct rockchip_mbox_chan *chans = chan->con_priv;
40892 - /* Enable all B2A interrupts */
40893 - writel_relaxed((1 << mb->mbox.num_chans) - 1,
40894 - mb->mbox_base + MAILBOX_B2A_INTEN);
40896 + spin_lock(&mb->cfg_lock);
40897 + val = readl_relaxed(mb->mbox_base + MAILBOX_B2A_INTEN) |
40898 + (1U << chans->idx);
40899 + writel_relaxed(val, mb->mbox_base + MAILBOX_B2A_INTEN);
40900 + spin_unlock(&mb->cfg_lock);
40904 @@ -90,12 +91,15 @@ static int rockchip_mbox_startup(struct mbox_chan *chan)
40907 struct rockchip_mbox *mb = dev_get_drvdata(chan->mbox->dev);
40908 - struct rockchip_mbox_chan *chans = mb->chans;
40909 -
40910 - /* Disable all B2A interrupts */
40911 - writel_relaxed(0, mb->mbox_base + MAILBOX_B2A_INTEN);
40912 -
40913 - mb->chans[chans->idx].msg = NULL;
40914 + struct rockchip_mbox_chan *chans = chan->con_priv;
40918 + spin_lock(&mb->cfg_lock);
40919 + val = readl_relaxed(mb->mbox_base + MAILBOX_B2A_INTEN) &
40920 + ~(1U << chans->idx);
40921 + writel_relaxed(val, mb->mbox_base + MAILBOX_B2A_INTEN);
40922 + spin_unlock(&mb->cfg_lock);
40926 @@ -107,45 +111,28 @@ static const struct mbox_chan_ops rockchip_mbox_chan_ops = {
40932 u32 status = readl_relaxed(mb->mbox_base + MAILBOX_B2A_STATUS);
40934 for (idx = 0; idx < mb->mbox.num_chans; idx++) {
40935 - if ((status & (1 << idx)) && (irq == mb->chans[idx].irq)) {
40936 + if ((status & (1U << idx)) && irq == mb->chans[idx].irq) {
40938 + msg.cmd = readl_relaxed(mb->mbox_base +
40940 + msg.data = readl_relaxed(mb->mbox_base +
40943 + dev_dbg(mb->mbox.dev, "Chan[%d]: B2A message, cmd 0x%08x, data 0x%08x\n",
40946 + if (mb->mbox.chans[idx].cl)
40947 + mbox_chan_received_data(&mb->mbox.chans[idx],
40950 - writel_relaxed(1 << idx,
40952 mb->mbox_base + MAILBOX_B2A_STATUS);
40953 - return IRQ_WAKE_THREAD;
40954 - }
40955 - }
40956 -
40957 - return IRQ_NONE;
40958 -}
40959 -
40960 -static irqreturn_t rockchip_mbox_isr(int irq, void *dev_id)
40961 -{
40962 - int idx;
40963 - struct rockchip_mbox_msg *msg = NULL;
40964 - struct rockchip_mbox *mb = (struct rockchip_mbox *)dev_id;
40965 -
40966 - for (idx = 0; idx < mb->mbox.num_chans; idx++) {
40967 - if (irq != mb->chans[idx].irq)
40968 - continue;
40969 -
40970 - msg = mb->chans[idx].msg;
40971 - if (!msg) {
40972 - dev_err(mb->mbox.dev,
40973 - "Chan[%d]: B2A message is NULL\n", idx);
40974 - break; /* spurious */
40976 -
40977 - mbox_chan_received_data(&mb->mbox.chans[idx], msg);
40978 - mb->chans[idx].msg = NULL;
40979 -
40980 - dev_dbg(mb->mbox.dev, "Chan[%d]: B2A message, cmd 0x%08x\n",
40981 - idx, msg->cmd);
40982 -
40983 - break;
40987 @@ -195,6 +182,7 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
40988 mb->mbox.num_chans = drv_data->num_chans;
40989 mb->mbox.ops = &rockchip_mbox_chan_ops;
40990 mb->mbox.txdone_irq = true;
40991 + spin_lock_init(&mb->cfg_lock);
40995 @@ -204,9 +192,6 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
40996 if (IS_ERR(mb->mbox_base))
40997 return PTR_ERR(mb->mbox_base);
40999 - /* Each channel has two buffers for A2B and B2A */
41000 - mb->buf_size = (size_t)resource_size(res) / (drv_data->num_chans * 2);
41001 -
41002 mb->pclk = devm_clk_get(&pdev->dev, "pclk_mailbox");
41003 if (IS_ERR(mb->pclk)) {
41004 ret = PTR_ERR(mb->pclk);
41005 @@ -223,20 +208,26 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
41007 for (i = 0; i < mb->mbox.num_chans; i++) {
41009 - if (irq < 0)
41010 - return irq;
41011 -
41012 - ret = devm_request_threaded_irq(&pdev->dev, irq,
41013 - rockchip_mbox_irq,
41014 - rockchip_mbox_isr, IRQF_ONESHOT,
41015 - dev_name(&pdev->dev), mb);
41016 - if (ret < 0)
41017 - return ret;
41020 + if (i > 0 && irq == -ENXIO)
41021 + mb->chans[i].irq = mb->chans[0].irq;
41025 + mb->chans[i].irq = irq;
41026 + ret = devm_request_threaded_irq(&pdev->dev, irq,
41030 + dev_name(&pdev->dev),
41036 mb->chans[i].idx = i;
41037 - mb->chans[i].irq = irq;
41038 - mb->chans[i].mb = mb;
41039 - mb->chans[i].msg = NULL;
41040 + mb->mbox.chans[i].con_priv = &mb->chans[i];
41043 ret = devm_mbox_controller_register(&pdev->dev, &mb->mbox);
41044 diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
41046 --- a/drivers/media/i2c/Kconfig
41048 @@ -384,6 +384,19 @@ config VIDEO_TC358743_CEC
41055 + select MEDIA_CONTROLLER
41056 + select VIDEO_V4L2_SUBDEV_API
41057 + select HDMI
41058 + select V4L2_FWNODE
41060 + Support for the Toshiba TC35874X HDMI to MIPI CSI-2 bridge.
41068 @@ -710,6 +723,16 @@ config VIDEO_ST_MIPID02
41071 module will be called st-mipid02.
41074 + tristate "Rockchip IR-CUT control device"
41077 + Support for the Rockchip IR-CUT control board.
41085 @@ -725,6 +748,17 @@ config VIDEO_APTINA_PLL
41093 + select V4L2_FWNODE
41101 tristate "Hynix Hi-556 sensor support"
41103 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
41105 --- a/drivers/media/i2c/Makefile
41107 @@ -108,9 +108,12 @@ obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
41108 obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
41109 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
41110 obj-$(CONFIG_VIDEO_I2C) += video-i2c.o
41111 +obj-$(CONFIG_VIDEO_RK_IRCUT) += rk_ircut.o
41112 obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
41113 obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
41114 obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
41115 +obj-$(CONFIG_VIDEO_TC35874X) += tc35874x.o
41116 +obj-$(CONFIG_VIDEO_GC8034) += gc8034.o
41117 obj-$(CONFIG_VIDEO_HI556) += hi556.o
41118 obj-$(CONFIG_VIDEO_IMX214) += imx214.o
41119 obj-$(CONFIG_VIDEO_IMX219) += imx219.o
41120 diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
41122 --- a/drivers/media/platform/Kconfig
41124 @@ -153,6 +153,9 @@ source "drivers/media/platform/xilinx/Kconfig"
41125 source "drivers/media/platform/rcar-vin/Kconfig"
41134 diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
41136 --- a/drivers/media/platform/Makefile
41138 @@ -53,6 +53,9 @@ obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
41139 obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
41141 obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/
41142 +obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip/cif/
41143 +obj-$(CONFIG_VIDEO_ROCKCHIP_ISP) += rockchip/isp/
41144 +obj-$(CONFIG_VIDEO_ROCKCHIP_ISPP) += rockchip/ispp/
41146 obj-y += omap/
41148 diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
41150 --- a/drivers/media/usb/uvc/uvc_driver.c
41152 @@ -12,6 +12,7 @@
41160 @@ -2341,7 +2342,11 @@ static int uvc_probe(struct usb_interface *intf,
41164 - usb_enable_autosuspend(udev);
41165 + if (udev->quirks & USB_QUIRK_AUTO_SUSPEND ||
41166 + udev->parent->quirks & USB_QUIRK_AUTO_SUSPEND)
41167 + uvc_printk(KERN_INFO, "auto-suspend is blacklisted for this device\n");
41173 diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
41175 --- a/drivers/media/v4l2-core/v4l2-async.c
41176 +++ b/drivers/media/v4l2-core/v4l2-async.c
41177 @@ -555,6 +555,60 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
41188 + list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
41197 + list_for_each_entry_safe(sd, tmp, &notifier->waiting, async_list) {
41198 + list_del_init(&sd->async_list);
41199 + sd->asd = NULL;
41200 + sd->dev = NULL;
41214 + while (notifier->parent)
41215 + notifier = notifier->parent;
41217 + if (!notifier->v4l2_dev)
41221 + dev_info(notifier->v4l2_dev->dev,
41238 diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
41240 --- a/drivers/mfd/rk808.c
41242 @@ -2,7 +2,7 @@
41246 - * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
41247 + * Copyright (c) 2014-2018, Fuzhou Rockchip Electronics Co., Ltd
41249 * Author: Chris Zhong <zyw@rock-chips.com>
41250 * Author: Zhang Qing <zhangqing@rock-chips.com>
41251 @@ -18,7 +18,11 @@
41263 @@ -65,22 +69,61 @@ static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
41275 - case RK817_SYS_STS:
41279 - return true;
41287 + * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
41289 + * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
41321 - .max_register = RK818_USB_CTRL_REG,
41324 - .volatile_reg = rk808_is_volatile_reg,
41329 @@ -99,11 +142,20 @@ static const struct regmap_config rk808_regmap_config = {
41345 - .cache_type = REGCACHE_NONE,
41351 @@ -111,18 +163,27 @@ static struct resource rtc_resources[] = {
41364 - DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
41375 - DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
41381 @@ -150,9 +211,28 @@ static const struct mfd_cell rk808s[] = {
41386 + { .name = "rk808-clkout", },
41387 + { .name = "rk808-regulator", },
41388 + { .name = "rk805-pinctrl", },
41389 + { .name = "rk816-battery", .of_compatible = "rk816-battery", },
41391 + .name = "rk805-pwrkey",
41396 + .name = "rk808-rtc",
41403 { .name = "rk808-clkout",},
41404 { .name = "rk808-regulator",},
41405 + { .name = "rk817-battery", .of_compatible = "rk817,battery", },
41406 + { .name = "rk817-charger", .of_compatible = "rk817,charger", },
41408 .name = "rk805-pwrkey",
41410 @@ -163,11 +243,17 @@ static const struct mfd_cell rk817s[] = {
41415 + .name = "rk817-codec",
41416 + .of_compatible = "rockchip,rk817-codec",
41421 { .name = "rk808-clkout", },
41422 { .name = "rk808-regulator", },
41423 + { .name = "rk818-battery", .of_compatible = "rk818-battery", },
41424 + { .name = "rk818-charger", },
41426 .name = "rk808-rtc",
41428 @@ -176,16 +262,18 @@ static const struct mfd_cell rk818s[] = {
41432 - {RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
41433 - RK805_BUCK1_2_ILMAX_4000MA},
41434 - {RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
41435 - RK805_BUCK1_2_ILMAX_4000MA},
41436 - {RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
41437 - RK805_BUCK3_ILMAX_3000MA},
41438 - {RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
41439 - RK805_BUCK4_ILMAX_3500MA},
41455 @@ -195,11 +283,40 @@ static const struct rk808_reg_data rk808_pre_init_reg[] = {
41496 @@ -220,8 +337,10 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
41507 @@ -301,6 +420,70 @@ static const struct regmap_irq rk808_irqs[] = {
41578 @@ -421,6 +604,61 @@ static const struct regmap_irq_chip rk808_irq_chip = {
41640 @@ -446,8 +684,70 @@ static const struct regmap_irq_chip rk818_irq_chip = {
41655 + ret = regmap_update_bits(rk808->regmap,
41659 + dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
41668 + regmap_update_bits(rk808->regmap,
41671 + regmap_update_bits(rk808->regmap,
41675 + if (rk808->pins && rk808->pins->p && rk808->pins->power_off) {
41676 + ret = regmap_update_bits(rk808->regmap,
41683 + ret = regmap_update_bits(rk808->regmap,
41690 + ret = pinctrl_select_state(rk808->pins->p,
41691 + rk808->pins->power_off);
41698 + ret = regmap_update_bits(rk808->regmap,
41702 + dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
41707 -static void rk808_pm_power_off(void)
41712 @@ -462,6 +762,10 @@ static void rk808_pm_power_off(void)
41723 @@ -469,42 +773,345 @@ static void rk808_pm_power_off(void)
41728 ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
41730 dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
41733 -static void rk8xx_shutdown(struct i2c_client *client)
41739 - struct rk808 *rk808 = i2c_get_clientdata(client);
41743 - switch (rk808->variant) {
41744 - case RK805_ID:
41745 - ret = regmap_update_bits(rk808->regmap,
41746 - RK805_GPIO_IO_POL_REG,
41747 - SLP_SD_MSK,
41748 - SHUTDOWN_FUN);
41750 + dev_warn(&rk808_i2c_client->dev,
41756 + regmap_update_bits(rk808->regmap,
41759 + regmap_update_bits(rk808->regmap,
41771 + if (rk808->variant == RK809_ID || rk808->variant == RK817_ID) {
41772 + ret = regmap_update_bits(rk808->regmap,
41777 + dev_warn(&rk808_i2c_client->dev,
41783 + dev_info(&rk808_i2c_client->dev, "System power off\n");
41786 + dev_info(&rk808_i2c_client->dev,
41838 + regmap_write(rk808->regmap, addr, data);
41839 + regmap_read(rk808->regmap, addr, &data);
41842 - case RK809_ID:
41843 - case RK817_ID:
41844 - ret = regmap_update_bits(rk808->regmap,
41845 - RK817_SYS_CFG(3),
41846 - RK817_SLPPIN_FUNC_MSK,
41847 - SLPPIN_DN_FUN);
41856 + regmap_read(rk808->regmap, addr, &data);
41860 - return;
41875 + pinctrl_dev = platform_device_alloc("rk805-pinctrl", -1);
41878 + return -ENOMEM;
41881 + pinctrl_dev->dev.parent = dev;
41887 + dev_err(dev, "Add rk805-pinctrl dev failed!\n");
41890 + if (dev->pins && !IS_ERR(dev->pins->p)) {
41895 + rk808->pins = devm_kzalloc(dev, sizeof(struct rk808_pin_info),
41897 + if (!rk808->pins)
41898 + return -ENOMEM;
41900 + rk808->pins->p = devm_pinctrl_get(dev);
41901 + if (IS_ERR(rk808->pins->p)) {
41902 + rk808->pins->p = NULL;
41907 + default_st = pinctrl_lookup_state(rk808->pins->p,
41912 + return -EINVAL;
41915 + ret = pinctrl_select_state(rk808->pins->p, default_st);
41918 + return -EINVAL;
41921 + rk808->pins->power_off = pinctrl_lookup_state(rk808->pins->p,
41922 + "pmic-power-off");
41923 + if (IS_ERR(rk808->pins->power_off)) {
41924 + rk808->pins->power_off = NULL;
41925 + dev_dbg(dev, "no power-off pinctrl state\n");
41928 + rk808->pins->sleep = pinctrl_lookup_state(rk808->pins->p,
41929 + "pmic-sleep");
41930 + if (IS_ERR(rk808->pins->sleep)) {
41931 + rk808->pins->sleep = NULL;
41932 + dev_dbg(dev, "no sleep-setting state\n");
41935 + rk808->pins->reset = pinctrl_lookup_state(rk808->pins->p,
41936 + "pmic-reset");
41937 + if (IS_ERR(rk808->pins->reset)) {
41938 + rk808->pins->reset = NULL;
41939 + dev_dbg(dev, "no reset-setting pinctrl state\n");
41943 + ret = pinctrl_select_state(rk808->pins->p, rk808->pins->reset);
41946 - dev_warn(&client->dev,
41947 - "Cannot switch to power down function\n");
41948 + dev_dbg(dev, "failed to activate reset-setting pinctrl state\n");
41973 + dev = &data->rk808->i2c->dev;
41975 + regmap_read(data->rk808->regmap, RK817_POWER_EN_SAVE0,
41978 + regmap_read(data->rk808->regmap, RK817_POWER_EN_SAVE1,
41981 + regmap_write(data->rk808->regmap,
41985 + regmap_write(data->rk808->regmap,
41989 + regmap_write(data->rk808->regmap,
41993 + regmap_write(data->rk808->regmap,
42010 + * In the case of 0b'00, PMIC reset itself which triggers SoC NPOR-reset
42018 + ret = regmap_update_bits(data->rk808->regmap,
42037 + struct device_node *np = dev->of_node;
42039 + ret = of_property_read_u32_index(np, "fb-inner-reg-idxs", 0, &inner);
42041 + regmap_update_bits(rk808->regmap, RK817_POWER_CONFIG,
42045 + regmap_update_bits(rk808->regmap, RK817_POWER_CONFIG,
42050 + ret = of_property_read_u32(np, "pmic-reset-func", &func);
42062 + regmap_update_bits(rk808->regmap, RK817_SYS_CFG(3), msk, val);
42086 @@ -517,13 +1124,20 @@ static int rk808_probe(struct i2c_client *client,
42087 struct device_node *np = client->dev.of_node;
42098 - int msb, lsb;
42099 - unsigned char pmic_id_msb, pmic_id_lsb;
42107 rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
42109 @@ -564,6 +1178,14 @@ static int rk808_probe(struct i2c_client *client,
42120 + rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare;
42123 rk808->regmap_cfg = &rk808_regmap_config;
42124 @@ -572,6 +1194,23 @@ static int rk808_probe(struct i2c_client *client,
42131 + rk808->regmap_cfg = &rk816_regmap_config;
42132 + rk808->regmap_irq_chip = &rk816_irq_chip;
42147 rk808->regmap_cfg = &rk818_regmap_config;
42148 @@ -580,6 +1219,13 @@ static int rk808_probe(struct i2c_client *client,
42162 @@ -589,6 +1235,11 @@ static int rk808_probe(struct i2c_client *client,
42168 + rk808->pm_pwroff_prep_fn = rk817_shutdown_prepare;
42173 dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
42174 @@ -597,6 +1248,7 @@ static int rk808_probe(struct i2c_client *client,
42177 rk808->i2c = client;
42181 rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
42182 @@ -605,11 +1257,50 @@ static int rk808_probe(struct i2c_client *client,
42183 return PTR_ERR(rk808->regmap);
42187 + ret = regmap_read(rk808->regmap, on_source, &on);
42189 + dev_err(&client->dev, "read 0x%x failed\n", on_source);
42193 + ret = regmap_read(rk808->regmap, off_source, &off);
42195 + dev_err(&client->dev, "read 0x%x failed\n", off_source);
42199 + dev_info(&client->dev, "source: on=0x%02x, off=0x%02x\n",
42203 if (!client->irq) {
42204 dev_err(&client->dev, "No interrupt support, no core IRQ\n");
42205 return -EINVAL;
42209 + of_property_prepare_fn(rk808, &client->dev);
42212 + ret = regmap_update_bits(rk808->regmap,
42217 + dev_err(&client->dev,
42225 + ret = pinctrl_init(&client->dev, rk808);
42230 ret = regmap_add_irq_chip(rk808->regmap, client->irq,
42231 IRQF_ONESHOT, -1,
42232 rk808->regmap_irq_chip, &rk808->irq_data);
42233 @@ -618,15 +1309,15 @@ static int rk808_probe(struct i2c_client *client,
42237 - for (i = 0; i < nr_pre_init_regs; i++) {
42238 - ret = regmap_update_bits(rk808->regmap,
42239 - pre_init_reg[i].addr,
42240 - pre_init_reg[i].mask,
42241 - pre_init_reg[i].value);
42243 + ret = regmap_add_irq_chip(rk808->regmap, client->irq,
42244 + IRQF_ONESHOT | IRQF_SHARED, -1,
42246 + &rk808->battery_irq_data);
42248 dev_err(&client->dev,
42249 - "0x%x write err\n",
42250 - pre_init_reg[i].addr);
42252 + regmap_del_irq_chip(client->irq, rk808->irq_data);
42256 @@ -639,15 +1330,34 @@ static int rk808_probe(struct i2c_client *client,
42260 - if (of_property_read_bool(np, "rockchip,system-power-controller")) {
42261 - rk808_i2c_client = client;
42262 - pm_power_off = rk808_pm_power_off;
42263 + pm_off = of_property_read_bool(np, "rockchip,system-power-controller");
42266 + pm_power_off_prepare = rk808->pm_pwroff_prep_fn;
42279 + dev_err(&client->dev, "create rk8xx sysfs error\n");
42288 regmap_del_irq_chip(client->irq, rk808->irq_data);
42290 + regmap_del_irq_chip(client->irq, rk808->battery_irq_data);
42294 @@ -656,21 +1366,45 @@ static int rk808_remove(struct i2c_client *client)
42297 regmap_del_irq_chip(client->irq, rk808->irq_data);
42298 + mfd_remove_devices(&client->dev);
42304 - if (pm_power_off == rk808_pm_power_off)
42311 + if (rk808->pm_pwroff_prep_fn &&
42312 + pm_power_off_prepare == rk808->pm_pwroff_prep_fn)
42323 - struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
42324 - int ret = 0;
42330 + ret = regmap_update_bits(rk808->regmap,
42341 switch (rk808->variant) {
42343 @@ -681,10 +1415,34 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
42347 - ret = regmap_update_bits(rk808->regmap,
42348 - RK817_SYS_CFG(3),
42349 - RK817_SLPPIN_FUNC_MSK,
42350 - SLPPIN_SLP_FUN);
42351 + if (rk808->pins && rk808->pins->p && rk808->pins->sleep) {
42352 + ret = regmap_update_bits(rk808->regmap,
42361 + ret = regmap_update_bits(rk808->regmap,
42371 + regmap_read(rk808->regmap, RK817_SYS_STS, &value);
42373 + ret = pinctrl_select_state(rk808->pins->p, rk808->pins->sleep);
42382 @@ -695,16 +1453,51 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
42386 - struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
42387 - int ret = 0;
42393 + ret = regmap_update_bits(rk808->regmap,
42404 switch (rk808->variant) {
42407 - ret = regmap_update_bits(rk808->regmap,
42408 - RK817_SYS_CFG(3),
42409 - RK817_SLPPIN_FUNC_MSK,
42410 - SLPPIN_NULL_FUN);
42411 + if (rk808->pins && rk808->pins->p && rk808->pins->reset) {
42412 + ret = regmap_update_bits(rk808->regmap,
42421 + ret = regmap_update_bits(rk808->regmap,
42431 + regmap_read(rk808->regmap, RK817_SYS_STS, &value);
42433 + ret = pinctrl_select_state(rk808->pins->p, rk808->pins->reset);
42440 @@ -712,7 +1505,7 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
42444 -static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
42449 @@ -722,10 +1515,23 @@ static struct i2c_driver rk808_i2c_driver = {
42453 - .shutdown = rk8xx_shutdown,
42473 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
42474 diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
42476 --- a/drivers/mmc/core/block.c
42478 @@ -2892,6 +2892,9 @@ static void mmc_blk_remove_debugfs(struct mmc_card *card,
42488 diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h
42490 --- a/drivers/mmc/core/block.h
42492 @@ -17,4 +17,5 @@ struct work_struct;
42498 diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
42500 --- a/drivers/mmc/core/core.h
42502 @@ -81,6 +81,8 @@ int mmc_attach_mmc(struct mmc_host *host);
42511 diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
42513 --- a/drivers/mmc/core/host.c
42515 @@ -513,15 +513,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
42519 -static int mmc_validate_host_caps(struct mmc_host *host)
42520 -{
42521 - if (host->caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) {
42522 - dev_warn(host->parent, "missing ->enable_sdio_irq() ops\n");
42523 - return -EINVAL;
42524 - }
42525 -
42526 - return 0;
42527 -}
42532 * mmc_add_host - initialise host hardware
42533 @@ -535,9 +528,8 @@ int mmc_add_host(struct mmc_host *host)
42537 - err = mmc_validate_host_caps(host);
42538 - if (err)
42539 - return err;
42540 + WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
42541 + !host->ops->enable_sdio_irq);
42543 err = device_add(&host->class_dev);
42545 @@ -591,3 +583,45 @@ void mmc_free_host(struct mmc_host *host)
42551 + * mmc_host_rescan - triger software rescan flow
42570 + return -ENOMEDIUM;
42575 + /* 0: oob 1:cap-sdio-irq */
42577 + host->caps |= MMC_CAP_SDIO_IRQ;
42579 + host->caps &= ~MMC_CAP_SDIO_IRQ;
42581 + dev_err(&host->class_dev, "sdio: host doesn't identify oob or sdio_irq mode!\n");
42582 + return -ENOMEDIUM;
42585 + if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->set_sdio_status)
42586 + host->ops->set_sdio_status(host, val);
42591 diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
42593 --- a/drivers/mmc/core/sdio.c
42595 @@ -3,9 +3,15 @@
42598 * Copyright 2006-2007 Pierre Ossman
42611 @@ -27,48 +33,6 @@
42615 -MMC_DEV_ATTR(vendor, "0x%04x\n", card->cis.vendor);
42616 -MMC_DEV_ATTR(device, "0x%04x\n", card->cis.device);
42617 -MMC_DEV_ATTR(revision, "%u.%u\n", card->major_rev, card->minor_rev);
42618 -MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
42619 -MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
42620 -
42621 -#define sdio_info_attr(num) \
42622 -static ssize_t info##num##_show(struct device *dev, struct device_attribute *attr, char *buf) \
42623 -{ \
42624 - struct mmc_card *card = mmc_dev_to_card(dev); \
42625 - \
42626 - if (num > card->num_info) \
42627 - return -ENODATA; \
42628 - if (!card->info[num-1][0]) \
42629 - return 0; \
42630 - return sprintf(buf, "%s\n", card->info[num-1]); \
42631 -} \
42632 -static DEVICE_ATTR_RO(info##num)
42633 -
42634 -sdio_info_attr(1);
42635 -sdio_info_attr(2);
42636 -sdio_info_attr(3);
42637 -sdio_info_attr(4);
42638 -
42639 -static struct attribute *sdio_std_attrs[] = {
42640 - &dev_attr_vendor.attr,
42641 - &dev_attr_device.attr,
42642 - &dev_attr_revision.attr,
42643 - &dev_attr_info1.attr,
42644 - &dev_attr_info2.attr,
42645 - &dev_attr_info3.attr,
42646 - &dev_attr_info4.attr,
42647 - &dev_attr_ocr.attr,
42648 - &dev_attr_rca.attr,
42649 - NULL,
42650 -};
42651 -ATTRIBUTE_GROUPS(sdio_std);
42652 -
42653 -static struct device_type sdio_type = {
42654 - .groups = sdio_std_groups,
42655 -};
42656 -
42660 @@ -200,18 +164,15 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
42661 if (mmc_host_uhs(card->host)) {
42663 card->sw_caps.sd3_bus_mode
42664 - |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50
42665 - | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
42669 card->sw_caps.sd3_bus_mode
42670 - |= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25
42671 - | SD_MODE_UHS_SDR12;
42675 card->sw_caps.sd3_bus_mode
42676 - |= SD_MODE_UHS_SDR104 | SD_MODE_UHS_SDR50
42677 - | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
42682 @@ -330,49 +291,30 @@ static int sdio_disable_wide(struct mmc_card *card)
42686 -static int sdio_disable_4bit_bus(struct mmc_card *card)
42687 -{
42688 - int err;
42689 -
42690 - if (card->type == MMC_TYPE_SDIO)
42691 - goto out;
42692 -
42693 - if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
42694 - return 0;
42695 -
42696 - if (!(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
42697 - return 0;
42698 -
42699 - err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1);
42700 - if (err)
42701 - return err;
42702 -
42703 -out:
42704 - return sdio_disable_wide(card);
42705 -}
42706 -
42712 - err = sdio_enable_wide(card);
42713 - if (err <= 0)
42714 - return err;
42715 if (card->type == MMC_TYPE_SDIO)
42716 - goto out;
42717 -
42718 - if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) {
42720 + else if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
42721 + (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
42723 - if (err) {
42724 - sdio_disable_wide(card);
42727 - }
42735 + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
42738 -out:
42739 - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
42741 - return 0;
42746 @@ -564,8 +506,10 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card)
42747 max_rate = min_not_zero(card->quirk_max_rate,
42748 card->sw_caps.uhs_max_dtr);
42750 - mmc_set_timing(card->host, timing);
42751 - mmc_set_clock(card->host, max_rate);
42753 + mmc_set_timing(card->host, timing);
42754 + mmc_set_clock(card->host, max_rate);
42759 @@ -605,33 +549,13 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card)
42763 -static int mmc_sdio_pre_init(struct mmc_host *host, u32 ocr,
42764 - struct mmc_card *card)
42768 - if (card)
42769 - mmc_remove_card(card);
42770 -
42771 - /*
42772 - * Reset the card by performing the same steps that are taken by
42773 - * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
42774 - *
42775 - * sdio_reset() is technically not needed. Having just powered up the
42776 - * hardware, it should already be in reset state. However, some
42777 - * platforms (such as SD8686 on OLPC) do not instantly cut power,
42778 - * meaning that a reset is required when restoring power soon after
42779 - * powering off. It is harmless in other cases.
42780 - *
42781 - * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec,
42782 - * is not necessary for non-removable cards. However, it is required
42783 - * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
42784 - * harmless in other situations.
42785 - *
42786 - */
42787 -
42790 - mmc_send_if_cond(host, ocr);
42791 - return mmc_send_io_op_cond(host, 0, NULL);
42792 + mmc_send_if_cond(host, host->ocr_avail);
42797 @@ -641,7 +565,7 @@ static int mmc_sdio_pre_init(struct mmc_host *host, u32 ocr,
42801 - struct mmc_card *oldcard)
42806 @@ -664,9 +588,25 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42810 - err = mmc_send_io_op_cond(host, ocr, &rocr);
42811 - if (err)
42812 - return err;
42814 + if (!(host->chip_alive)) {
42835 @@ -674,15 +614,17 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42839 - return err;
42846 - card = mmc_alloc_card(host, &sdio_type);
42847 - if (IS_ERR(card))
42848 - return PTR_ERR(card);
42856 mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
42857 @@ -690,15 +632,15 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42859 if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
42860 memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
42861 - err = -ENOENT;
42862 - goto mismatch;
42864 + return -ENOENT;
42867 card->type = MMC_TYPE_SDIO;
42869 if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
42870 - err = -ENOENT;
42871 - goto mismatch;
42873 + return -ENOENT;
42877 @@ -708,6 +650,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42878 if (host->ops->init_card)
42879 host->ops->init_card(host, card);
42882 card->ocr = ocr_card;
42885 @@ -721,10 +664,10 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42889 - if (rocr & ocr & R4_18V_PRESENT) {
42892 if (err == -EAGAIN) {
42893 - mmc_sdio_pre_init(host, ocr_card, card);
42895 retries--;
42898 @@ -735,10 +678,20 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42902 - if (!mmc_host_is_spi(host)) {
42905 + if (!(host->chip_alive)) {
42906 + err = mmc_send_relative_addr(host, &card->rca);
42910 + card->rca = 1;
42913 err = mmc_send_relative_addr(host, &card->rca);
42920 @@ -755,7 +708,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42921 if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
42924 - goto remove;
42929 @@ -763,7 +716,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42931 * Select card, as all following commands rely on that.
42933 - if (!mmc_host_is_spi(host)) {
42938 @@ -782,12 +735,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42939 mmc_set_timing(card->host, MMC_TIMING_SD_HS);
42942 - if (oldcard)
42943 - mmc_remove_card(card);
42944 - else
42945 - host->card = card;
42946 -
42947 - return 0;
42952 @@ -796,7 +744,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42956 - mmc_sdio_pre_init(host, ocr_card, card);
42961 @@ -813,14 +761,13 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42965 - if (card->cis.vendor == oldcard->cis.vendor &&
42966 - card->cis.device == oldcard->cis.device) {
42967 - mmc_remove_card(card);
42968 - card = oldcard;
42969 - } else {
42970 - err = -ENOENT;
42971 - goto mismatch;
42972 - }
42973 + int same = (card->cis.vendor == oldcard->cis.vendor &&
42974 + card->cis.device == oldcard->cis.device);
42977 + return -ENOENT;
42983 @@ -881,27 +828,33 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
42984 err = -EINVAL;
42987 -
42988 - host->card = card;
42991 + host->card = card;
42994 -mismatch:
42995 - pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host));
42997 - if (oldcard != card)
43005 -static int mmc_sdio_reinit_card(struct mmc_host *host)
43010 - ret = mmc_sdio_pre_init(host, host->card->ocr, NULL);
43013 + mmc_send_if_cond(host, host->card->ocr);
43019 - return mmc_sdio_init_card(host, host->card->ocr, host->card);
43020 + return mmc_sdio_init_card(host, host->card->ocr, host->card,
43025 @@ -987,37 +940,21 @@ static void mmc_sdio_detect(struct mmc_host *host)
43029 - int i;
43032 for (i = 0; i < host->card->sdio_funcs; i++) {
43033 struct sdio_func *func = host->card->sdio_func[i];
43034 if (func && sdio_func_present(func) && func->dev.driver) {
43035 const struct dev_pm_ops *pmops = func->dev.driver->pm;
43036 - if (!pmops || !pmops->suspend || !pmops->resume)
43037 + if (!pmops || !pmops->suspend || !pmops->resume) {
43039 - goto remove;
43040 + err = -ENOSYS;
43046 - return 0;
43047 -
43048 -remove:
43049 - if (!mmc_card_is_removable(host)) {
43050 - dev_warn(mmc_dev(host),
43051 - "missing suspend/resume ops for non-removable SDIO card\n");
43052 - /* Don't remove a non-removable card - we can't re-detect it. */
43053 - return 0;
43054 - }
43055 -
43056 - /* Remove the SDIO card and let it be re-detected later on. */
43057 - mmc_sdio_remove(host);
43058 - mmc_claim_host(host);
43059 - mmc_detach_bus(host);
43060 - mmc_power_off(host);
43061 - mmc_release_host(host);
43062 - host->pm_flags = 0;
43063 -
43064 - return 0;
43069 @@ -1025,8 +962,6 @@ static int mmc_sdio_pre_suspend(struct mmc_host *host)
43073 - WARN_ON(host->sdio_irqs && !mmc_card_keep_power(host));
43074 -
43076 mmc_card_set_suspended(host->card);
43077 cancel_delayed_work_sync(&host->sdio_irq_work);
43078 @@ -1034,7 +969,7 @@ static int mmc_sdio_suspend(struct mmc_host *host)
43082 - sdio_disable_4bit_bus(host->card);
43083 + sdio_disable_wide(host->card);
43087 @@ -1055,11 +990,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
43091 - /*
43092 - * Restore power and reinitialize the card when needed. Note that a
43093 - * removable card is checked from a detect work later on in the resume
43094 - * process.
43095 - */
43098 mmc_power_up(host, host->card->ocr);
43100 @@ -1073,8 +1004,12 @@ static int mmc_sdio_resume(struct mmc_host *host)
43101 pm_runtime_set_active(&host->card->dev);
43102 pm_runtime_enable(&host->card->dev);
43104 - err = mmc_sdio_reinit_card(host);
43105 - } else if (mmc_card_wake_sdio_irq(host)) {
43108 + /* No need to reinitialize powered-resumed nonremovable cards */
43112 /* We may have switched to 1-bit mode during suspend */
43113 err = sdio_enable_4bit_bus(host->card);
43115 @@ -1089,7 +1024,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
43116 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD))
43117 wake_up_process(host->sdio_irq_thread);
43118 else if (host->caps & MMC_CAP_SDIO_IRQ)
43119 - queue_delayed_work(system_wq, &host->sdio_irq_work, 0);
43120 + host->ops->enable_sdio_irq(host, 1);
43124 @@ -1099,6 +1034,38 @@ static int mmc_sdio_resume(struct mmc_host *host)
43143 + * is not necessary for non-removable cards. However, it is required
43152 + if (!ret && host->sdio_irqs)
43163 @@ -1116,42 +1083,16 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
43164 /* Restore power and re-initialize. */
43166 mmc_power_up(host, host->card->ocr);
43167 - ret = mmc_sdio_reinit_card(host);
43174 -/*
43175 - * SDIO HW reset
43176 - *
43177 - * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW
43178 - * reset was asynchronously scheduled, else a negative error code.
43179 - */
43182 - struct mmc_card *card = host->card;
43183 -
43184 - /*
43185 - * In case the card is shared among multiple func drivers, reset the
43186 - * card through a rescan work. In this way it will be removed and
43187 - * re-detected, thus all func drivers becomes informed about it.
43188 - */
43189 - if (atomic_read(&card->sdio_funcs_probed) > 1) {
43190 - if (mmc_card_removed(card))
43191 - return 1;
43192 - host->rescan_entered = 0;
43193 - mmc_card_set_removed(card);
43194 - _mmc_detect_change(host, 0, false);
43195 - return 1;
43196 - }
43197 -
43198 - /*
43199 - * A single func driver has been probed, then let's skip the heavy
43200 - * hotplug dance above and execute the reset immediately.
43201 - */
43202 - mmc_power_cycle(host, card->ocr);
43203 - return mmc_sdio_reinit_card(host);
43204 + mmc_power_cycle(host, host->card->ocr);
43209 @@ -1163,7 +1104,7 @@ static int mmc_sdio_sw_reset(struct mmc_host *host)
43213 - return mmc_sdio_reinit_card(host);
43218 @@ -1191,9 +1132,21 @@ int mmc_attach_sdio(struct mmc_host *host)
43220 WARN_ON(!host->claimed);
43223 + if (!(host->chip_alive)) {
43239 if (host->ocr_avail_sdio)
43240 @@ -1213,7 +1166,7 @@ int mmc_attach_sdio(struct mmc_host *host)
43244 - err = mmc_sdio_init_card(host, rocr, NULL);
43249 @@ -1264,6 +1217,11 @@ int mmc_attach_sdio(struct mmc_host *host)
43250 pm_runtime_enable(&card->sdio_func[i]->dev);
43254 + if (host->card->sdio_func[1])
43255 + host->card->sdio_func[1]->card_alive = host->chip_alive;
43261 @@ -1308,3 +1266,48 @@ int mmc_attach_sdio(struct mmc_host *host)
43267 + struct mmc_host *host = card->host;
43273 + if (host->chip_alive)
43274 + host->chip_alive = 0;
43282 + mmc_power_cycle(host, host->card->ocr);
43285 + mmc_set_clock(host, host->f_min);
43293 + err = -EINVAL;
43310 diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
43312 --- a/drivers/mmc/host/Makefile
43314 @@ -61,6 +61,7 @@ obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o
43315 obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
43316 obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
43317 obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
43318 +obj-$(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE) += ../../$(VENDOR_DRIVER_DIR)/mmc/host/
43319 obj-$(CONFIG_MMC_DW_ZX) += dw_mmc-zx.o
43320 obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
43321 obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
43322 diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
43324 --- a/drivers/mmc/host/dw_mmc-rockchip.c
43325 +++ b/drivers/mmc/host/dw_mmc-rockchip.c
43326 @@ -22,6 +22,9 @@ struct dw_mci_rockchip_priv_data {
43336 @@ -43,6 +46,9 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
43338 * DDR52 8-bit mode.
43340 + if (ios->clock < priv->f_min)
43341 + ios->clock = priv->f_min;
43343 if (ios->bus_width == MMC_BUS_WIDTH_8 &&
43344 ios->timing == MMC_TIMING_MMC_DDR52)
43345 cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
43346 @@ -61,7 +67,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
43350 - if (!IS_ERR(priv->sample_clk))
43351 + if (!IS_ERR(priv->sample_clk) && ios->timing <= MMC_TIMING_SD_HS)
43352 clk_set_phase(priv->sample_clk, priv->default_sample_phase);
43355 @@ -132,6 +138,42 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
43361 + struct dw_mci *host = slot->host;
43362 + struct dw_mci_rockchip_priv_data *priv = host->priv;
43363 + struct mmc_host *mmc = slot->mmc;
43370 + i = clk_get_phase(priv->sample_clk) / 90 - 1;
43376 + if (degrees[i] == priv->last_degree)
43379 + clk_set_phase(priv->sample_clk, degrees[i]);
43385 + dev_warn(host->dev, "All phases bad!");
43386 + return -EIO;
43390 + dev_info(host->dev, "Successfully tuned phase to %d\n", degrees[i]);
43391 + priv->last_degree = degrees[i];
43397 struct dw_mci *host = slot->host;
43398 @@ -155,6 +197,13 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
43399 return -EIO;
43402 + if (priv->use_v2_tuning) {
43409 ranges = kmalloc_array(priv->num_phases / 2 + 1,
43412 @@ -267,6 +316,17 @@ static int dw_mci_rk3288_parse_dt(struct dw_mci *host)
43414 return -ENOMEM;
43421 + if (of_device_is_compatible(host->dev->of_node,
43422 + "rockchip,rk3568-dw-mshc"))
43423 + priv->f_min = 375000;
43425 + priv->f_min = 100000;
43427 if (of_property_read_u32(np, "rockchip,desired-num-phases",
43428 &priv->num_phases))
43429 priv->num_phases = 360;
43430 @@ -275,6 +335,9 @@ static int dw_mci_rk3288_parse_dt(struct dw_mci *host)
43431 &priv->default_sample_phase))
43432 priv->default_sample_phase = 0;
43434 + if (of_property_read_bool(np, "rockchip,use-v2-tuning"))
43435 + priv->use_v2_tuning = true;
43437 priv->drv_clk = devm_clk_get(host->dev, "ciu-drive");
43438 if (IS_ERR(priv->drv_clk))
43439 dev_dbg(host->dev, "ciu-drive not available\n");
43440 @@ -297,6 +360,7 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
43441 "rockchip,rk3288-dw-mshc"))
43442 host->bus_hz /= RK3288_CLKGEN_DIV;
43444 + host->need_xfer_timer = true;
43448 @@ -335,28 +399,43 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
43454 if (!pdev->dev.of_node)
43455 return -ENODEV;
43457 + if (!device_property_read_bool(&pdev->dev, "non-removable") &&
43458 + !device_property_read_bool(&pdev->dev, "cd-gpios"))
43461 match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
43462 drv_data = match->data;
43468 pm_runtime_get_noresume(&pdev->dev);
43469 - pm_runtime_set_active(&pdev->dev);
43470 - pm_runtime_enable(&pdev->dev);
43471 - pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
43472 - pm_runtime_use_autosuspend(&pdev->dev);
43475 + pm_runtime_set_active(&pdev->dev);
43476 + pm_runtime_enable(&pdev->dev);
43477 + pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
43478 + pm_runtime_use_autosuspend(&pdev->dev);
43483 - pm_runtime_disable(&pdev->dev);
43484 - pm_runtime_set_suspended(&pdev->dev);
43486 + pm_runtime_disable(&pdev->dev);
43487 + pm_runtime_set_suspended(&pdev->dev);
43489 pm_runtime_put_noidle(&pdev->dev);
43493 - pm_runtime_put_autosuspend(&pdev->dev);
43495 + pm_runtime_put_autosuspend(&pdev->dev);
43499 diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
43501 --- a/drivers/mmc/host/dw_mmc.h
43503 @@ -230,6 +230,8 @@ struct dw_mci {
43512 diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
43514 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
43515 +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
43516 @@ -9,9 +9,12 @@
43519 #include <linux/dma-mapping.h>
43528 #include "sdhci-pltfm.h"
43529 @@ -21,11 +24,47 @@
43530 /* DWCMSHC specific Mode Select value */
43565 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
43577 @@ -100,6 +139,104 @@ static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
43588 + if (ios->enhanced_strobe)
43603 + host->mmc->actual_clock = 0;
43613 + err = clk_set_rate(pltfm_host->clk, clock);
43615 + dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock);
43651 + err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0,
43655 + dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n");
43660 + 0x2 << 17 | /* pre-change delay */
43661 + 0x3 << 19; /* post-change delay */
43664 + if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
43665 + host->mmc->ios.timing == MMC_TIMING_MMC_HS400)
43666 + txclk_tapnum = priv->txclk_tapnum;
43682 @@ -109,21 +246,89 @@ static const struct sdhci_ops sdhci_dwcmshc_ops = {
43713 + priv->rockchip_clks[0].id = "axi";
43714 + priv->rockchip_clks[1].id = "block";
43715 + priv->rockchip_clks[2].id = "timer";
43716 + err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), ROCKCHIP_MAX_CLKS,
43717 + priv->rockchip_clks);
43719 + dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err);
43723 + err = clk_bulk_prepare_enable(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
43725 + dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err);
43729 + if (of_property_read_u32(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum",
43730 + &priv->txclk_tapnum))
43731 + priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT;
43743 + .compatible = "snps,dwcmshc-sdhci",
43747 + .compatible = "rockchip,dwcmshc-sdhci",
43762 - host = sdhci_pltfm_init(pdev, &sdhci_dwcmshc_pdata,
43763 + pltfm_data = of_device_get_match_data(&pdev->dev);
43765 + dev_err(&pdev->dev, "Error: No device match data found\n");
43766 + return -ENODEV;
43773 @@ -160,16 +365,32 @@ static int dwcmshc_probe(struct platform_device *pdev)
43776 host->mmc_host_ops.request = dwcmshc_request;
43777 + host->mmc_host_ops.hs400_enhanced_strobe =
43790 + pm_runtime_get_noresume(&pdev->dev);
43791 + pm_runtime_set_active(&pdev->dev);
43792 + pm_runtime_enable(&pdev->dev);
43793 + pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
43794 + pm_runtime_use_autosuspend(&pdev->dev);
43795 + pm_runtime_put_autosuspend(&pdev->dev);
43800 clk_disable_unprepare(pltfm_host->clk);
43801 clk_disable_unprepare(priv->bus_clk);
43802 + clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
43806 @@ -185,6 +406,7 @@ static int dwcmshc_remove(struct platform_device *pdev)
43808 clk_disable_unprepare(pltfm_host->clk);
43809 clk_disable_unprepare(priv->bus_clk);
43810 + clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
43814 @@ -207,6 +429,7 @@ static int dwcmshc_suspend(struct device *dev)
43815 if (!IS_ERR(priv->bus_clk))
43816 clk_disable_unprepare(priv->bus_clk);
43818 + clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
43822 @@ -227,15 +450,40 @@ static int dwcmshc_resume(struct device *dev)
43826 + ret = clk_bulk_prepare_enable(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
43832 -#endif
43834 -static SIMPLE_DEV_PM_OPS(dwcmshc_pmops, dwcmshc_suspend, dwcmshc_resume);
43841 -static const struct of_device_id sdhci_dwcmshc_dt_ids[] = {
43842 - { .compatible = "snps,dwcmshc-sdhci" },
43843 - {}
43844 + priv->actual_clk = host->mmc->actual_clock;
43856 + sdhci_set_clock(host, priv->actual_clk);
43868 diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Mak…
43870 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
43872 @@ -19,7 +19,8 @@ obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
43873 obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
43874 obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
43875 obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
43876 -obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
43877 +obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rockchip.o
43878 +dwmac-rockchip-objs := dwmac-rk.o dwmac-rk-tool.o
43879 obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
43880 obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
43881 obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
43882 diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/d…
43884 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
43885 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
43886 @@ -11,6 +11,7 @@
43894 @@ -22,22 +23,30 @@
43898 -
43901 +#include "dwmac-rk-tool.h"
43926 @@ -56,6 +65,7 @@ struct rk_priv_data {
43934 @@ -63,8 +73,132 @@ struct rk_priv_data {
43966 + (((x) == 0) ? SR_MII_BASE : (SR_MII1_BASE + ((x) - 1) * 0x10000)); \
43974 + ret = regmap_read(bsp_priv->xpcs,
43987 + return regmap_write(bsp_priv->xpcs,
44002 + } while (ret & MDIO_CTRL1_RESET && --retries);
44004 + return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
44021 + int ret, i, id = bsp_priv->bus_id;
44029 + dev_err(&bsp_priv->pdev->dev, "xpcs_soft_reset fail %d\n", ret);
44067 @@ -72,8 +206,16 @@ struct rk_priv_data {
44071 - (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
44072 - ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
44086 @@ -133,6 +275,127 @@ static const struct rk_gmac_ops px30_ops = {
44114 + struct device *dev = &bsp_priv->pdev->dev;
44116 + if (IS_ERR(bsp_priv->grf)) {
44121 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44125 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON0,
44131 + struct device *dev = &bsp_priv->pdev->dev;
44133 + if (IS_ERR(bsp_priv->grf)) {
44138 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44144 + struct device *dev = &bsp_priv->pdev->dev;
44147 + if (IS_ERR(bsp_priv->grf)) {
44153 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
44158 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
44163 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 125000000);
44174 + struct device *dev = &bsp_priv->pdev->dev;
44177 + if (IS_ERR(bsp_priv->clk_mac_speed)) {
44183 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44186 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
44191 + regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
44194 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
44214 @@ -176,8 +439,7 @@ static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
44216 regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
44218 - RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
44219 - RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
44224 @@ -293,8 +555,7 @@ static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
44227 regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
44228 - RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
44229 - RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
44234 @@ -414,8 +675,7 @@ static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
44236 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
44238 - RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
44239 - RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
44244 @@ -482,6 +742,64 @@ static const struct rk_gmac_ops rk3288_ops = {
44258 + struct device *dev = &bsp_priv->pdev->dev;
44260 + if (IS_ERR(bsp_priv->grf)) {
44265 + regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
44271 + struct device *dev = &bsp_priv->pdev->dev;
44274 + if (IS_ERR(bsp_priv->clk_mac_speed)) {
44280 + regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
44283 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
44288 + regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
44291 + ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
44309 @@ -528,12 +846,10 @@ static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
44310 regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
44313 - RK3328_GMAC_RXCLK_DLY_ENABLE |
44314 - RK3328_GMAC_TXCLK_DLY_ENABLE);
44317 regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
44318 - RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
44319 - RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
44324 @@ -658,8 +974,7 @@ static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
44326 regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
44328 - RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
44329 - RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
44334 @@ -769,8 +1084,7 @@ static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
44336 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
44338 - RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
44339 - RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
44344 @@ -880,8 +1194,7 @@ static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
44346 regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
44348 - RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
44349 - RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
44354 @@ -948,6 +1261,283 @@ static const struct rk_gmac_ops rk3399_ops = {
44388 + struct device *dev = &bsp_priv->pdev->dev;
44391 + if (IS_ERR(bsp_priv->grf)) {
44396 + offset_con1 = bsp_priv->bus_id == 1 ? RK3568_GRF_GMAC1_CON1 :
44398 + regmap_write(bsp_priv->grf, offset_con1, RK3568_GMAC_GMII_MODE);
44405 + struct device *dev = &bsp_priv->pdev->dev;
44408 + if (IS_ERR(bsp_priv->grf)) {
44413 + offset_con1 = bsp_priv->bus_id == 1 ? RK3568_GRF_GMAC1_CON1 :
44415 + regmap_write(bsp_priv->grf, offset_con1, RK3568_GMAC_GMII_MODE);
44423 + struct device *dev = &bsp_priv->pdev->dev;
44426 + if (IS_ERR(bsp_priv->grf)) {
44431 + offset_con0 = (bsp_priv->bus_id == 1) ? RK3568_GRF_GMAC1_CON0 :
44433 + offset_con1 = (bsp_priv->bus_id == 1) ? RK3568_GRF_GMAC1_CON1 :
44436 + regmap_write(bsp_priv->grf, offset_con1,
44440 + regmap_write(bsp_priv->grf, offset_con0,
44446 + struct device *dev = &bsp_priv->pdev->dev;
44449 + if (IS_ERR(bsp_priv->grf)) {
44454 + offset_con1 = (bsp_priv->bus_id == 1) ? RK3568_GRF_GMAC1_CON1 :
44457 + regmap_write(bsp_priv->grf, offset_con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
44462 + struct device *dev = &bsp_priv->pdev->dev;
44481 + ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
44540 + struct device *dev = &bsp_priv->pdev->dev;
44541 + u32 offset_con, id = bsp_priv->bus_id;
44543 + if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
44548 + offset_con = bsp_priv->bus_id == 1 ? RK3588_GRF_GMAC_CON9 :
44551 + regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
44554 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
44557 + regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
44560 + regmap_write(bsp_priv->grf, offset_con,
44566 + struct device *dev = &bsp_priv->pdev->dev;
44568 + if (IS_ERR(bsp_priv->php_grf)) {
44573 + regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
44574 + RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->bus_id));
44576 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
44577 + RK3588_GMAC_CLK_RMII_MODE(bsp_priv->bus_id));
44582 + struct device *dev = &bsp_priv->pdev->dev;
44583 + unsigned int val = 0, id = bsp_priv->bus_id;
44587 + if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
44593 + if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
44599 + if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
44608 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
44618 + unsigned int val = input ? RK3588_GMAC_CLK_SELET_IO(bsp_priv->bus_id) :
44619 + RK3588_GMAC_CLK_SELET_CRU(bsp_priv->bus_id);
44621 + val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->bus_id) :
44622 + RK3588_GMAC_CLK_RMII_GATE(bsp_priv->bus_id);
44624 + regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
44638 @@ -1000,6 +1590,123 @@ static const struct rk_gmac_ops rv1108_ops = {
44669 + struct device *dev = &bsp_priv->pdev->dev;
44671 + if (IS_ERR(bsp_priv->grf)) {
44676 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
44681 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
44684 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
44690 + struct device *dev = &bsp_priv->pdev->dev;
44692 + if (IS_ERR(bsp_priv->grf)) {
44697 + regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
44703 + struct device *dev = &bsp_priv->pdev->dev;
44722 + ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
44730 + struct device *dev = &bsp_priv->pdev->dev;
44746 + ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
44762 @@ -1090,6 +1797,12 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
44766 + } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_SGMII ||
44767 + bsp_priv->phy_iface == PHY_INTERFACE_MODE_QSGMII) {
44768 + bsp_priv->pclk_xpcs = devm_clk_get(dev, "pclk_xpcs");
44769 + if (IS_ERR(bsp_priv->pclk_xpcs))
44774 bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
44775 @@ -1103,14 +1816,17 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
44776 clk_set_rate(bsp_priv->clk_mac, 50000000);
44779 - if (plat->phy_node && bsp_priv->integrated_phy) {
44780 + if (plat->phy_node) {
44781 bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
44782 - if (IS_ERR(bsp_priv->clk_phy)) {
44783 - ret = PTR_ERR(bsp_priv->clk_phy);
44784 - dev_err(dev, "Cannot get PHY clock: %d\n", ret);
44785 - return -EINVAL;
44787 + if (bsp_priv->integrated_phy) {
44788 + if (IS_ERR(bsp_priv->clk_phy)) {
44789 + ret = PTR_ERR(bsp_priv->clk_phy);
44791 + return -EINVAL;
44793 + clk_set_rate(bsp_priv->clk_phy, 50000000);
44795 - clk_set_rate(bsp_priv->clk_phy, 50000000);
44799 @@ -1151,11 +1867,18 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
44800 if (!IS_ERR(bsp_priv->clk_mac_speed))
44801 clk_prepare_enable(bsp_priv->clk_mac_speed);
44803 + if (!IS_ERR(bsp_priv->pclk_xpcs))
44804 + clk_prepare_enable(bsp_priv->pclk_xpcs);
44806 + if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
44807 + bsp_priv->ops->set_clock_selection(bsp_priv,
44808 + bsp_priv->clock_input, true);
44811 * if (!IS_ERR(bsp_priv->clk_mac))
44812 * clk_prepare_enable(bsp_priv->clk_mac);
44814 - mdelay(5);
44816 bsp_priv->clk_enabled = true;
44819 @@ -1177,6 +1900,12 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
44820 clk_disable_unprepare(bsp_priv->mac_clk_tx);
44822 clk_disable_unprepare(bsp_priv->clk_mac_speed);
44824 + clk_disable_unprepare(bsp_priv->pclk_xpcs);
44826 + if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
44827 + bsp_priv->ops->set_clock_selection(bsp_priv,
44828 + bsp_priv->clock_input, false);
44830 * if (!IS_ERR(bsp_priv->clk_mac))
44831 * clk_disable_unprepare(bsp_priv->clk_mac);
44832 @@ -1188,7 +1917,7 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
44836 -static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
44839 struct regulator *ldo = bsp_priv->regulator;
44841 @@ -1226,6 +1955,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
44843 of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
44844 bsp_priv->ops = ops;
44845 + bsp_priv->bus_id = plat->bus_id;
44847 bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
44848 if (IS_ERR(bsp_priv->regulator)) {
44849 @@ -1252,7 +1982,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
44851 ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
44853 - bsp_priv->tx_delay = 0x30;
44854 + bsp_priv->tx_delay = -1;
44857 bsp_priv->tx_delay);
44858 @@ -1263,7 +1993,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
44860 ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
44862 - bsp_priv->rx_delay = 0x10;
44863 + bsp_priv->rx_delay = -1;
44866 bsp_priv->rx_delay);
44867 @@ -1274,6 +2004,20 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
44869 bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
44871 + bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
44873 + bsp_priv->xpcs = syscon_regmap_lookup_by_phandle(dev->of_node,
44875 + if (!IS_ERR(bsp_priv->xpcs)) {
44878 + comphy = devm_of_phy_get(&pdev->dev, dev->of_node, NULL);
44886 if (plat->phy_node) {
44887 bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
44888 @@ -1307,30 +2051,45 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
44889 switch (bsp_priv->phy_iface) {
44892 - bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
44893 - bsp_priv->rx_delay);
44894 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
44895 + bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
44896 + bsp_priv->rx_delay);
44900 - bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
44901 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
44902 + bsp_priv->ops->set_to_rgmii(bsp_priv, -1, -1);
44906 - bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
44907 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
44908 + bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, -1);
44912 - bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
44913 + if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
44914 + bsp_priv->ops->set_to_rgmii(bsp_priv, -1, bsp_priv->rx_delay);
44918 - bsp_priv->ops->set_to_rmii(bsp_priv);
44919 + if (bsp_priv->ops && bsp_priv->ops->set_to_rmii)
44920 + bsp_priv->ops->set_to_rmii(bsp_priv);
44924 + if (bsp_priv->ops && bsp_priv->ops->set_to_sgmii)
44925 + bsp_priv->ops->set_to_sgmii(bsp_priv);
44929 + if (bsp_priv->ops && bsp_priv->ops->set_to_qsgmii)
44930 + bsp_priv->ops->set_to_qsgmii(bsp_priv);
44936 - ret = phy_power_on(bsp_priv, true);
44941 @@ -1351,7 +2110,7 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac)
44943 pm_runtime_put_sync(&gmac->pdev->dev);
44945 - phy_power_on(gmac, false);
44950 @@ -1365,16 +2124,96 @@ static void rk_fix_speed(void *priv, unsigned int speed)
44954 - bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
44955 + if (bsp_priv->ops && bsp_priv->ops->set_rgmii_speed)
44956 + bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
44959 - bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
44960 + if (bsp_priv->ops && bsp_priv->ops->set_rmii_speed)
44961 + bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
44967 dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
44974 + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv;
44976 + if (bsp_priv->ops->set_to_rgmii) {
44977 + bsp_priv->ops->set_to_rgmii(bsp_priv, tx_delay, rx_delay);
44978 + bsp_priv->tx_delay = tx_delay;
44979 + bsp_priv->rx_delay = rx_delay;
44987 + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv;
44989 + if (!bsp_priv->ops->set_to_rgmii)
44992 + *tx_delay = bsp_priv->tx_delay;
44993 + *rx_delay = bsp_priv->rx_delay;
44999 + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv;
45001 + return bsp_priv->phy_iface;
45008 + struct device *dev = &bsp_priv->pdev->dev;
45010 + int ret, id = bsp_priv->bus_id;
45049 @@ -1396,8 +2235,11 @@ static int rk_gmac_probe(struct platform_device *pdev)
45053 - plat_dat->has_gmac = true;
45054 + if (!of_device_is_compatible(pdev->dev.of_node, "snps,dwmac-4.20a"))
45055 + plat_dat->has_gmac = true;
45057 plat_dat->fix_mac_speed = rk_fix_speed;
45058 + plat_dat->get_eth_addr = rk_get_eth_addr;
45060 plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
45061 if (IS_ERR(plat_dat->bsp_priv)) {
45062 @@ -1417,6 +2259,10 @@ static int rk_gmac_probe(struct platform_device *pdev)
45066 + ret = dwmac_rk_create_loopback_sysfs(&pdev->dev);
45073 @@ -1433,6 +2279,7 @@ static int rk_gmac_remove(struct platform_device *pdev)
45074 int ret = stmmac_dvr_remove(&pdev->dev);
45077 + dwmac_rk_remove_loopback_sysfs(&pdev->dev);
45081 @@ -1470,14 +2317,19 @@ static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
45084 { .compatible = "rockchip,px30-gmac", .data = &px30_ops },
45085 + { .compatible = "rockchip,rk1808-gmac", .data = &rk1808_ops },
45086 { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
45087 { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
45088 { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
45089 + { .compatible = "rockchip,rk3308-mac", .data = &rk3308_ops },
45090 { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
45091 { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
45092 { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
45093 { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
45094 + { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
45095 + { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
45096 { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
45097 + { .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
45101 diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
45103 --- a/drivers/net/wireless/Kconfig
45105 @@ -48,6 +48,7 @@ source "drivers/net/wireless/st/Kconfig"
45113 diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
45115 --- a/drivers/net/wireless/Makefile
45117 @@ -30,3 +30,4 @@ obj-$(CONFIG_USB_NET_RNDIS_WLAN) += rndis_wlan.o
45118 obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
45120 obj-$(CONFIG_VIRT_WIFI) += virt_wifi.o
45121 +obj-$(CONFIG_WL_ROCKCHIP) += rockchip_wlan/
45122 diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
45124 --- a/drivers/nvmem/core.c
45126 @@ -1667,7 +1667,11 @@ static void __exit nvmem_exit(void)
45138 diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c
45140 --- a/drivers/nvmem/rockchip-efuse.c
45141 +++ b/drivers/nvmem/rockchip-efuse.c
45142 @@ -7,6 +7,7 @@
45146 +#include <linux/clk-provider.h>
45150 @@ -16,7 +17,53 @@
45154 -
45205 @@ -49,9 +96,149 @@
45209 - struct clk *clk;
45263 + mutex_lock(&efuse->mutex);
45265 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45267 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45274 + addr_len = addr_end - addr_start;
45278 + ret = -ENOMEM;
45282 + rk1808_efuse_timing_init(efuse->base);
45284 + while (addr_len--) {
45287 + efuse->base + RK1808_AUTO_CTRL);
45289 + status = readl(efuse->base + RK1808_INT_STATUS);
45291 + ret = -EIO;
45294 + out_value = readl(efuse->base + RK1808_DOUT);
45295 + writel(RK1808_INT_FINISH, efuse->base + RK1808_INT_STATUS);
45302 + rk1808_efuse_timing_deinit(efuse->base);
45305 + rk1808_efuse_timing_deinit(efuse->base);
45306 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45308 + mutex_unlock(&efuse->mutex);
45320 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45322 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45326 + writel(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL);
45328 + while (bytes--) {
45329 + writel(readl(efuse->base + REG_EFUSE_CTRL) &
45331 + efuse->base + REG_EFUSE_CTRL);
45332 + writel(readl(efuse->base + REG_EFUSE_CTRL) |
45334 + efuse->base + REG_EFUSE_CTRL);
45336 + writel(readl(efuse->base + REG_EFUSE_CTRL) |
45337 + RK3288_STROBE, efuse->base + REG_EFUSE_CTRL);
45339 + *buf++ = readb(efuse->base + REG_EFUSE_DOUT);
45340 + writel(readl(efuse->base + REG_EFUSE_CTRL) &
45341 + (~RK3288_STROBE), efuse->base + REG_EFUSE_CTRL);
45346 + writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL);
45348 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45356 @@ -59,7 +246,7 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
45360 - ret = clk_prepare_enable(efuse->clk);
45361 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45363 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45365 @@ -87,7 +274,53 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
45367 writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL);
45369 - clk_disable_unprepare(efuse->clk);
45370 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45384 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45386 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45390 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45393 + while (bytes--) {
45394 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45396 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45397 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45399 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45401 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45403 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45405 + *buf++ = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_DOUT);
45406 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45408 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45413 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45416 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45420 @@ -101,7 +334,7 @@ static int rockchip_rk3328_efuse_read(void *context, unsigned int offset,
45424 - ret = clk_prepare_enable(efuse->clk);
45425 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45427 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45429 @@ -142,11 +375,56 @@ static int rockchip_rk3328_efuse_read(void *context, unsigned int offset,
45433 - clk_disable_unprepare(efuse->clk);
45434 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45447 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45449 + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45453 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45456 + while (bytes--) {
45457 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45459 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45460 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45462 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45464 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
45466 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45468 + *buf++ = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_DOUT);
45469 + wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
45471 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
45476 + sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
45479 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45487 @@ -156,7 +434,7 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
45491 - ret = clk_prepare_enable(efuse->clk);
45492 + ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
45494 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
45496 @@ -170,8 +448,8 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
45500 - clk_disable_unprepare(efuse->clk);
45501 - return -ENOMEM;
45502 + ret = -ENOMEM;
45507 @@ -198,9 +476,10 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
45511 - clk_disable_unprepare(efuse->clk);
45513 + clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
45515 - return 0;
45520 @@ -212,6 +491,10 @@ static struct nvmem_config econfig = {
45525 + .compatible = "rockchip,rk1808-efuse",
45529 .compatible = "rockchip,rockchip-efuse",
45531 @@ -220,6 +503,10 @@ static const struct of_device_id rockchip_efuse_match[] = {
45532 .compatible = "rockchip,rk3066a-efuse",
45536 + .compatible = "rockchip,rk3128-efuse",
45540 .compatible = "rockchip,rk3188-efuse",
45542 @@ -233,13 +520,17 @@ static const struct of_device_id rockchip_efuse_match[] = {
45546 - .compatible = "rockchip,rk3368-efuse",
45547 - .data = (void *)&rockchip_rk3288_efuse_read,
45548 + .compatible = "rockchip,rk3288-secure-efuse",
45552 .compatible = "rockchip,rk3328-efuse",
45556 + .compatible = "rockchip,rk3368-efuse",
45560 .compatible = "rockchip,rk3399-efuse",
45562 @@ -268,13 +559,16 @@ static int rockchip_efuse_probe(struct platform_device *pdev)
45563 return -ENOMEM;
45566 + efuse->phys = res->start;
45567 efuse->base = devm_ioremap_resource(dev, res);
45568 if (IS_ERR(efuse->base))
45569 return PTR_ERR(efuse->base);
45571 - efuse->clk = devm_clk_get(dev, "pclk_efuse");
45572 - if (IS_ERR(efuse->clk))
45573 - return PTR_ERR(efuse->clk);
45574 + efuse->num_clks = devm_clk_bulk_get_all(dev, &efuse->clks);
45575 + if (efuse->num_clks < 1)
45576 + return -ENODEV;
45578 + mutex_init(&efuse->mutex);
45580 efuse->dev = dev;
45581 if (of_property_read_u32(dev->of_node, "rockchip,efuse-size",
45582 @@ -296,6 +590,26 @@ static struct platform_driver rockchip_efuse_driver = {
45586 -module_platform_driver(rockchip_efuse_driver);
45610 diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
45612 --- a/drivers/nvmem/rockchip-otp.c
45613 +++ b/drivers/nvmem/rockchip-otp.c
45614 @@ -263,6 +263,26 @@ static struct platform_driver rockchip_otp_driver = {
45618 -module_platform_driver(rockchip_otp_driver);
45642 diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
45644 --- a/drivers/opp/debugfs.c
45646 @@ -239,11 +239,55 @@ void opp_debug_unregister(struct opp_device *opp_dev,
45647 opp_dev->dentry = NULL;
45652 + struct list_head *lists = (struct list_head *)s->private;
45659 + seq_puts(s, "-------------------------------------------------------------------\n");
45662 + seq_printf(s, " %s\n", opp_table->dentry_name);
45663 + mutex_lock(&opp_table->lock);
45664 + list_for_each_entry(opp, &opp_table->opp_list, node) {
45666 + opp->rate,
45667 + opp->supplies[0].u_volt,
45668 + opp->supplies[0].u_volt_min,
45669 + opp->supplies[0].u_volt_max);
45671 + mutex_unlock(&opp_table->lock);
45681 + return single_open(file, opp_summary_show, inode->i_private);
45702 diff --git a/drivers/opp/of.c b/drivers/opp/of.c
45704 --- a/drivers/opp/of.c
45706 @@ -1328,7 +1328,7 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
45710 - ret = em_dev_register_perf_domain(dev, nr_opp, &em_cb, cpus);
45715 diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
45717 --- a/drivers/pci/controller/Makefile
45719 @@ -23,9 +23,9 @@ obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
45720 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
45721 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
45722 obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
45723 -obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
45724 -obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o
45725 -obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
45726 +obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o pcie-rockchip.o
45727 +pcierockchiphost-y := pcie-rockchip-host.o pcie-rockchip.o
45728 +obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcierockchiphost.o
45729 obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
45730 obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
45731 obj-$(CONFIG_VMD) += vmd.o
45732 diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
45734 --- a/drivers/pci/controller/dwc/Kconfig
45736 @@ -82,6 +82,15 @@ config PCIE_DW_PLAT_EP
45737 order to enable device-specific features PCI_DW_PLAT_EP must be
45742 + select PCIE_DW
45743 + select PCIE_DW_HOST
45752 diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
45754 --- a/drivers/pci/controller/dwc/Makefile
45756 @@ -20,6 +20,7 @@ obj-$(CONFIG_PCI_MESON) += pci-meson.o
45757 obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
45758 obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
45759 obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
45760 +obj-$(CONFIG_PCIE_DW_ROCKCHIP) += ../../../$(VENDOR_DRIVER_DIR)/pci/controller/dwc/
45764 diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designw…
45766 --- a/drivers/pci/controller/dwc/pcie-designware.h
45767 +++ b/drivers/pci/controller/dwc/pcie-designware.h
45768 @@ -42,6 +42,7 @@
45776 diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
45778 --- a/drivers/pci/controller/pcie-rockchip.c
45779 +++ b/drivers/pci/controller/pcie-rockchip.c
45780 @@ -14,6 +14,7 @@
45788 @@ -421,3 +422,7 @@ void rockchip_pcie_cfg_configuration_accesses(
45796 diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
45798 --- a/drivers/phy/rockchip/Kconfig
45800 @@ -2,6 +2,15 @@
45806 + tristate "Rockchip CSI2 D-PHY Driver"
45809 + select GENERIC_PHY
45816 @@ -28,6 +37,14 @@ config PHY_ROCKCHIP_EMMC
45823 + select GENERIC_PHY
45831 @@ -47,6 +64,14 @@ config PHY_ROCKCHIP_INNO_USB2
45838 + select GENERIC_PHY
45839 + select USB_PHY
45846 @@ -56,6 +81,40 @@ config PHY_ROCKCHIP_INNO_DSIDPHY
45851 + tristate "Rockchip MIPI RX D-PHY Driver"
45854 + select GENERIC_PHY
45856 + Enable this to support the Rockchip MIPI D-PHY with Synopsys or Innosilicon IP block.
45861 + select GENERIC_PHY
45869 + select GENERIC_PHY
45877 + select EXTCON
45879 + select GENERIC_PHY
45880 + select USB_COMMON
45887 @@ -65,6 +124,38 @@ config PHY_ROCKCHIP_PCIE
45894 + select GENERIC_PHY
45895 + select GENERIC_PHY_MIPI_DPHY
45903 + select GENERIC_PHY
45910 + select GENERIC_PHY
45918 + select GENERIC_PHY
45919 + select MFD_SYSCON
45926 @@ -80,3 +171,12 @@ config PHY_ROCKCHIP_USB
45927 select GENERIC_PHY
45934 + select GENERIC_PHY
45935 + select TYPEC
45939 diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
45941 --- a/drivers/phy/rockchip/Makefile
45943 @@ -1,10 +1,20 @@
45944 # SPDX-License-Identifier: GPL-2.0
45945 +obj-$(CONFIG_PHY_ROCKCHIP_CSI2_DPHY) += phy-rockchip-csi2-dphy-hw.o \
45946 + phy-rockchip-csi2-dphy.o
45947 obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
45948 obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0.o
45949 obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
45950 +obj-$(CONFIG_PHY_ROCKCHIP_INNO_COMBPHY) += phy-rockchip-inno-combphy.o
45951 obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
45952 -obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
45953 +obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi-phy.o
45954 obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
45955 +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o
45956 +obj-$(CONFIG_PHY_ROCKCHIP_MIPI_RX) += phy-rockchip-mipi-rx.o
45957 +obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
45958 +obj-$(CONFIG_PHY_ROCKCHIP_NANENG_EDP) += phy-rockchip-naneng-edp.o
45959 +obj-$(CONFIG_PHY_ROCKCHIP_NANENG_USB2) += phy-rockchip-naneng-usb2.o
45960 obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
45961 +obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o
45962 obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
45963 obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
45964 +obj-$(CONFIG_PHY_ROCKCHIP_USBDP) += phy-rockchip-usbdp.o
45965 diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-i…
45967 --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
45968 +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
45969 @@ -83,9 +83,31 @@
46001 @@ -101,20 +123,22 @@
46010 -#define T_HS_ZERO_CNT_MASK GENMASK(5, 0)
46011 -#define T_HS_ZERO_CNT(x) UPDATE(x, 5, 0)
46018 -#define T_HS_EXIT_CNT_MASK GENMASK(4, 0)
46019 -#define T_HS_EXIT_CNT(x) UPDATE(x, 4, 0)
46023 -#define T_CLK_POST_CNT_MASK GENMASK(3, 0)
46024 -#define T_CLK_POST_CNT(x) UPDATE(x, 3, 0)
46030 @@ -128,9 +152,13 @@
46044 @@ -168,6 +196,20 @@
46065 @@ -176,8 +218,9 @@ struct inno_dsidphy {
46069 - enum phy_mode mode;
46076 @@ -188,6 +231,12 @@ struct inno_dsidphy {
46089 @@ -199,6 +248,44 @@ enum {
46134 @@ -216,6 +303,17 @@ static void phy_update_bits(struct inno_dsidphy *inno,
46135 writel(tmp, inno->phy_base + reg);
46143 + orig = readl(inno->host_base + reg);
46146 + writel(tmp, inno->host_base + reg);
46152 @@ -286,39 +384,48 @@ static unsigned long inno_dsidphy_pll_calc_rate(struct inno_dsidphy *inno,
46156 -static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46160 - struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg;
46161 - const struct {
46162 - unsigned long rate;
46163 - u8 hs_prepare;
46164 - u8 clk_lane_hs_zero;
46165 - u8 data_lane_hs_zero;
46166 - u8 hs_trail;
46167 - } timings[] = {
46168 - { 110000000, 0x20, 0x16, 0x02, 0x22},
46169 - { 150000000, 0x06, 0x16, 0x03, 0x45},
46170 - { 200000000, 0x18, 0x17, 0x04, 0x0b},
46171 - { 250000000, 0x05, 0x17, 0x05, 0x16},
46172 - { 300000000, 0x51, 0x18, 0x06, 0x2c},
46173 - { 400000000, 0x64, 0x19, 0x07, 0x33},
46174 - { 500000000, 0x20, 0x1b, 0x07, 0x4e},
46175 - { 600000000, 0x6a, 0x1d, 0x08, 0x3a},
46176 - { 700000000, 0x3e, 0x1e, 0x08, 0x6a},
46177 - { 800000000, 0x21, 0x1f, 0x09, 0x29},
46178 - {1000000000, 0x09, 0x20, 0x09, 0x27},
46179 - };
46180 - u32 t_txbyteclkhs, t_txclkesc;
46181 - u32 txbyteclkhs, txclkesc, esc_clk_div;
46182 - u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait;
46183 - u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero;
46186 + unsigned int lane_mbps = inno->pll.rate / USEC_PER_SEC;
46189 - inno_dsidphy_pll_calc_rate(inno, cfg->hs_clk_rate);
46190 + timings = inno->pdata->inno_mipi_dphy_timing_table;
46191 + num_timings = inno->pdata->num_timings;
46193 - /* Select MIPI mode */
46194 - phy_update_bits(inno, REGISTER_PART_LVDS, 0x03,
46195 - MODE_ENABLE_MASK, MIPI_MODE_ENABLE);
46201 + --i;
46210 + REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv));
46212 + REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv));
46214 + REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv));
46229 REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv));
46230 @@ -330,6 +437,10 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46241 @@ -342,6 +453,17 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46249 + struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg;
46257 txbyteclkhs = inno->pll.rate / 8;
46259 @@ -365,15 +487,6 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46260 * Tclk-pre = Tpin_txbyteclkhs * value
46262 clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
46263 -
46264 - /*
46265 - * The value of counter for HS Tlpx Time
46266 - * Tlpx = Tpin_txbyteclkhs * (2 + value)
46267 - */
46268 - lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs);
46269 - if (lpx >= 2)
46270 - lpx -= 2;
46271 -
46273 * The value of counter for HS Tta-go
46274 * Tta-go for turnaround
46275 @@ -393,17 +506,22 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46277 ta_wait = DIV_ROUND_UP(cfg->ta_get, t_txclkesc);
46279 - for (i = 0; i < ARRAY_SIZE(timings); i++)
46280 - if (inno->pll.rate <= timings[i].rate)
46281 - break;
46282 -
46283 - if (i == ARRAY_SIZE(timings))
46284 - --i;
46285 -
46286 - hs_prepare = timings[i].hs_prepare;
46287 - hs_trail = timings[i].hs_trail;
46288 - clk_lane_hs_zero = timings[i].clk_lane_hs_zero;
46289 - data_lane_hs_zero = timings[i].data_lane_hs_zero;
46295 + if (inno->pdata->max_rate == MAX_1GHZ) {
46296 + lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs);
46298 + lpx -= 2;
46300 + lpx = timing->lpx;
46302 + hs_prepare = timing->hs_prepare;
46303 + hs_trail = timing->hs_trail;
46304 + clk_lane_hs_zero = timing->clk_lane_hs_zero;
46305 + data_lane_hs_zero = timing->data_lane_hs_zero;
46309 @@ -416,14 +534,29 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46313 - phy_update_bits(inno, i, 0x07, T_HS_ZERO_CNT_MASK,
46314 - T_HS_ZERO_CNT(hs_zero));
46316 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46324 - phy_update_bits(inno, i, 0x09, T_HS_EXIT_CNT_MASK,
46325 - T_HS_EXIT_CNT(hs_exit));
46326 - phy_update_bits(inno, i, 0x0a, T_CLK_POST_CNT_MASK,
46327 - T_CLK_POST_CNT(clk_post));
46329 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46336 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46345 @@ -437,11 +570,46 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
46351 - /* Enable all lanes on analog part */
46352 - phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00,
46353 - LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 |
46354 - LANE_EN_1 | LANE_EN_0);
46359 + switch (inno->lanes) {
46380 + /* Select MIPI mode */
46384 + if (inno->pdata->max_rate == MAX_2_5GHZ)
46396 @@ -451,8 +619,9 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
46400 - SAMPLE_CLOCK_DIRECTION_MASK,
46401 - SAMPLE_CLOCK_DIRECTION_REVERSE);
46406 /* Select LVDS mode */
46408 @@ -472,6 +641,10 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
46412 + /* Select PLL mode */
46419 @@ -491,9 +664,36 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
46425 + /* Select TTL mode */
46454 clk_prepare_enable(inno->pclk_phy);
46455 clk_prepare_enable(inno->ref_clk);
46456 @@ -506,7 +706,7 @@ static int inno_dsidphy_power_on(struct phy *phy)
46460 - switch (inno->mode) {
46465 @@ -514,7 +714,7 @@ static int inno_dsidphy_power_on(struct phy *phy)
46469 - return -EINVAL;
46474 @@ -551,17 +751,6 @@ static int inno_dsidphy_power_off(struct phy *phy)
46478 - struct inno_dsidphy *inno = phy_get_drvdata(phy);
46479 -
46480 - switch (mode) {
46481 - case PHY_MODE_MIPI_DPHY:
46482 - case PHY_MODE_LVDS:
46483 - inno->mode = mode;
46484 - break;
46485 - default:
46486 - return -EINVAL;
46487 - }
46488 -
46492 @@ -569,9 +758,11 @@ static int inno_dsidphy_configure(struct phy *phy,
46496 + struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg;
46500 - if (inno->mode != PHY_MODE_MIPI_DPHY)
46502 return -EINVAL;
46504 ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
46505 @@ -580,6 +771,32 @@ static int inno_dsidphy_configure(struct phy *phy,
46507 memcpy(&inno->dphy_cfg, &opts->mipi_dphy, sizeof(inno->dphy_cfg));
46509 + inno_dsidphy_pll_calc_rate(inno, cfg->hs_clk_rate);
46510 + cfg->hs_clk_rate = inno->pll.rate;
46511 + opts->mipi_dphy.hs_clk_rate = inno->pll.rate;
46520 + clk_prepare_enable(inno->pclk_phy);
46521 + clk_prepare_enable(inno->ref_clk);
46522 + pm_runtime_get_sync(inno->dev);
46531 + pm_runtime_put(inno->dev);
46532 + clk_disable_unprepare(inno->ref_clk);
46533 + clk_disable_unprepare(inno->pclk_phy);
46538 @@ -588,6 +805,8 @@ static const struct phy_ops inno_dsidphy_ops = {
46547 @@ -597,6 +816,7 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46555 @@ -604,12 +824,23 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46556 return -ENOMEM;
46558 inno->dev = dev;
46559 + inno->pdata = of_device_get_match_data(inno->dev);
46562 - inno->phy_base = devm_platform_ioremap_resource(pdev, 0);
46563 + inno->phy_base = devm_platform_ioremap_resource_byname(pdev, "phy");
46564 if (IS_ERR(inno->phy_base))
46565 return PTR_ERR(inno->phy_base);
46570 + return -EINVAL;
46573 + inno->host_base = devm_ioremap(dev, res->start, resource_size(res));
46574 + if (IS_ERR(inno->host_base))
46575 + return PTR_ERR(inno->host_base);
46577 inno->ref_clk = devm_clk_get(dev, "ref");
46578 if (IS_ERR(inno->ref_clk)) {
46579 ret = PTR_ERR(inno->ref_clk);
46580 @@ -624,6 +855,13 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46584 + inno->pclk_host = devm_clk_get(dev, "pclk_host");
46585 + if (IS_ERR(inno->pclk_host)) {
46586 + ret = PTR_ERR(inno->pclk_host);
46591 inno->rst = devm_reset_control_get(dev, "apb");
46592 if (IS_ERR(inno->rst)) {
46593 ret = PTR_ERR(inno->rst);
46594 @@ -638,6 +876,9 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46598 + if (of_property_read_u32(dev->of_node, "inno,lanes", &inno->lanes))
46599 + inno->lanes = 4;
46604 @@ -652,6 +893,18 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
46623 @@ -662,9 +915,18 @@ static int inno_dsidphy_remove(struct platform_device *pdev)
46627 - { .compatible = "rockchip,px30-dsi-dphy", },
46628 - { .compatible = "rockchip,rk3128-dsi-dphy", },
46629 - { .compatible = "rockchip,rk3368-dsi-dphy", },
46630 + { .compatible = "rockchip,px30-dsi-dphy",
46633 + .compatible = "rockchip,rk3128-dsi-dphy",
46636 + .compatible = "rockchip,rk3368-dsi-dphy",
46639 + .compatible = "rockchip,rk3568-dsi-dphy",
46645 diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno
46647 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
46648 +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
46649 @@ -22,15 +22,22 @@
46664 -#define OTG_SCHEDULE_DELAY (2 * HZ)
46673 @@ -69,6 +76,7 @@ enum usb_chg_state {
46681 @@ -95,7 +103,7 @@ struct usb2phy_reg {
46685 - * @opmode: utmi operational mode.
46690 @@ -107,7 +115,7 @@ struct rockchip_chg_det_reg {
46694 - struct usb2phy_reg opmode;
46699 @@ -116,32 +124,81 @@ struct rockchip_chg_det_reg {
46705 + * @bypass_sel: usb bypass uart select register.
46720 + * @iddig_en: utmi iddig select between grf and phy,
46773 * struct rockchip_usb2phy_cfg - usb-phy configuration.
46774 * @reg: the address offset of grf for usb-phy config.
46779 * @port_cfgs: usb-phy port configurations.
46781 @@ -149,6 +206,8 @@ struct rockchip_usb2phy_port_cfg {
46790 @@ -158,16 +217,30 @@ struct rockchip_usb2phy_cfg {
46791 * struct rockchip_usb2phy_port - usb-phy port data.
46798 + * @typec_vbus_det: Type-C otg vbus detect.
46800 + * true - use avalid to get vbus status
46801 + * false - use bvalid to get vbus status
46810 * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
46811 * irqs to one irq in otg-port.
46821 @@ -176,17 +249,30 @@ struct rockchip_usb2phy_cfg {
46852 @@ -196,6 +282,8 @@ struct rockchip_usb2phy_port {
46861 @@ -203,6 +291,12 @@ struct rockchip_usb2phy_port {
46874 @@ -211,12 +305,18 @@ struct rockchip_usb2phy {
46893 @@ -254,6 +354,25 @@ static inline bool property_enabled(struct regmap *base,
46894 return tmp == reg->enable;
46901 + ret = reset_control_assert(rphy->phy_reset);
46907 + ret = reset_control_deassert(rphy->phy_reset);
46919 @@ -319,7 +438,7 @@ static int
46922 struct device_node *node = rphy->dev->of_node;
46923 - struct clk_init_data init;
46928 @@ -393,6 +512,8 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
46929 dev_err(rphy->dev, "failed to register extcon device\n");
46933 + rphy->edev_self = true;
46936 rphy->edev = edev;
46937 @@ -400,6 +521,177 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
46941 +/* The caller must hold rport->mutex lock */
46948 + ret = property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr, true);
46952 + ret = property_enable(rphy->grf, &rport->port_cfg->idfall_det_en, en);
46956 + ret = property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr, true);
46960 + ret = property_enable(rphy->grf, &rport->port_cfg->idrise_det_en, en);
46965 +/* The caller must hold rport->mutex lock */
46972 + ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
46976 + ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_en, en);
46987 + ret = property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
46991 + ret = property_enable(rphy->grf, &rport->port_cfg->ls_det_en, en);
47002 + ret = property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true);
47006 + ret = property_enable(rphy->grf, &rport->port_cfg->disfall_en, en);
47010 + ret = property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true);
47014 + ret = property_enable(rphy->grf, &rport->port_cfg->disrise_en, en);
47022 + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47023 + const struct usb2phy_reg *iomux = &rport->port_cfg->bypass_iomux;
47027 + mutex_lock(&rport->mutex);
47029 + if (en == property_enabled(base, &rport->port_cfg->bypass_sel)) {
47030 + dev_info(&rport->phy->dev,
47035 + dev_info(&rport->phy->dev, "bypass uart %s\n", en ? "on" : "off");
47044 + * in non-driving mode to disable resistance when use USB
47046 + * set phy in non-driving mode, it will cause UART to print
47049 + ret |= property_enable(base, &rport->port_cfg->bypass_sel,
47051 + ret |= property_enable(base, &rport->port_cfg->bypass_dm_en,
47055 + if (iomux->offset)
47056 + ret |= property_enable(rphy->grf, iomux, true);
47059 + ret |= property_enable(base, &rport->port_cfg->bypass_sel,
47061 + ret |= property_enable(base, &rport->port_cfg->bypass_dm_en,
47065 + if (iomux->offset)
47066 + ret |= property_enable(rphy->grf, iomux, false);
47070 + mutex_unlock(&rport->mutex);
47080 + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47084 + mutex_lock(&rport->mutex);
47086 + iddig = property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig);
47088 + if (rport->utmi_avalid)
47089 + vbus = property_enabled(rphy->grf, &rport->port_cfg->utmi_avalid);
47091 + vbus = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
47093 + mutex_unlock(&rport->mutex);
47104 + dev_warn(&rport->phy->dev,
47107 + schedule_delayed_work(&rport->bypass_uart_work,
47115 @@ -408,39 +700,50 @@ static int rockchip_usb2phy_init(struct phy *phy)
47117 mutex_lock(&rport->mutex);
47119 - if (rport->port_id == USB2PHY_PORT_OTG) {
47120 - if (rport->mode != USB_DR_MODE_HOST &&
47121 - rport->mode != USB_DR_MODE_UNKNOWN) {
47122 - /* clear bvalid status and enable bvalid detect irq */
47123 - ret = property_enable(rphy->grf,
47124 - &rport->port_cfg->bvalid_det_clr,
47125 - true);
47126 - if (ret)
47127 + if (rport->port_id == USB2PHY_PORT_OTG &&
47128 + (rport->mode == USB_DR_MODE_PERIPHERAL ||
47129 + rport->mode == USB_DR_MODE_OTG)) {
47131 + if (rport->id_irq > 0 || rport->otg_mux_irq > 0 ||
47132 + rphy->irq > 0) {
47136 + dev_err(rphy->dev,
47142 - ret = property_enable(rphy->grf,
47143 - &rport->port_cfg->bvalid_det_en,
47144 - true);
47145 - if (ret)
47147 + if ((rport->bvalid_irq > 0 || rport->otg_mux_irq > 0 ||
47148 + rphy->irq > 0) && !rport->vbus_always_on) {
47152 + dev_err(rphy->dev,
47157 - schedule_delayed_work(&rport->otg_sm_work,
47158 - OTG_SCHEDULE_DELAY * 3);
47159 - } else {
47160 - /* If OTG works in host only mode, do nothing. */
47161 - dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
47162 + schedule_delayed_work(&rport->otg_sm_work, 0);
47164 } else if (rport->port_id == USB2PHY_PORT_HOST) {
47165 - /* clear linestate and enable linestate detect irq */
47166 - ret = property_enable(rphy->grf,
47167 - &rport->port_cfg->ls_det_clr, true);
47168 - if (ret)
47169 - goto out;
47170 + if (rport->port_cfg->disfall_en.offset) {
47171 + rport->host_disconnect = true;
47174 + dev_err(rphy->dev, "failed to enable disconnect irq\n");
47179 - ret = property_enable(rphy->grf,
47180 - &rport->port_cfg->ls_det_en, true);
47181 - if (ret)
47185 + dev_err(rphy->dev, "failed to enable linestate irq\n");
47189 schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
47191 @@ -459,22 +762,56 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
47193 dev_dbg(&rport->phy->dev, "port power on\n");
47195 - if (!rport->suspended)
47196 - return 0;
47197 + if (rport->bypass_uart_en) {
47200 + dev_warn(&rport->phy->dev,
47206 + mutex_lock(&rport->mutex);
47208 + if (!rport->suspended) {
47213 ret = clk_prepare_enable(rphy->clk480m);
47215 - return ret;
47218 ret = property_enable(base, &rport->port_cfg->phy_sus, false);
47220 - return ret;
47238 rport->suspended = false;
47239 - return 0;
47242 + mutex_unlock(&rport->mutex);
47245 + if (rport->bypass_uart_en)
47246 + schedule_delayed_work(&rport->bypass_uart_work, 0);
47253 @@ -486,42 +823,258 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
47255 dev_dbg(&rport->phy->dev, "port power off\n");
47257 - if (rport->suspended)
47258 - return 0;
47259 + mutex_lock(&rport->mutex);
47261 + if (rport->suspended) {
47266 ret = property_enable(base, &rport->port_cfg->phy_sus, true);
47268 - return ret;
47271 rport->suspended = true;
47272 clk_disable_unprepare(rphy->clk480m);
47274 - return 0;
47276 + mutex_unlock(&rport->mutex);
47279 + if (rport->bypass_uart_en)
47280 + schedule_delayed_work(&rport->bypass_uart_work, 0);
47289 - if (rport->port_id == USB2PHY_PORT_OTG &&
47290 - rport->mode != USB_DR_MODE_HOST &&
47291 - rport->mode != USB_DR_MODE_UNKNOWN) {
47292 - cancel_delayed_work_sync(&rport->otg_sm_work);
47293 - cancel_delayed_work_sync(&rport->chg_work);
47294 - } else if (rport->port_id == USB2PHY_PORT_HOST)
47295 + if (rport->port_id == USB2PHY_PORT_HOST)
47296 cancel_delayed_work_sync(&rport->sm_work);
47297 + else if (rport->port_id == USB2PHY_PORT_OTG &&
47298 + rport->bvalid_irq > 0)
47299 + flush_delayed_work(&rport->otg_sm_work);
47309 + if (!rport->vbus)
47312 + if (en && !rport->vbus_enabled) {
47313 + ret = regulator_enable(rport->vbus);
47315 + dev_err(&rport->phy->dev,
47317 + } else if (!en && rport->vbus_enabled) {
47318 + ret = regulator_disable(rport->vbus);
47322 + rport->vbus_enabled = en;
47331 + struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
47335 + if (rport->port_id != USB2PHY_PORT_OTG)
47348 + extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, false);
47350 + extcon_set_state(rphy->edev, EXTCON_USB, true);
47351 + rport->perip_connected = true;
47358 + dev_err(&rport->phy->dev,
47363 + extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, true);
47365 + extcon_set_state(rphy->edev, EXTCON_USB, false);
47366 + rport->perip_connected = false;
47372 + dev_info(&rport->phy->dev, "illegal mode\n");
47376 + if (rphy->phy_cfg->vbus_detect)
47377 + rphy->phy_cfg->vbus_detect(rphy, vbus_det_en);
47379 + ret = property_enable(rphy->grf, &rport->port_cfg->vbus_det_en,
47403 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
47404 + rport = &rphy->ports[index];
47405 + if (rport->port_id == USB2PHY_PORT_OTG)
47410 + dev_err(rphy->dev, "Fail to get otg port\n");
47411 + return -EINVAL;
47412 + } else if (rport->port_id != USB2PHY_PORT_OTG) {
47413 + dev_err(rphy->dev, "No support otg\n");
47414 + return -EINVAL;
47417 + switch (rport->mode) {
47428 + return -EINVAL;
47442 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
47443 + rport = &rphy->ports[index];
47444 + if (rport->port_id == USB2PHY_PORT_OTG)
47449 + dev_err(rphy->dev, "Fail to get otg port\n");
47450 + rc = -EINVAL;
47452 + } else if (rport->port_id != USB2PHY_PORT_OTG ||
47453 + rport->mode == USB_DR_MODE_UNKNOWN) {
47454 + dev_err(rphy->dev, "No support otg\n");
47455 + rc = -EINVAL;
47459 + mutex_lock(&rport->mutex);
47468 + dev_err(rphy->dev, "Error mode! Input 'otg' or 'host' or 'peripheral'\n");
47469 + rc = -EINVAL;
47473 + if (rport->mode == new_dr_mode) {
47474 + dev_warn(rphy->dev, "Same as current mode\n");
47478 + rport->mode = new_dr_mode;
47480 + switch (rport->mode) {
47482 + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST, 0);
47483 + property_enable(base, &rport->port_cfg->iddig_output, false);
47484 + property_enable(base, &rport->port_cfg->iddig_en, true);
47487 + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_DEVICE, 0);
47488 + property_enable(base, &rport->port_cfg->iddig_output, true);
47489 + property_enable(base, &rport->port_cfg->iddig_en, true);
47492 + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_OTG, 0);
47493 + property_enable(base, &rport->port_cfg->iddig_output, false);
47494 + property_enable(base, &rport->port_cfg->iddig_en, false);
47501 + mutex_unlock(&rport->mutex);
47522 @@ -530,59 +1083,80 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
47523 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47526 - bool vbus_attach, sch_work, notify_charger;
47529 + mutex_lock(&rport->mutex);
47531 - vbus_attach = property_enabled(rphy->grf,
47532 - &rport->port_cfg->utmi_bvalid);
47533 + if (rport->port_cfg->bvalid_grf_con.enable && rport->typec_vbus_det)
47534 + rport->vbus_attached =
47535 + property_enabled(rphy->grf, &rport->port_cfg->bvalid_grf_con);
47536 + else if (rport->utmi_avalid)
47537 + rport->vbus_attached =
47538 + property_enabled(rphy->grf, &rport->port_cfg->utmi_avalid);
47540 + rport->vbus_attached =
47541 + property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
47544 - notify_charger = false;
47547 dev_dbg(&rport->phy->dev, "%s otg sm work\n",
47548 usb_otg_state_string(rport->state));
47550 switch (rport->state) {
47552 rport->state = OTG_STATE_B_IDLE;
47553 - if (!vbus_attach)
47554 + if (!rport->vbus_attached) {
47555 + mutex_unlock(&rport->mutex);
47556 rockchip_usb2phy_power_off(rport->phy);
47557 + mutex_lock(&rport->mutex);
47561 - if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
47562 + if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0 ||
47563 + extcon_get_state(rphy->edev, EXTCON_USB_VBUS_EN) > 0) {
47564 dev_dbg(&rport->phy->dev, "usb otg host connect\n");
47565 rport->state = OTG_STATE_A_HOST;
47566 + rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47567 + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47568 + mutex_unlock(&rport->mutex);
47569 rockchip_usb2phy_power_on(rport->phy);
47571 - } else if (vbus_attach) {
47572 + } else if (rport->vbus_attached) {
47573 dev_dbg(&rport->phy->dev, "vbus_attach\n");
47574 switch (rphy->chg_state) {
47576 + mutex_unlock(&rport->mutex);
47577 schedule_delayed_work(&rport->chg_work, 0);
47580 switch (rphy->chg_type) {
47582 dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
47583 + wake_lock(&rport->wakelock);
47585 + mutex_unlock(&rport->mutex);
47586 rockchip_usb2phy_power_on(rport->phy);
47587 + mutex_lock(&rport->mutex);
47588 rport->state = OTG_STATE_B_PERIPHERAL;
47589 - notify_charger = true;
47590 + rport->perip_connected = true;
47592 - cable = EXTCON_CHG_USB_SDP;
47595 dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
47596 - rockchip_usb2phy_power_off(rport->phy);
47597 - notify_charger = true;
47598 - sch_work = true;
47603 dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
47604 + wake_lock(&rport->wakelock);
47606 + mutex_unlock(&rport->mutex);
47607 rockchip_usb2phy_power_on(rport->phy);
47608 + mutex_lock(&rport->mutex);
47609 rport->state = OTG_STATE_B_PERIPHERAL;
47610 - notify_charger = true;
47611 + rport->perip_connected = true;
47613 - cable = EXTCON_CHG_USB_CDP;
47617 @@ -592,32 +1166,34 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
47621 - notify_charger = true;
47622 rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47623 rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47624 - }
47625 -
47626 - if (rport->vbus_attached != vbus_attach) {
47627 - rport->vbus_attached = vbus_attach;
47628 -
47629 - if (notify_charger && rphy->edev) {
47630 - extcon_set_state_sync(rphy->edev,
47631 - cable, vbus_attach);
47632 - if (cable == EXTCON_CHG_USB_SDP)
47633 - extcon_set_state_sync(rphy->edev,
47634 - EXTCON_USB,
47635 - vbus_attach);
47636 - }
47637 + mutex_unlock(&rport->mutex);
47638 + rockchip_usb2phy_power_off(rport->phy);
47639 + mutex_lock(&rport->mutex);
47643 - if (!vbus_attach) {
47644 - dev_dbg(&rport->phy->dev, "usb disconnect\n");
47647 + if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0 ||
47648 + extcon_get_state(rphy->edev,
47650 + dev_dbg(&rport->phy->dev, "usb otg host connect\n");
47651 + rport->state = OTG_STATE_A_HOST;
47652 rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47653 rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47654 + rport->perip_connected = false;
47656 + wake_unlock(&rport->wakelock);
47657 + } else if (!rport->vbus_attached) {
47658 + dev_dbg(&rport->phy->dev, "usb disconnect\n");
47659 rport->state = OTG_STATE_B_IDLE;
47660 - delay = 0;
47661 - rockchip_usb2phy_power_off(rport->phy);
47662 + rport->perip_connected = false;
47663 + rphy->chg_state = USB_CHG_STATE_UNDEFINED;
47664 + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
47666 + wake_unlock(&rport->wakelock);
47670 @@ -625,15 +1201,47 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
47671 if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
47672 dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
47673 rport->state = OTG_STATE_B_IDLE;
47674 - rockchip_usb2phy_power_off(rport->phy);
47677 + mutex_unlock(&rport->mutex);
47682 - break;
47683 + mutex_unlock(&rport->mutex);
47687 + if (extcon_get_state(rphy->edev, cable) != rport->vbus_attached) {
47688 + extcon_set_state_sync(rphy->edev,
47689 + cable, rport->vbus_attached);
47691 + if (!rport->vbus_attached)
47693 + } else if (rport->state == OTG_STATE_A_HOST &&
47694 + extcon_get_state(rphy->edev, cable)) {
47698 + * in high, so the rport->vbus_attached may not be
47701 + extcon_set_state_sync(rphy->edev, cable, false);
47705 + if (rphy->edev_self &&
47706 + (extcon_get_state(rphy->edev, EXTCON_USB) !=
47707 + rport->perip_connected)) {
47708 + extcon_set_state_sync(rphy->edev,
47710 + rport->perip_connected);
47711 + extcon_sync(rphy->edev, EXTCON_USB_HOST);
47714 schedule_delayed_work(&rport->otg_sm_work, delay);
47716 + mutex_unlock(&rport->mutex);
47720 @@ -687,21 +1295,45 @@ static void rockchip_chg_detect_work(struct work_struct *work)
47722 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47730 dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
47731 rphy->chg_state);
47736 + * 2. Set the utmi_opmode in non-driving mode.
47741 switch (rphy->chg_state) {
47743 - if (!rport->suspended)
47744 - rockchip_usb2phy_power_off(rport->phy);
47745 - /* put the controller in non-driving mode */
47746 - property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
47747 + mutex_lock(&rport->mutex);
47749 + phy_sus_reg = &rport->port_cfg->phy_sus;
47750 + ret = regmap_read(base, phy_sus_reg->offset,
47751 + &rphy->phy_sus_cfg);
47753 + dev_err(&rport->phy->dev,
47755 + phy_sus_reg->offset, ret);
47756 + mutex_unlock(&rport->mutex);
47761 + property_enable(base, &rphy->phy_cfg->chg_det.chg_mode, true);
47764 rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
47765 rphy->dcd_retries = 0;
47766 + rphy->primary_retries = 0;
47770 @@ -739,6 +1371,19 @@ static void rockchip_chg_detect_work(struct work_struct *work)
47771 rphy->chg_state = USB_CHG_STATE_DETECTED;
47774 + if (rphy->primary_retries < 2) {
47781 + rphy->chg_state =
47783 + rphy->primary_retries++;
47787 rphy->chg_type = POWER_SUPPLY_TYPE_USB;
47788 rphy->chg_state = USB_CHG_STATE_DETECTED;
47790 @@ -757,19 +1402,36 @@ static void rockchip_chg_detect_work(struct work_struct *work)
47793 rphy->chg_state = USB_CHG_STATE_DETECTED;
47794 - delay = 0;
47797 - /* put the controller in normal mode */
47798 - property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
47799 + if (rphy->phy_cfg->chg_det.chg_mode.offset !=
47800 + rport->port_cfg->phy_sus.offset)
47801 + property_enable(base, &rphy->phy_cfg->chg_det.chg_mode, false);
47804 + phy_sus_reg = &rport->port_cfg->phy_sus;
47805 + mask = GENMASK(phy_sus_reg->bitend, phy_sus_reg->bitstart);
47806 + ret = regmap_write(base, phy_sus_reg->offset,
47807 + (rphy->phy_sus_cfg | (mask << BIT_WRITEABLE_SHIFT)));
47809 + dev_err(&rport->phy->dev,
47811 + phy_sus_reg->offset, ret);
47812 + mutex_unlock(&rport->mutex);
47813 rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
47814 dev_dbg(&rport->phy->dev, "charger = %s\n",
47815 chg_to_string(rphy->chg_type));
47818 + mutex_unlock(&rport->mutex);
47827 schedule_delayed_work(&rport->chg_work, delay);
47830 @@ -791,30 +1453,43 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
47833 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47834 - unsigned int sh = rport->port_cfg->utmi_hstdet.bitend -
47835 - rport->port_cfg->utmi_hstdet.bitstart + 1;
47836 - unsigned int ul, uhd, state;
47841 + if (!rport->port_cfg->utmi_ls.offset ||
47842 + (!rport->port_cfg->utmi_hstdet.offset &&
47843 + !rport->port_cfg->disfall_en.offset)) {
47844 + dev_dbg(&rport->phy->dev, "some property may not be specified\n");
47848 mutex_lock(&rport->mutex);
47850 ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
47854 - ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
47855 - if (ret < 0)
47856 - goto next_schedule;
47857 -
47858 - uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
47859 - rport->port_cfg->utmi_hstdet.bitstart);
47860 ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
47861 rport->port_cfg->utmi_ls.bitstart);
47863 - /* stitch on utmi_ls and utmi_hstdet as phy state */
47864 - state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
47865 - (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
47866 + if (rport->port_cfg->utmi_hstdet.offset) {
47867 + ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
47871 + uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
47872 + rport->port_cfg->utmi_hstdet.bitstart);
47874 + sh = rport->port_cfg->utmi_hstdet.bitend -
47875 + rport->port_cfg->utmi_hstdet.bitstart + 1;
47877 + state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
47878 + (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
47880 + state = ((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << 1 |
47881 + rport->host_disconnect;
47886 @@ -839,7 +1514,9 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
47888 if (rport->suspended) {
47889 dev_dbg(&rport->phy->dev, "Connected\n");
47890 + mutex_unlock(&rport->mutex);
47891 rockchip_usb2phy_power_on(rport->phy);
47892 + mutex_lock(&rport->mutex);
47893 rport->suspended = false;
47895 /* D+ line pull-up, D- line pull-down */
47896 @@ -849,7 +1526,9 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
47898 if (!rport->suspended) {
47899 dev_dbg(&rport->phy->dev, "Disconnected\n");
47900 + mutex_unlock(&rport->mutex);
47901 rockchip_usb2phy_power_off(rport->phy);
47902 + mutex_lock(&rport->mutex);
47903 rport->suspended = true;
47906 @@ -857,8 +1536,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
47908 * plug-in irq.
47910 - property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
47911 - property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
47916 @@ -867,7 +1545,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
47917 mutex_unlock(&rport->mutex);
47920 - dev_dbg(&rport->phy->dev, "unknown phy state\n");
47921 + dev_dbg(&rport->phy->dev, "unknown phy state %d\n", state);
47925 @@ -884,11 +1562,12 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
47926 if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
47929 + dev_dbg(&rport->phy->dev, "linestate interrupt\n");
47931 mutex_lock(&rport->mutex);
47934 - property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
47935 - property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
47938 mutex_unlock(&rport->mutex);
47940 @@ -918,99 +1597,157 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
47942 mutex_unlock(&rport->mutex);
47944 + if (rport->bypass_uart_en)
47947 + cancel_delayed_work_sync(&rport->otg_sm_work);
47948 rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
47953 -static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
47957 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
47960 - if (property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
47961 - return rockchip_usb2phy_bvalid_irq(irq, data);
47962 - else
47963 + if (!property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st) &&
47964 + !property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st))
47967 + mutex_lock(&rport->mutex);
47970 + if (property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st)) {
47971 + property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr,
47974 + } else if (property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st)) {
47975 + property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr,
47980 + extcon_set_state(rphy->edev, EXTCON_USB_HOST, cable_vbus_state);
47981 + extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, cable_vbus_state);
47983 + extcon_sync(rphy->edev, EXTCON_USB_HOST);
47984 + extcon_sync(rphy->edev, EXTCON_USB_VBUS_EN);
47988 + mutex_unlock(&rport->mutex);
47993 -static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
47994 - struct rockchip_usb2phy_port *rport,
47995 - struct device_node *child_np)
47998 - int ret;
48000 + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
48002 - rport->port_id = USB2PHY_PORT_HOST;
48003 - rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
48004 - rport->suspended = true;
48005 + if (!property_enabled(rphy->grf, &rport->port_cfg->disfall_st) &&
48006 + !property_enabled(rphy->grf, &rport->port_cfg->disrise_st))
48009 - mutex_init(&rport->mutex);
48010 - INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
48011 + mutex_lock(&rport->mutex);
48013 - rport->ls_irq = of_irq_get_byname(child_np, "linestate");
48014 - if (rport->ls_irq < 0) {
48015 - dev_err(rphy->dev, "no linestate irq provided\n");
48016 - return rport->ls_irq;
48018 + if (property_enabled(rphy->grf, &rport->port_cfg->disfall_st)) {
48019 + property_enable(rphy->grf, &rport->port_cfg->disfall_clr,
48021 + rport->host_disconnect = false;
48022 + } else if (property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) {
48023 + property_enable(rphy->grf, &rport->port_cfg->disrise_clr,
48025 + rport->host_disconnect = true;
48028 - ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
48029 - rockchip_usb2phy_linestate_irq,
48030 - IRQF_ONESHOT,
48031 - "rockchip_usb2phy", rport);
48032 - if (ret) {
48033 - dev_err(rphy->dev, "failed to request linestate irq handle\n");
48034 - return ret;
48035 - }
48036 + mutex_unlock(&rport->mutex);
48038 - return 0;
48042 -static int rockchip_otg_event(struct notifier_block *nb,
48043 - unsigned long event, void *ptr)
48046 - struct rockchip_usb2phy_port *rport =
48047 - container_of(nb, struct rockchip_usb2phy_port, event_nb);
48050 - schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
48055 - return NOTIFY_DONE;
48059 -static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
48060 - struct rockchip_usb2phy_port *rport,
48061 - struct device_node *child_np)
48064 - int ret;
48071 - rport->port_id = USB2PHY_PORT_OTG;
48072 - rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
48073 - rport->state = OTG_STATE_UNDEFINED;
48074 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
48075 + rport = &rphy->ports[index];
48076 + if (!rport->phy)
48079 - /*
48080 - * set suspended flag to true, but actually don't
48081 - * put phy in suspend mode, it aims to enable usb
48082 - * phy and clock in power_on() called by usb controller
48083 - * driver during probe.
48084 - */
48085 - rport->suspended = true;
48086 - rport->vbus_attached = false;
48087 + if (rport->port_id == USB2PHY_PORT_HOST &&
48088 + rport->port_cfg->disfall_en.offset)
48091 - mutex_init(&rport->mutex);
48095 - rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
48096 - if (rport->mode == USB_DR_MODE_HOST ||
48097 - rport->mode == USB_DR_MODE_UNKNOWN) {
48098 - ret = 0;
48099 - goto out;
48104 + if (rport->port_id == USB2PHY_PORT_OTG &&
48105 + rport->mode != USB_DR_MODE_UNKNOWN) {
48106 + if (rport->mode == USB_DR_MODE_HOST) {
48115 + force_mode = property_enabled(rphy->grf,
48116 + &rport->port_cfg->iddig_en);
48121 + if (!rport->vbus_always_on)
48128 - INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
48129 - INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
48143 + if (rphy->irq > 0)
48147 - * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
48148 - * interrupts muxed together, so probe the otg-mux interrupt first,
48149 - * if not found, then look for the regular interrupts one by one.
48151 + * the irqs of otg port. So probe the otg-mux interrupt first,
48154 rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
48155 if (rport->otg_mux_irq > 0) {
48156 @@ -1020,20 +1757,50 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
48160 - if (ret) {
48162 dev_err(rphy->dev,
48163 "failed to request otg-mux irq handle\n");
48164 - goto out;
48165 - }
48166 - } else {
48167 - rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
48168 - if (rport->bvalid_irq < 0) {
48169 - dev_err(rphy->dev, "no vbus valid irq provided\n");
48170 - ret = rport->bvalid_irq;
48171 - goto out;
48177 + rport->ls_irq = of_irq_get_byname(child_np, "linestate");
48178 + if (rport->ls_irq <= 0) {
48179 + dev_err(rphy->dev, "no linestate irq provided\n");
48180 + return -EINVAL;
48183 + ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
48188 + dev_err(rphy->dev, "failed to request linestate irq handle\n");
48197 + if (rport->port_id == USB2PHY_PORT_HOST ||
48198 + rport->mode == USB_DR_MODE_HOST ||
48199 + rport->mode == USB_DR_MODE_UNKNOWN)
48203 + if (!rport->vbus_always_on) {
48204 + rport->bvalid_irq = of_irq_get_byname(child_np,
48205 + "otg-bvalid");
48206 + if (rport->bvalid_irq <= 0) {
48207 + dev_err(rphy->dev, "no bvalid irq provided\n");
48208 + return -EINVAL;
48211 - ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
48212 + ret = devm_request_threaded_irq(rphy->dev,
48213 + rport->bvalid_irq,
48217 @@ -1042,187 +1809,1023 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
48219 dev_err(rphy->dev,
48220 "failed to request otg-bvalid irq handle\n");
48221 - goto out;
48226 - if (!IS_ERR(rphy->edev)) {
48227 - rport->event_nb.notifier_call = rockchip_otg_event;
48229 + if (rphy->edev_self) {
48230 + rport->id_irq = of_irq_get_byname(child_np, "otg-id");
48231 + if (rport->id_irq <= 0) {
48232 + dev_err(rphy->dev, "no otg id irq provided\n");
48233 + return -EINVAL;
48236 - ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
48237 - EXTCON_USB_HOST, &rport->event_nb);
48238 - if (ret)
48239 - dev_err(rphy->dev, "register USB HOST notifier failed\n");
48240 + ret = devm_request_threaded_irq(rphy->dev,
48241 + rport->id_irq, NULL,
48247 + dev_err(rphy->dev,
48248 + "failed to request otg-id irq handle\n");
48253 -out:
48257 -static int rockchip_usb2phy_probe(struct platform_device *pdev)
48262 - struct device *dev = &pdev->dev;
48263 - struct device_node *np = dev->of_node;
48264 - struct device_node *child_np;
48265 - struct phy_provider *provider;
48266 - struct rockchip_usb2phy *rphy;
48267 - const struct rockchip_usb2phy_cfg *phy_cfgs;
48268 - const struct of_device_id *match;
48269 - unsigned int reg;
48270 - int index, ret;
48271 -
48272 - rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
48273 - if (!rphy)
48274 - return -ENOMEM;
48275 -
48276 - match = of_match_device(dev->driver->of_match_table, dev);
48277 - if (!match || !match->data) {
48278 - dev_err(dev, "phy configs are not assigned!\n");
48279 - return -EINVAL;
48280 - }
48284 - if (!dev->parent || !dev->parent->of_node)
48285 - return -EINVAL;
48286 + rport->port_id = USB2PHY_PORT_HOST;
48287 + rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
48289 - rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
48290 - if (IS_ERR(rphy->grf))
48291 - return PTR_ERR(rphy->grf);
48293 + rport->low_power_en =
48294 + of_property_read_bool(child_np, "rockchip,low-power-mode");
48296 - if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
48297 - rphy->usbgrf =
48298 - syscon_regmap_lookup_by_phandle(dev->of_node,
48299 - "rockchip,usbgrf");
48300 - if (IS_ERR(rphy->usbgrf))
48301 - return PTR_ERR(rphy->usbgrf);
48302 - } else {
48303 - rphy->usbgrf = NULL;
48304 - }
48305 + mutex_init(&rport->mutex);
48306 + INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
48308 - if (of_property_read_u32(np, "reg", &reg)) {
48309 - dev_err(dev, "the reg property is not assigned in %pOFn node\n",
48310 - np);
48311 - return -EINVAL;
48314 + dev_err(rphy->dev, "failed to init irq for host port\n");
48318 - rphy->dev = dev;
48319 - phy_cfgs = match->data;
48320 - rphy->chg_state = USB_CHG_STATE_UNDEFINED;
48321 - rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
48322 - platform_set_drvdata(pdev, rphy);
48323 -
48324 - ret = rockchip_usb2phy_extcon_register(rphy);
48326 + * Let us put phy-port into suspend mode here for saving power
48330 + ret = property_enable(base, &rport->port_cfg->phy_sus, true);
48333 + rport->suspended = true;
48335 - /* find out a proper config which can be matched with dt. */
48336 - index = 0;
48337 - while (phy_cfgs[index].reg) {
48338 - if (phy_cfgs[index].reg == reg) {
48339 - rphy->phy_cfg = &phy_cfgs[index];
48340 - break;
48341 - }
48345 - ++index;
48346 - }
48353 - if (!rphy->phy_cfg) {
48354 - dev_err(dev, "no phy-config can be matched with %pOFn node\n",
48355 - np);
48356 - return -EINVAL;
48357 - }
48358 + schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
48360 - rphy->clk = of_clk_get_by_name(np, "phyclk");
48361 - if (!IS_ERR(rphy->clk)) {
48373 + rport->port_id = USB2PHY_PORT_OTG;
48374 + rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
48375 + rport->state = OTG_STATE_UNDEFINED;
48376 + rport->vbus_attached = false;
48377 + rport->vbus_enabled = false;
48378 + rport->perip_connected = false;
48379 + rport->prev_iddig = true;
48381 + mutex_init(&rport->mutex);
48384 + rport->bypass_uart_en =
48385 + of_property_read_bool(child_np, "rockchip,bypass-uart");
48386 + rport->vbus_always_on =
48387 + of_property_read_bool(child_np, "rockchip,vbus-always-on");
48388 + rport->utmi_avalid =
48389 + of_property_read_bool(child_np, "rockchip,utmi-avalid");
48392 + rport->low_power_en =
48393 + of_property_read_bool(child_np, "rockchip,low-power-mode");
48395 + /* For type-c with vbus_det always pull up */
48396 + rport->typec_vbus_det =
48397 + of_property_read_bool(child_np, "rockchip,typec-vbus-det");
48400 + rport->vbus = devm_regulator_get_optional(&rport->phy->dev, "vbus");
48401 + if (IS_ERR(rport->vbus)) {
48402 + ret = PTR_ERR(rport->vbus);
48403 + if (ret == -EPROBE_DEFER)
48406 + if (rport->mode == USB_DR_MODE_OTG)
48407 + dev_warn(&rport->phy->dev, "No vbus specified for otg port\n");
48408 + rport->vbus = NULL;
48411 + rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
48412 + iddig = property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig);
48413 + if (rphy->edev_self && (rport->mode == USB_DR_MODE_HOST ||
48414 + rport->mode == USB_DR_MODE_UNKNOWN || !iddig)) {
48416 + extcon_set_state(rphy->edev, EXTCON_USB, false);
48417 + extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
48418 + extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
48426 + dev_err(rphy->dev, "failed to init irq for otg port\n");
48430 + if (rport->vbus_always_on || rport->mode == USB_DR_MODE_HOST ||
48431 + rport->mode == USB_DR_MODE_UNKNOWN)
48434 + /* Select bvalid of usb phy as bvalid of usb controller */
48435 + if (rport->port_cfg->bvalid_grf_con.enable != 0)
48436 + property_enable(base, &rport->port_cfg->bvalid_grf_con, false);
48438 + wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg");
48439 + INIT_DELAYED_WORK(&rport->bypass_uart_work,
48441 + INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
48442 + INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
48444 + if (!IS_ERR(rphy->edev)) {
48445 + rport->event_nb.notifier_call = rockchip_otg_event;
48447 + ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
48448 + EXTCON_USB_HOST, &rport->event_nb);
48450 + dev_err(rphy->dev, "register USB HOST notifier failed\n");
48457 + * Let us put phy-port into suspend mode here for saving power
48461 + ret = property_enable(base, &rport->port_cfg->phy_sus, true);
48464 + rport->suspended = true;
48469 + wake_lock_destroy(&rport->wakelock);
48475 + struct device *dev = &pdev->dev;
48476 + struct device_node *np = dev->of_node;
48489 + return -ENOMEM;
48491 + match = of_match_device(dev->driver->of_match_table, dev);
48492 + if (!match || !match->data) {
48494 + return -EINVAL;
48497 + if (!dev->parent || !dev->parent->of_node) {
48501 + return -ENODEV;
48504 + rphy->phy_base = devm_ioremap_resource(dev, res);
48505 + if (IS_ERR(rphy->phy_base))
48506 + return PTR_ERR(rphy->phy_base);
48508 + rphy->grf = syscon_regmap_lookup_by_phandle(np,
48510 + if (IS_ERR(rphy->grf))
48511 + return PTR_ERR(rphy->grf);
48513 + reg = res->start;
48515 + rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
48516 + if (IS_ERR(rphy->grf))
48517 + return PTR_ERR(rphy->grf);
48519 + if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
48520 + rphy->usbgrf =
48521 + syscon_regmap_lookup_by_phandle(dev->of_node,
48523 + if (IS_ERR(rphy->usbgrf))
48524 + return PTR_ERR(rphy->usbgrf);
48526 + rphy->usbgrf = NULL;
48531 + np->name);
48532 + return -EINVAL;
48536 + rphy->dev = dev;
48537 + phy_cfgs = match->data;
48538 + rphy->chg_state = USB_CHG_STATE_UNDEFINED;
48539 + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
48540 + rphy->edev_self = false;
48541 + rphy->irq = platform_get_irq(pdev, 0);
48552 + rphy->phy_cfg = &phy_cfgs[index];
48559 + if (!rphy->phy_cfg) {
48560 + dev_err(dev, "no phy-config can be matched with %pOFn node\n",
48562 + return -EINVAL;
48570 + rphy->phy_reset = devm_reset_control_get_optional(dev, "phy");
48571 + if (IS_ERR(rphy->phy_reset))
48572 + return PTR_ERR(rphy->phy_reset);
48574 + rphy->clk = of_clk_get_by_name(np, "phyclk");
48575 + if (!IS_ERR(rphy->clk)) {
48576 clk_prepare_enable(rphy->clk);
48578 dev_info(&pdev->dev, "no phyclk specified\n");
48579 rphy->clk = NULL;
48582 - ret = rockchip_usb2phy_clk480m_register(rphy);
48583 - if (ret) {
48584 - dev_err(dev, "failed to register 480m output clock\n");
48585 - goto disable_clks;
48586 - }
48587 + if (rphy->phy_cfg->phy_tuning) {
48588 + ret = rphy->phy_cfg->phy_tuning(rphy);
48595 + struct rockchip_usb2phy_port *rport = &rphy->ports[index];
48598 + /* This driver aims to support both otg-port and host-port */
48599 + if (!of_node_name_eq(child_np, "host-port") &&
48600 + !of_node_name_eq(child_np, "otg-port"))
48610 + rport->phy = phy;
48611 + phy_set_drvdata(rport->phy, rport);
48614 + if (of_node_name_eq(child_np, "host-port")) {
48628 + if (++index >= rphy->phy_cfg->num_ports)
48640 + ret = sysfs_create_group(&dev->kobj, &usb2_phy_attr_group);
48652 + if (rphy->irq > 0) {
48653 + ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
48659 + dev_err(rphy->dev,
48665 + if (of_property_read_bool(np, "wakeup-source"))
48666 + device_init_wakeup(rphy->dev, true);
48668 + device_init_wakeup(rphy->dev, false);
48677 + if (rphy->clk) {
48678 + clk_disable_unprepare(rphy->clk);
48679 + clk_put(rphy->clk);
48691 + if (!rport->low_power_en)
48694 + if (rport->port_id == USB2PHY_PORT_OTG) {
48695 + dev_info(&rport->phy->dev, "set otg port low power state %d\n",
48697 + ret = property_enable(rphy->grf, &rport->port_cfg->bypass_bc,
48702 + ret = property_enable(rphy->grf, &rport->port_cfg->bypass_otg,
48707 + ret = property_enable(rphy->grf, &rport->port_cfg->vbus_det_en,
48709 + } else if (rport->port_id == USB2PHY_PORT_HOST) {
48710 + dev_info(&rport->phy->dev, "set host port low power state %d\n",
48713 + ret = property_enable(rphy->grf, &rport->port_cfg->bypass_host,
48725 + ret = regmap_write(rphy->grf, 0x298, 0x00040000);
48736 + /* Open pre-emphasize in non-chirp state for PHY0 otg port */
48737 + if (rphy->phy_cfg->reg == 0x760)
48738 + ret = regmap_write(rphy->grf, 0x76c, 0x00070004);
48747 + /* Open pre-emphasize in non-chirp state for otg port */
48748 + ret = regmap_write(rphy->grf, 0x0, 0x00070004);
48752 + /* Open pre-emphasize in non-chirp state for host port */
48753 + ret = regmap_write(rphy->grf, 0x30, 0x00070004);
48758 + ret = regmap_write(rphy->grf, 0x18, 0x00040000);
48770 + ret = regmap_write(rphy->grf, 0x2c, 0xffff0400);
48774 + /* Open pre-emphasize in non-chirp state for otg port */
48775 + ret = regmap_write(rphy->grf, 0x0, 0x00070004);
48779 + /* Open pre-emphasize in non-chirp state for host port */
48780 + ret = regmap_write(rphy->grf, 0x30, 0x00070004);
48785 + ret = regmap_write(rphy->grf, 0x18, 0x00040000);
48799 + /* open HS pre-emphasize to expand HS slew rate for each port. */
48800 + ret |= regmap_write(rphy->grf, 0x0780, open_pre_emphasize);
48801 + ret |= regmap_write(rphy->grf, 0x079c, eye_height_tuning);
48802 + ret |= regmap_write(rphy->grf, 0x07b0, open_pre_emphasize);
48803 + ret |= regmap_write(rphy->grf, 0x07cc, eye_height_tuning);
48806 + ret |= regmap_write(rphy->grf, 0x078c, compensation_tuning);
48813 + struct device_node *node = rphy->dev->of_node;
48816 + if (rphy->phy_cfg->reg == 0xe450) {
48818 + * Disable the pre-emphasize in eop state
48819 + * and chirp state to avoid mis-trigger the
48823 + ret |= regmap_write(rphy->grf, 0x4480,
48825 + ret |= regmap_write(rphy->grf, 0x44b4,
48829 + * Disable the pre-emphasize in eop state
48830 + * and chirp state to avoid mis-trigger the
48834 + ret |= regmap_write(rphy->grf, 0x4500,
48836 + ret |= regmap_write(rphy->grf, 0x4534,
48840 + if (!of_property_read_bool(node, "rockchip,u2phy-tuning"))
48843 + if (rphy->phy_cfg->reg == 0xe450) {
48848 + ret |= regmap_write(rphy->grf, 0x448c,
48851 + /* Set max pre-emphasis level for PHY0 */
48852 + ret |= regmap_write(rphy->grf, 0x44b0,
48858 + ret |= regmap_write(rphy->grf, 0x4480,
48865 + ret |= regmap_write(rphy->grf, 0x450c,
48868 + /* Set max pre-emphasis level for PHY1 */
48869 + ret |= regmap_write(rphy->grf, 0x4530,
48875 + ret |= regmap_write(rphy->grf, 0x4500,
48887 + reg = readl(rphy->phy_base + 0x30);
48889 + writel(reg & ~BIT(2), rphy->phy_base + 0x30);
48891 + reg = readl(rphy->phy_base);
48892 + /* Enable otg port pre-emphasis during non-chirp phase */
48895 + writel(reg, rphy->phy_base);
48897 + reg = readl(rphy->phy_base + 0x0400);
48898 + /* Enable host port pre-emphasis during non-chirp phase */
48901 + writel(reg, rphy->phy_base + 0x0400);
48903 + if (rphy->phy_cfg->reg == 0xfe8a0000) {
48905 + reg = readl(rphy->phy_base + 0x30);
48908 + writel(reg, rphy->phy_base + 0x30);
48914 + ret |= regmap_write(rphy->grf, 0x0048, FILTER_COUNTER);
48920 + ret |= regmap_write(rphy->grf, 0x004c, FILTER_COUNTER);
48931 + reg = readl(rphy->phy_base + 0x3c);
48933 + writel(reg & ~BIT(7), rphy->phy_base + 0x3c);
48935 + reg = readl(rphy->phy_base + 0x3c);
48937 + writel(reg | BIT(7), rphy->phy_base + 0x3c);
48948 + ret = regmap_write(rphy->grf, 0x0008,
48958 + if (rphy->phy_cfg->reg == 0x0000) {
48963 + * 3. Set utmi_opmode to 2'b01 (no-driving)
48965 + ret |= regmap_write(rphy->grf, 0x000c,
48969 + ret |= regmap_write(rphy->grf, 0x0004,
48972 - index = 0;
48973 - for_each_available_child_of_node(np, child_np) {
48974 - struct rockchip_usb2phy_port *rport = &rphy->ports[index];
48975 - struct phy *phy;
48976 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
48977 + ret |= regmap_write(rphy->grf, 0x0008,
48980 - /* This driver aims to support both otg-port and host-port */
48981 - if (!of_node_name_eq(child_np, "host-port") &&
48982 - !of_node_name_eq(child_np, "otg-port"))
48983 - goto next_child;
48985 + ret |= regmap_write(rphy->grf, 0x0010,
48987 + } else if (rphy->phy_cfg->reg == 0x4000) {
48992 + * 3. Set utmi_opmode to 2'b01 (no-driving)
48994 + ret |= regmap_write(rphy->grf, 0x000c,
48997 - phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
48998 - if (IS_ERR(phy)) {
48999 - dev_err(dev, "failed to create phy\n");
49000 - ret = PTR_ERR(phy);
49001 - goto put_child;
49003 + ret |= regmap_write(rphy->grf, 0x0004,
49006 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
49007 + ret |= regmap_write(rphy->grf, 0x0008,
49011 + ret |= regmap_write(rphy->grf, 0x0010,
49013 + } else if (rphy->phy_cfg->reg == 0x8000) {
49020 + ret |= regmap_write(rphy->grf, 0x000c,
49024 + ret |= regmap_write(rphy->grf, 0x0004,
49027 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
49028 + ret |= regmap_write(rphy->grf, 0x0008,
49030 + } else if (rphy->phy_cfg->reg == 0xc000) {
49037 + ret |= regmap_write(rphy->grf, 0x000c,
49041 + ret |= regmap_write(rphy->grf, 0x0004,
49044 + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
49045 + ret |= regmap_write(rphy->grf, 0x0008,
49061 + if (device_may_wakeup(rphy->dev))
49064 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
49065 + rport = &rphy->ports[index];
49066 + if (!rport->phy)
49069 + if (rport->port_id == USB2PHY_PORT_OTG &&
49070 + (rport->id_irq > 0 || rphy->irq > 0)) {
49071 + mutex_lock(&rport->mutex);
49072 + rport->prev_iddig = property_enabled(rphy->grf,
49073 + &rport->port_cfg->utmi_iddig);
49076 + mutex_unlock(&rport->mutex);
49078 + dev_err(rphy->dev,
49084 - rport->phy = phy;
49085 - phy_set_drvdata(rport->phy, rport);
49086 + if (rport->port_id == USB2PHY_PORT_OTG && wakeup_enable &&
49087 + rport->bvalid_irq > 0)
49088 + enable_irq_wake(rport->bvalid_irq);
49090 - /* initialize otg/host port separately */
49091 - if (of_node_name_eq(child_np, "host-port")) {
49092 - ret = rockchip_usb2phy_host_port_init(rphy, rport,
49093 - child_np);
49094 - if (ret)
49095 - goto put_child;
49096 - } else {
49097 - ret = rockchip_usb2phy_otg_port_init(rphy, rport,
49098 - child_np);
49099 - if (ret)
49100 - goto put_child;
49102 + mutex_lock(&rport->mutex);
49104 + mutex_unlock(&rport->mutex);
49106 + dev_err(rphy->dev, "failed to enable linestate irq\n");
49110 -next_child:
49111 - /* to prevent out of boundary */
49112 - if (++index >= rphy->phy_cfg->num_ports)
49113 - break;
49114 + if (wakeup_enable && rport->ls_irq > 0)
49115 + enable_irq_wake(rport->ls_irq);
49121 - provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
49122 - return PTR_ERR_OR_ZERO(provider);
49126 -put_child:
49127 - of_node_put(child_np);
49128 -disable_clks:
49129 - if (rphy->clk) {
49130 - clk_disable_unprepare(rphy->clk);
49131 - clk_put(rphy->clk);
49141 + if (device_may_wakeup(rphy->dev))
49144 + if (rphy->phy_cfg->phy_tuning)
49145 + ret = rphy->phy_cfg->phy_tuning(rphy);
49147 + for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
49148 + rport = &rphy->ports[index];
49149 + if (!rport->phy)
49152 + if (rport->port_id == USB2PHY_PORT_OTG &&
49153 + (rport->id_irq > 0 || rphy->irq > 0)) {
49154 + mutex_lock(&rport->mutex);
49155 + iddig = property_enabled(rphy->grf,
49156 + &rport->port_cfg->utmi_iddig);
49159 + mutex_unlock(&rport->mutex);
49161 + dev_err(rphy->dev,
49166 + if (iddig != rport->prev_iddig) {
49167 + dev_dbg(&rport->phy->dev,
49169 + rport->prev_iddig = iddig;
49170 + extcon_set_state_sync(rphy->edev,
49173 + extcon_set_state_sync(rphy->edev,
49182 + if (rport->port_id == USB2PHY_PORT_OTG && wakeup_enable &&
49183 + rport->bvalid_irq > 0)
49184 + disable_irq_wake(rport->bvalid_irq);
49186 + if (wakeup_enable && rport->ls_irq > 0)
49187 + disable_irq_wake(rport->ls_irq);
49321 - .phy_sus = { 0x0760, 15, 0, 0, 0x1d1 },
49343 - .phy_sus = { 0x0764, 15, 0, 0, 0x1d1 },
49351 - .opmode = { 0x0760, 3, 0, 5, 1 },
49356 @@ -1240,18 +2843,72 @@ static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
49360 - .phy_sus = { 0x800, 15, 0, 0, 0x1d1 },
49407 - .phy_sus = { 0x804, 15, 0, 0, 0x1d1 },
49408 - .ls_det_en = { 0x0684, 1, 1, 0, 1 },
49409 - .ls_det_st = { 0x0694, 1, 1, 0, 1 },
49410 - .ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
49434 @@ -1260,22 +2917,36 @@ static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
49442 - .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
49467 - .phy_sus = { 0x104, 15, 0, 0, 0x1d1 },
49473 @@ -1284,7 +2955,7 @@ static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
49477 - .opmode = { 0x0100, 3, 0, 5, 1 },
49482 @@ -1303,10 +2974,11 @@ static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
49490 - .phy_sus = { 0x0728, 15, 0, 0, 0x1d1 },
49495 @@ -1318,19 +2990,86 @@ static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
49557 - .phy_sus = { 0xe454, 1, 0, 2, 1 },
49583 @@ -1342,7 +3081,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
49587 - .opmode = { 0xe454, 3, 0, 5, 1 },
49592 @@ -1357,15 +3096,30 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
49600 - .phy_sus = { 0xe464, 1, 0, 2, 1 },
49624 @@ -1376,6 +3130,246 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
49677 + /* Select suspend control from controller */
49783 + /* Select suspend control from controller */
49871 @@ -1407,7 +3401,7 @@ static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
49875 - .opmode = { 0x0100, 3, 0, 5, 1 },
49880 @@ -1424,10 +3418,16 @@ static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
49883 { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
49884 + { .compatible = "rockchip,rk1808-usb2phy", .data = &rk1808_phy_cfgs },
49885 + { .compatible = "rockchip,rk3128-usb2phy", .data = &rk312x_phy_cfgs },
49886 { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
49887 + { .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
49888 { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
49889 { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
49890 + { .compatible = "rockchip,rk3368-usb2phy", .data = &rk3368_phy_cfgs },
49891 { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
49892 + { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
49893 + { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
49894 { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
49897 @@ -1437,6 +3437,7 @@ static struct platform_driver rockchip_usb2phy_driver = {
49900 .name = "rockchip-usb2phy",
49905 diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
49907 --- a/drivers/phy/rockchip/phy-rockchip-pcie.c
49908 +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
49909 @@ -182,6 +182,12 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
49911 mutex_lock(&rk_phy->pcie_mutex);
49913 + regmap_write(rk_phy->reg_base,
49914 + rk_phy->phy_data->pcie_laneoff,
49917 + PHY_LANE_IDLE_A_SHIFT + inst->index));
49919 if (rk_phy->pwr_cnt++)
49922 @@ -196,12 +202,6 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
49926 - regmap_write(rk_phy->reg_base,
49927 - rk_phy->phy_data->pcie_laneoff,
49928 - HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
49929 - PHY_LANE_IDLE_MASK,
49930 - PHY_LANE_IDLE_A_SHIFT + inst->index));
49931 -
49934 * so we make it large enough here. And we use loop-break
49935 diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
49937 --- a/drivers/phy/rockchip/phy-rockchip-typec.c
49938 +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
49939 @@ -54,6 +54,7 @@
49943 +#include <linux/phy/phy-rockchip-typec.h>
49947 @@ -285,13 +286,37 @@
49951 -#define PMA_LANE_CFG (0xc000 << 2)
49966 -#define DP_MODE_CTL (0xc008 << 2)
49987 @@ -314,21 +339,29 @@
49991 -#define CLK_PLL_CONFIG 0X30
50007 -#define DP_MODE_A0 BIT(4)
50008 -#define DP_MODE_A2 BIT(6)
50009 -#define DP_MODE_ENTER_A0 0xc101
50010 -#define DP_MODE_ENTER_A2 0xc104
50022 @@ -340,6 +373,10 @@
50033 @@ -368,6 +405,11 @@ struct rockchip_usb3phy_port_cfg {
50045 @@ -384,6 +426,7 @@ struct rockchip_typec_phy {
50053 @@ -408,26 +451,136 @@ static struct phy_reg usb3_pll_cfg[] = {
50057 -static struct phy_reg dp_pll_cfg[] = {
50058 - { 0xf0, CMN_PLL1_VCOCAL_INIT },
50059 - { 0x18, CMN_PLL1_VCOCAL_ITER },
50060 - { 0x30b9, CMN_PLL1_VCOCAL_START },
50061 - { 0x21c, CMN_PLL1_INTDIV },
50062 - { 0, CMN_PLL1_FRACDIV },
50063 - { 0x5, CMN_PLL1_HIGH_THR },
50064 - { 0x35, CMN_PLL1_SS_CTRL1 },
50065 - { 0x7f1e, CMN_PLL1_SS_CTRL2 },
50066 - { 0x20, CMN_PLL1_DSM_DIAG },
50067 - { 0, CMN_PLLSM1_USER_DEF_CTRL },
50068 - { 0, CMN_DIAG_PLL1_OVRD },
50069 - { 0, CMN_DIAG_PLL1_FBH_OVRD },
50070 - { 0, CMN_DIAG_PLL1_FBL_OVRD },
50071 - { 0x6, CMN_DIAG_PLL1_V2I_TUNE },
50072 - { 0x45, CMN_DIAG_PLL1_CP_TUNE },
50073 - { 0x8, CMN_DIAG_PLL1_LF_PROG },
50074 - { 0x100, CMN_DIAG_PLL1_PTATIS_TUNE1 },
50075 - { 0x7, CMN_DIAG_PLL1_PTATIS_TUNE2 },
50076 - { 0x4, CMN_DIAG_PLL1_INCLK_CTRL },
50210 @@ -454,6 +607,134 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
50233 + PHY_DP_POWER_STATE_DISABLED = -1,
50250 + reg = readl(tcphy->base + PMA_CMN_CTRL1);
50252 + dev_err(tcphy->dev, "cmn_ready in the inactive state\n");
50253 + return -EINVAL;
50256 + reg = readl(tcphy->base + PHY_DP_MODE_CTL);
50259 + writel(reg, tcphy->base + PHY_DP_MODE_CTL);
50261 + ret = readl_poll_timeout(tcphy->base + PHY_DP_MODE_CTL,
50266 + dev_err(tcphy->dev, "failed to enter power state %d\n", state);
50288 + * -------------------------------------------------------------------
50290 + * -------------------------------------------------------------------
50291 + * Lane0 (tx_p/m_ln_0) TX1+/TX1- (pins A2/A3)
50292 + * Lane1 (tx_rx_p/m_ln_1) RX1+/RX1- (pins B11/B10)
50293 + * Lane2 (tx_rx_p/m_ln_2) RX2+/RX2- (pins A11/A10)
50294 + * Lane3 (tx_p/m_ln_3) TX2+/TX2- (pins B2/B3)
50295 + * -------------------------------------------------------------------
50301 + * ----------------------------------------------------------------------
50303 + * ----------------------------------------------------------------------
50308 + * ----------------------------------------------------------------------
50313 + * The PHY_PMA_LANE_CFG register is used to select whether a PMA lane
50329 + tcphy->base + PHY_PMA_LANE_CFG);
50338 + tcphy->base + PHY_PMA_LANE_CFG);
50345 @@ -475,7 +756,7 @@ static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
50347 rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
50349 - rdata |= CLK_PLL_CONFIG;
50351 writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL);
50354 @@ -489,17 +770,44 @@ static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy)
50355 tcphy->base + usb3_pll_cfg[i].addr);
50358 -static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy)
50361 - u32 i;
50366 + hsclk_sel = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
50391 - /* set the default mode to RBR */
50392 - writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR,
50393 - tcphy->base + DP_CLK_CTL);
50395 + writel(clk_ctrl, tcphy->base + PHY_DP_CLK_CTL);
50396 + writel(hsclk_sel, tcphy->base + CMN_DIAG_HSCLK_SEL);
50399 - for (i = 0; i < ARRAY_SIZE(dp_pll_cfg); i++)
50400 - writel(dp_pll_cfg[i].value, tcphy->base + dp_pll_cfg[i].addr);
50402 + writel(phy_cfg[i].value, tcphy->base + phy_cfg[i].addr);
50406 @@ -526,9 +834,10 @@ static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
50407 writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane));
50410 -static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
50414 - u16 rdata;
50417 writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane));
50418 writel(0x6799, tcphy->base + TX_PSC_A0(lane));
50419 @@ -536,27 +845,234 @@ static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
50420 writel(0x98, tcphy->base + TX_PSC_A2(lane));
50421 writel(0x98, tcphy->base + TX_PSC_A3(lane));
50423 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
50424 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_001(lane));
50425 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_010(lane));
50426 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_011(lane));
50427 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_100(lane));
50428 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_101(lane));
50429 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_110(lane));
50430 - writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_111(lane));
50431 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_10(lane));
50432 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_01(lane));
50433 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
50434 - writel(0, tcphy->base + TX_TXCC_CPOST_MULT_11(lane));
50435 -
50436 - writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
50437 - writel(0x400, tcphy->base + TX_DIAG_TX_DRV(lane));
50438 -
50439 - rdata = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50440 - rdata = (rdata & 0x8fff) | 0x6000;
50441 - writel(rdata, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50442 + writel(tcphy->config[swing][pre_emp].swing,
50443 + tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
50444 + writel(tcphy->config[swing][pre_emp].pe,
50445 + tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
50448 + writel(0x700, tcphy->base + TX_DIAG_TX_DRV(lane));
50449 + writel(0x13c, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
50451 + writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
50452 + writel(0x0400, tcphy->base + TX_DIAG_TX_DRV(lane));
50455 + val = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50467 + writel(val, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
50476 + if (!phy->power_count)
50477 + return -EPERM;
50479 + if (tcphy->mode == MODE_DFP_DP) {
50483 + if (tcphy->flip) {
50501 + if (!phy->power_count)
50502 + return -EPERM;
50507 + * power-down the unused PHY DP lanes (and their mapped PMA lanes).
50511 + reg = readl(tcphy->base + PHY_DP_MODE_CTL);
50526 + return -EINVAL;
50529 + writel(reg, tcphy->base + PHY_DP_MODE_CTL);
50543 + if (!phy->power_count)
50544 + return -EPERM;
50549 + dev_err(tcphy->dev, "failed to enter A3 state: %d\n", ret);
50554 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50557 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50559 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50563 + dev_err(tcphy->dev, "wait DP PLL clock disabled timeout\n");
50568 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50571 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50573 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50577 + dev_err(tcphy->dev, "wait DP PLL not ready timeout\n");
50581 + /* Re-configure PHY registers for the new data rate */
50582 + cmn_diag_hsclk_sel = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
50585 + phy_dp_clk_ctl = readl(tcphy->base + PHY_DP_CLK_CTL);
50614 + return -EINVAL;
50617 + writel(cmn_diag_hsclk_sel, tcphy->base + CMN_DIAG_HSCLK_SEL);
50618 + writel(phy_dp_clk_ctl, tcphy->base + PHY_DP_CLK_CTL);
50622 + writel(phy_cfg[i].value, tcphy->base + phy_cfg[i].addr);
50625 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50628 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50630 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50634 + dev_err(tcphy->dev, "wait DP PLL ready timeout\n");
50639 + reg = readl(tcphy->base + PHY_DP_CLK_CTL);
50642 + writel(reg, tcphy->base + PHY_DP_CLK_CTL);
50644 + ret = readl_poll_timeout(tcphy->base + PHY_DP_CLK_CTL, reg,
50648 + dev_err(tcphy->dev, "wait DP PLL clock enabled timeout\n");
50655 + dev_err(tcphy->dev, "failed to enter A2 state: %d\n", ret);
50662 + dev_err(tcphy->dev, "failed to enter A0 state: %d\n", ret);
50673 @@ -719,6 +1235,18 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
50674 writel(val, tcphy->base + TX_DIG_CTRL_REG_2);
50680 + const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50682 + property_enable(tcphy, &cfg->usb3tousb2_en, value);
50683 + property_enable(tcphy, &cfg->usb3_host_disable, value);
50684 + property_enable(tcphy, &cfg->usb3_host_port, !value);
50691 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50692 @@ -743,32 +1271,33 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
50699 - tcphy_cfg_dp_pll(tcphy);
50703 - tcphy_dp_cfg_lane(tcphy, i);
50704 -
50705 - writel(PIN_ASSIGN_C_E, tcphy->base + PMA_LANE_CFG);
50709 - tcphy_cfg_dp_pll(tcphy);
50711 if (tcphy->flip) {
50714 - tcphy_dp_cfg_lane(tcphy, 0);
50715 - tcphy_dp_cfg_lane(tcphy, 1);
50721 - tcphy_dp_cfg_lane(tcphy, 2);
50722 - tcphy_dp_cfg_lane(tcphy, 3);
50726 -
50727 - writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
50730 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
50731 + val = readl(tcphy->base + PHY_DP_MODE_CTL);
50734 + writel(val, tcphy->base + PHY_DP_MODE_CTL);
50736 reset_control_deassert(tcphy->uphy_rst);
50738 @@ -851,22 +1380,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
50742 -static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
50743 - bool value)
50746 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50747 -
50748 - property_enable(tcphy, &cfg->usb3tousb2_en, value);
50749 - property_enable(tcphy, &cfg->usb3_host_disable, value);
50750 - property_enable(tcphy, &cfg->usb3_host_port, !value);
50751 -
50752 - return 0;
50753 -}
50754 -
50755 -static int rockchip_usb3_phy_power_on(struct phy *phy)
50756 -{
50757 - struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
50758 - const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
50759 const struct usb3phy_reg *reg = &cfg->pipe_status;
50762 @@ -917,6 +1433,24 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
50779 + dev_info(tcphy->dev, "Needed %d loops to turn on\n", tries);
50787 @@ -980,8 +1514,8 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
50789 property_enable(tcphy, &cfg->uphy_dp_sel, 1);
50791 - ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
50792 - val, val & DP_MODE_A2, 1000,
50793 + ret = readx_poll_timeout(readl, tcphy->base + PHY_DP_MODE_CTL,
50797 dev_err(tcphy->dev, "failed to wait TCPHY enter A2\n");
50798 @@ -990,14 +1524,10 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
50802 - writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
50803 -
50804 - ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
50805 - val, val & DP_MODE_A0, 1000,
50806 - PHY_MODE_SET_TIMEOUT);
50807 - if (ret < 0) {
50808 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
50809 - dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
50813 + dev_err(tcphy->dev, "failed to enter A0 power state\n");
50817 @@ -1014,6 +1544,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
50823 mutex_lock(&tcphy->lock);
50825 @@ -1022,7 +1553,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
50827 tcphy->mode &= ~MODE_DFP_DP;
50829 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
50832 + dev_err(tcphy->dev, "failed to enter A2 power state\n");
50836 if (tcphy->mode == MODE_DISCONNECT)
50838 @@ -1041,6 +1576,8 @@ static const struct phy_ops rockchip_dp_phy_ops = {
50844 tcphy->grf_regs = syscon_regmap_lookup_by_phandle(dev->of_node,
50846 if (IS_ERR(tcphy->grf_regs)) {
50847 @@ -1078,6 +1615,16 @@ static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
50848 return PTR_ERR(tcphy->tcphy_rst);
50855 + ret = of_property_read_u32_array(dev->of_node, "rockchip,phy-config",
50856 + (u32 *)tcphy->config, sizeof(tcphy->config) / sizeof(u32));
50858 + memcpy(tcphy->config, tcphy_default_config,
50859 + sizeof(tcphy->config));
50864 diff --git a/drivers/phy/rockchip/phy-rockchip-usb.c b/drivers/phy/rockchip/phy-rockchip-usb.c
50866 --- a/drivers/phy/rockchip/phy-rockchip-usb.c
50867 +++ b/drivers/phy/rockchip/phy-rockchip-usb.c
50868 @@ -8,20 +8,26 @@
50871 #include <linux/clk-provider.h>
50873 +#include <linux/extcon-provider.h>
50890 -#include <linux/mfd/syscon.h>
50891 -#include <linux/delay.h>
50897 @@ -45,6 +51,69 @@ static int enable_usb_uart;
50967 @@ -61,20 +130,127 @@ struct rockchip_usb_phy_pdata {
50977 - struct device_node *np;
50978 - unsigned int reg_offset;
50979 - struct clk *clk;
50980 - struct clk *clk480m;
50981 - struct clk_hw clk480m_hw;
50982 - struct phy *phy;
50983 - bool uart_enabled;
50984 - struct reset_control *reset;
50985 - struct regulator *vbus;
51012 + return -EINVAL;
51015 + switch (rk_phy->mode) {
51028 + return -EINVAL;
51041 + return -EINVAL;
51044 + mutex_lock(&rk_phy->mutex);
51053 + dev_err(&rk_phy->phy->dev, "Error mode! Input 'otg' or 'host' or 'peripheral'\n");
51054 + ret = -EINVAL;
51058 + if (rk_phy->mode == new_dr_mode) {
51059 + dev_warn(&rk_phy->phy->dev, "Same as current mode.\n");
51063 + rk_phy->mode = new_dr_mode;
51065 + switch (rk_phy->mode) {
51082 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON3, val);
51085 + mutex_unlock(&rk_phy->mutex);
51104 @@ -136,6 +312,46 @@ static const struct clk_ops rockchip_usb_phy480m_ops = {
51114 + if (phy->bvalid_irq > 0) {
51115 + mutex_lock(&phy->mutex);
51122 + ret = regmap_write(phy->base->reg_base, RK3288_UOC0_CON4, val);
51124 + dev_err(phy->base->dev,
51129 + schedule_delayed_work(&phy->otg_sm_work, OTG_SCHEDULE_DELAY);
51132 + mutex_unlock(&phy->mutex);
51142 + if (phy->bvalid_irq > 0)
51143 + flush_delayed_work(&phy->otg_sm_work);
51151 @@ -179,7 +395,7 @@ static int rockchip_usb_phy_reset(struct phy *_phy)
51155 -static const struct phy_ops ops = {
51160 @@ -199,13 +415,383 @@ static void rockchip_usb_phy_action(void *data)
51161 clk_put(rk_phy->clk);
51167 + struct device_node *node = base->dev->of_node;
51171 + edev = extcon_get_edev_by_phandle(base->dev, 0);
51173 + if (PTR_ERR(edev) != -EPROBE_DEFER)
51174 + dev_err(base->dev,
51180 + edev = devm_extcon_dev_allocate(base->dev,
51184 + return -ENOMEM;
51186 + ret = devm_extcon_dev_register(base->dev, edev);
51188 + dev_err(base->dev,
51194 + base->edev = edev;
51211 + mutex_lock(&rk_phy->mutex);
51215 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS2, &val);
51218 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS2, &val);
51222 + if (!vbus_attached || !id || rk_phy->mode == USB_DR_MODE_HOST) {
51223 + dev_dbg(&rk_phy->phy->dev, "peripheral disconnected\n");
51224 + wake_unlock(&rk_phy->wakelock);
51225 + extcon_set_state_sync(rk_phy->base->edev, cable, false);
51226 + rk_phy->chg_state = USB_CHG_STATE_UNDEFINED;
51236 + switch (rk_phy->chg_state) {
51238 + mutex_unlock(&rk_phy->mutex);
51239 + schedule_delayed_work(&rk_phy->chg_work, 0);
51242 + switch (rk_phy->chg_type) {
51244 + dev_dbg(&rk_phy->phy->dev, "sdp cable is connected\n");
51245 + wake_lock(&rk_phy->wakelock);
51250 + dev_dbg(&rk_phy->phy->dev, "dcp cable is connected\n");
51255 + dev_dbg(&rk_phy->phy->dev, "cdp cable is connected\n");
51256 + wake_lock(&rk_phy->wakelock);
51269 + if (extcon_get_state(rk_phy->base->edev, cable) != vbus_attached)
51270 + extcon_set_state_sync(rk_phy->base->edev, cable,
51275 + schedule_delayed_work(&rk_phy->otg_sm_work, OTG_SCHEDULE_DELAY);
51277 + mutex_unlock(&rk_phy->mutex);
51306 + dev_dbg(&rk_phy->phy->dev, "chg detection work state = %d\n",
51307 + rk_phy->chg_state);
51309 + switch (rk_phy->chg_state) {
51311 + mutex_lock(&rk_phy->mutex);
51312 + /* put the controller in non-driving mode */
51315 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51319 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON3, val);
51323 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51324 + rk_phy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
51331 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS19, &val);
51340 + regmap_write(rk_phy->base->reg_base,
51348 + regmap_write(rk_phy->base->reg_base,
51351 + rk_phy->chg_state = USB_CHG_STATE_DCD_DONE;
51358 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS19, &val);
51363 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51372 + regmap_write(rk_phy->base->reg_base,
51375 + rk_phy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
51379 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
51380 + rk_phy->chg_state = USB_CHG_STATE_DETECTED;
51386 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB;
51387 + rk_phy->chg_state = USB_CHG_STATE_DETECTED;
51393 + regmap_read(rk_phy->base->reg_base, RK3288_SOC_STATUS19, &val);
51400 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51402 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
51404 + rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
51407 + rk_phy->chg_state = USB_CHG_STATE_DETECTED;
51412 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON2, val);
51416 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON3, val);
51417 + mutex_unlock(&rk_phy->mutex);
51418 + rk3288_usb_phy_otg_sm_work(&rk_phy->otg_sm_work.work);
51419 + dev_info(&rk_phy->phy->dev, "charger = %s\n",
51420 + chg_to_string(rk_phy->chg_type));
51423 + mutex_unlock(&rk_phy->mutex);
51432 + schedule_delayed_work(&rk_phy->chg_work, delay);
51441 + ret = regmap_read(rk_phy->base->reg_base, RK3288_UOC0_CON4, &val);
51445 + mutex_lock(&rk_phy->mutex);
51450 + regmap_write(rk_phy->base->reg_base, RK3288_UOC0_CON4, val);
51452 + mutex_unlock(&rk_phy->mutex);
51454 + if (rk_phy->uart_enabled)
51457 + cancel_delayed_work_sync(&rk_phy->otg_sm_work);
51458 + rk3288_usb_phy_otg_sm_work(&rk_phy->otg_sm_work.work);
51468 + if (rk_phy->reg_offset == 0x320) {
51472 + rk_phy->bvalid_irq = of_irq_get_byname(rk_phy->np,
51473 + "otg-bvalid");
51474 + regmap_read(rk_phy->base->reg_base, RK3288_UOC0_CON4, &val);
51475 + if (rk_phy->bvalid_irq <= 0) {
51476 + dev_err(&rk_phy->phy->dev,
51478 + ret = -EINVAL;
51482 + ret = devm_request_threaded_irq(rk_phy->base->dev,
51483 + rk_phy->bvalid_irq,
51490 + dev_err(&rk_phy->phy->dev,
51491 + "failed to request otg-bvalid irq handle\n");
51495 + rk_phy->chg_state = USB_CHG_STATE_UNDEFINED;
51496 + wake_lock_init(&rk_phy->wakelock, WAKE_LOCK_SUSPEND,
51498 + INIT_DELAYED_WORK(&rk_phy->chg_work, rk3288_chg_detect_work);
51499 + INIT_DELAYED_WORK(&rk_phy->otg_sm_work,
51502 + rk_phy->mode = of_usb_get_dr_mode_by_phy(rk_phy->np, -1);
51503 + if (rk_phy->mode == USB_DR_MODE_OTG ||
51504 + rk_phy->mode == USB_DR_MODE_UNKNOWN) {
51505 + ret = sysfs_create_group(&rk_phy->phy->dev.kobj,
51508 + dev_err(&rk_phy->phy->dev,
51513 + } else if (rk_phy->reg_offset == 0x334) {
51517 + * EHCI (auto) suspend causes the corresponding usb-phy into
51519 + * usb-phy if the COMMONONN is set to 1'b1. The PLL output
51524 + * usb-phy always powered.
51526 + regmap_write(rk_phy->base->reg_base, rk_phy->reg_offset,
51536 + struct device_node *np = base->dev->of_node;
51540 - struct clk_init_data init;
51544 rk_phy = devm_kzalloc(base->dev, sizeof(*rk_phy), GFP_KERNEL);
51545 @@ -214,6 +800,7 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
51547 rk_phy->base = base;
51548 rk_phy->np = child;
51549 + mutex_init(&rk_phy->mutex);
51552 dev_err(base->dev, "missing reg property in node %pOFn\n",
51553 @@ -288,6 +875,12 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
51555 phy_set_drvdata(rk_phy->phy, rk_phy);
51557 + if (of_device_is_compatible(np, "rockchip,rk3288-usb-phy")) {
51563 rk_phy->vbus = devm_regulator_get_optional(&rk_phy->phy->dev, "vbus");
51564 if (IS_ERR(rk_phy->vbus)) {
51565 if (PTR_ERR(rk_phy->vbus) == -EPROBE_DEFER)
51566 @@ -402,10 +995,6 @@ static const struct rockchip_usb_phy_pdata rk3188_pdata = {
51570 -#define RK3288_UOC0_CON3 0x32c
51571 -#define RK3288_UOC0_CON3_BYPASSDMEN BIT(6)
51572 -#define RK3288_UOC0_CON3_BYPASSSEL BIT(7)
51573 -
51577 @@ -487,6 +1076,10 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
51578 return PTR_ERR(phy_base->reg_base);
51585 for_each_available_child_of_node(dev->of_node, child) {
51588 @@ -496,6 +1089,7 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
51596 diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
51598 --- a/drivers/pinctrl/Kconfig
51600 @@ -207,13 +207,18 @@ config PINCTRL_OXNAS
51601 select MFD_SYSCON
51604 - bool
51608 + select GPIOLIB
51609 select PINMUX
51610 select GENERIC_PINCONF
51611 select GENERIC_IRQ_CHIP
51612 select MFD_SYSCON
51613 select OF_GPIO
51619 tristate "One-register-per-pin type device tree based pinctrl driver"
51620 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
51622 --- a/drivers/pinctrl/Makefile
51624 @@ -72,3 +72,5 @@ obj-y += mediatek/
51625 obj-$(CONFIG_PINCTRL_ZX) += zte/
51626 obj-y += cirrus/
51627 obj-$(CONFIG_PINCTRL_VISCONTI) += visconti/
51629 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/pinctrl
51630 diff --git a/drivers/pinctrl/pinctrl-rk805.c b/drivers/pinctrl/pinctrl-rk805.c
51632 --- a/drivers/pinctrl/pinctrl-rk805.c
51633 +++ b/drivers/pinctrl/pinctrl-rk805.c
51634 @@ -78,6 +78,7 @@ struct rk805_pctrl_info {
51642 @@ -132,12 +133,167 @@ static const struct rk805_pin_config rk805_gpio_cfgs[] = {
51801 + if (!pci->pin_cfg[offset].val_msk) {
51802 + dev_dbg(pci->dev, "getting gpio%d value is not support\n",
51804 + return -1;
51807 ret = regmap_read(pci->rk808->regmap, pci->pin_cfg[offset].reg, &val);
51809 dev_err(pci->dev, "get gpio%d value failed\n", offset);
51810 @@ -154,6 +310,9 @@ static void rk805_gpio_set(struct gpio_chip *chip,
51814 + if (!pci->pin_cfg[offset].val_msk)
51817 ret = regmap_update_bits(pci->rk808->regmap,
51818 pci->pin_cfg[offset].reg,
51819 pci->pin_cfg[offset].val_msk,
51820 @@ -214,6 +373,34 @@ static const struct gpio_chip rk805_gpio_chip = {
51825 + .label = "rk816-gpio",
51834 + .base = -1,
51839 + .label = "rk817-gpio",
51848 + .base = -1,
51855 @@ -289,7 +476,7 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
51856 if (!pci->pin_cfg[offset].fun_msk)
51859 - if (mux == RK805_PINMUX_GPIO) {
51861 ret = regmap_update_bits(pci->rk808->regmap,
51862 pci->pin_cfg[offset].reg,
51863 pci->pin_cfg[offset].fun_msk,
51864 @@ -298,6 +485,15 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
51865 dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
51869 + ret = regmap_update_bits(pci->rk808->regmap,
51870 + pci->pin_cfg[offset].reg,
51871 + pci->pin_cfg[offset].fun_msk,
51874 + dev_err(pci->dev, "set gpio%d TS failed\n", offset);
51878 dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
51879 return -EINVAL;
51880 @@ -306,6 +502,27 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
51891 + if (!pci->pin_cfg[offset].fun_msk)
51894 + mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1;
51895 + ret = regmap_update_bits(pci->rk808->regmap,
51896 + pci->pin_cfg[offset].reg,
51897 + pci->pin_cfg[offset].fun_msk, mux);
51900 + dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux);
51908 @@ -314,7 +531,18 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
51909 int mux = pci->functions[function].mux_option;
51912 - return _rk805_pinctrl_set_mux(pctldev, offset, mux);
51913 + switch (pci->rk808->variant) {
51922 + dev_err(pci->dev, "Couldn't find the variant id\n");
51923 + return -EINVAL;
51928 @@ -324,13 +552,6 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
51932 - /* switch to gpio function */
51933 - ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
51934 - if (ret) {
51935 - dev_err(pci->dev, "set gpio%d mux failed\n", offset);
51936 - return ret;
51937 - }
51938 -
51940 if (!pci->pin_cfg[offset].dir_msk)
51942 @@ -347,7 +568,25 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
51953 + switch (pci->rk808->variant) {
51968 @@ -364,6 +603,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
51973 arg = rk805_gpio_get(&pci->gpio_chip, pin);
51976 @@ -390,8 +630,13 @@ static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
51980 - rk805_gpio_set(&pci->gpio_chip, pin, arg);
51982 + rk805_gpio_set(&pci->gpio_chip, pin, arg);
51990 dev_err(pci->dev, "Properties not supported\n");
51991 @@ -415,9 +660,26 @@ static const struct pinctrl_desc rk805_pinctrl_desc = {
51996 + .name = "rk816-pinctrl",
52004 + .name = "rk817-pinctrl",
52017 pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
52018 @@ -425,18 +687,19 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
52019 return -ENOMEM;
52021 pci->dev = &pdev->dev;
52022 - pci->dev->of_node = pdev->dev.parent->of_node;
52023 + np = of_get_child_by_name(pdev->dev.parent->of_node, "pinctrl_rk8xx");
52025 + pci->dev->of_node = np;
52027 + pci->dev->of_node = pdev->dev.parent->of_node;
52028 pci->rk808 = dev_get_drvdata(pdev->dev.parent);
52030 - pci->pinctrl_desc = rk805_pinctrl_desc;
52031 - pci->gpio_chip = rk805_gpio_chip;
52032 - pci->gpio_chip.parent = &pdev->dev;
52033 - pci->gpio_chip.of_node = pdev->dev.parent->of_node;
52034 -
52037 switch (pci->rk808->variant) {
52039 + pci->pinctrl_desc = rk805_pinctrl_desc;
52040 + pci->gpio_chip = rk805_gpio_chip;
52041 pci->pins = rk805_pins_desc;
52042 pci->num_pins = ARRAY_SIZE(rk805_pins_desc);
52043 pci->functions = rk805_pin_functions;
52044 @@ -448,13 +711,59 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
52045 pci->pin_cfg = rk805_gpio_cfgs;
52046 pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
52050 + pci->pinctrl_desc = rk816_pinctrl_desc;
52051 + pci->gpio_chip = rk816_gpio_chip;
52052 + pci->pins = rk816_pins_desc;
52053 + pci->num_pins = ARRAY_SIZE(rk816_pins_desc);
52054 + pci->functions = rk816_pin_functions;
52055 + pci->num_functions = ARRAY_SIZE(rk816_pin_functions);
52056 + pci->groups = rk816_pin_groups;
52057 + pci->num_pin_groups = ARRAY_SIZE(rk816_pin_groups);
52058 + pci->pinctrl_desc.pins = rk816_pins_desc;
52059 + pci->pinctrl_desc.npins = ARRAY_SIZE(rk816_pins_desc);
52060 + pci->pin_cfg = rk816_gpio_cfgs;
52061 + pci->gpio_chip.ngpio = ARRAY_SIZE(rk816_gpio_cfgs);
52066 + pci->pinctrl_desc = rk817_pinctrl_desc;
52067 + pci->gpio_chip = rk817_gpio_chip;
52068 + pci->pins = rk817_pins_desc;
52069 + pci->num_pins = ARRAY_SIZE(rk817_pins_desc);
52070 + pci->functions = rk817_pin_functions;
52071 + pci->num_functions = ARRAY_SIZE(rk817_pin_functions);
52072 + pci->groups = rk817_pin_groups;
52073 + pci->num_pin_groups = ARRAY_SIZE(rk817_pin_groups);
52074 + pci->pinctrl_desc.pins = rk817_pins_desc;
52075 + pci->pinctrl_desc.npins = ARRAY_SIZE(rk817_pins_desc);
52076 + pci->pin_cfg = rk817_gpio_cfgs;
52077 + pci->gpio_chip.ngpio = ARRAY_SIZE(rk817_gpio_cfgs);
52079 + if (pci->rk808->variant == RK809_ID) {
52080 + pci->pinctrl_desc.npins = 1;
52081 + pci->num_pin_groups = 1;
52082 + pci->num_pins = 1;
52083 + pci->gpio_chip.ngpio = 1;
52088 dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
52089 pci->rk808->variant);
52090 return -EINVAL;
52093 - /* Add gpio chip */
52094 + pci->gpio_chip.parent = &pdev->dev;
52097 + pci->gpio_chip.of_node = np;
52099 + pci->gpio_chip.of_node = pdev->dev.parent->of_node;
52102 ret = devm_gpiochip_add_data(&pdev->dev, &pci->gpio_chip, pci);
52104 dev_err(&pdev->dev, "Couldn't add gpiochip\n");
52105 @@ -485,7 +794,12 @@ static struct platform_driver rk805_pinctrl_driver = {
52106 .name = "rk805-pinctrl",
52109 -module_platform_driver(rk805_pinctrl_driver);
52118 MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
52119 diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
52121 --- a/drivers/pinctrl/pinctrl-rockchip.c
52122 +++ b/drivers/pinctrl/pinctrl-rockchip.c
52123 @@ -16,12 +16,14 @@
52131 -#include <linux/gpio/driver.h>
52139 @@ -31,37 +33,19 @@
52144 #include <dt-bindings/pinctrl/rockchip.h>
52148 +#include "pinctrl-rockchip.h"
52150 -/* GPIO control registers */
52151 -#define GPIO_SWPORT_DR 0x00
52152 -#define GPIO_SWPORT_DDR 0x04
52153 -#define GPIO_INTEN 0x30
52154 -#define GPIO_INTMASK 0x34
52155 -#define GPIO_INTTYPE_LEVEL 0x38
52156 -#define GPIO_INT_POLARITY 0x3c
52157 -#define GPIO_INT_STATUS 0x40
52158 -#define GPIO_INT_RAWSTATUS 0x44
52159 -#define GPIO_DEBOUNCE 0x48
52160 -#define GPIO_PORTS_EOI 0x4c
52161 -#define GPIO_EXT_PORT 0x50
52162 -#define GPIO_LS_SYNC 0x60
52163 -
52164 -enum rockchip_pinctrl_type {
52165 - PX30,
52166 - RV1108,
52167 - RK2928,
52168 - RK3066B,
52169 - RK3128,
52170 - RK3188,
52171 - RK3288,
52172 - RK3308,
52173 - RK3368,
52174 - RK3399,
52175 -};
52185 @@ -72,103 +56,8 @@ enum rockchip_pinctrl_type {
52189 -
52190 -/**
52191 - * struct rockchip_iomux
52192 - * @type: iomux variant using IOMUX_* constants
52193 - * @offset: if initialized to -1 it will be autocalculated, by specifying
52194 - * an initial offset value the relevant source offset can be reset
52195 - * to a new value for autocalculating the following iomux registers.
52196 - */
52197 -struct rockchip_iomux {
52198 - int type;
52199 - int offset;
52200 -};
52201 -
52202 -/*
52203 - * enum type index corresponding to rockchip_perpin_drv_list arrays index.
52204 - */
52205 -enum rockchip_pin_drv_type {
52206 - DRV_TYPE_IO_DEFAULT = 0,
52207 - DRV_TYPE_IO_1V8_OR_3V0,
52208 - DRV_TYPE_IO_1V8_ONLY,
52209 - DRV_TYPE_IO_1V8_3V0_AUTO,
52210 - DRV_TYPE_IO_3V3_ONLY,
52211 - DRV_TYPE_MAX
52212 -};
52213 -
52214 -/*
52215 - * enum type index corresponding to rockchip_pull_list arrays index.
52216 - */
52217 -enum rockchip_pin_pull_type {
52218 - PULL_TYPE_IO_DEFAULT = 0,
52219 - PULL_TYPE_IO_1V8_ONLY,
52220 - PULL_TYPE_MAX
52221 -};
52222 -
52223 -/**
52224 - * struct rockchip_drv
52225 - * @drv_type: drive strength variant using rockchip_perpin_drv_type
52226 - * @offset: if initialized to -1 it will be autocalculated, by specifying
52227 - * an initial offset value the relevant source offset can be reset
52228 - * to a new value for autocalculating the following drive strength
52229 - * registers. if used chips own cal_drv func instead to calculate
52230 - * registers offset, the variant could be ignored.
52231 - */
52232 -struct rockchip_drv {
52233 - enum rockchip_pin_drv_type drv_type;
52234 - int offset;
52235 -};
52236 -
52237 -/**
52238 - * struct rockchip_pin_bank
52239 - * @reg_base: register base of the gpio bank
52240 - * @regmap_pull: optional separate register for additional pull settings
52241 - * @clk: clock of the gpio bank
52242 - * @irq: interrupt of the gpio bank
52243 - * @saved_masks: Saved content of GPIO_INTEN at suspend time.
52244 - * @pin_base: first pin number
52245 - * @nr_pins: number of pins in this bank
52246 - * @name: name of the bank
52247 - * @bank_num: number of the bank, to account for holes
52248 - * @iomux: array describing the 4 iomux sources of the bank
52249 - * @drv: array describing the 4 drive strength sources of the bank
52250 - * @pull_type: array describing the 4 pull type sources of the bank
52251 - * @valid: is all necessary information present
52252 - * @of_node: dt node of this bank
52253 - * @drvdata: common pinctrl basedata
52254 - * @domain: irqdomain of the gpio bank
52255 - * @gpio_chip: gpiolib chip
52256 - * @grange: gpio range
52257 - * @slock: spinlock for the gpio bank
52258 - * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode
52259 - * @recalced_mask: bit mask to indicate a need to recalulate the mask
52260 - * @route_mask: bits describing the routing pins of per bank
52261 - */
52262 -struct rockchip_pin_bank {
52263 - void __iomem *reg_base;
52264 - struct regmap *regmap_pull;
52265 - struct clk *clk;
52266 - int irq;
52267 - u32 saved_masks;
52268 - u32 pin_base;
52269 - u8 nr_pins;
52270 - char *name;
52271 - u8 bank_num;
52272 - struct rockchip_iomux iomux[4];
52273 - struct rockchip_drv drv[4];
52274 - enum rockchip_pin_pull_type pull_type[4];
52275 - bool valid;
52276 - struct device_node *of_node;
52277 - struct rockchip_pinctrl *drvdata;
52278 - struct irq_domain *domain;
52279 - struct gpio_chip gpio_chip;
52280 - struct pinctrl_gpio_range grange;
52281 - raw_spinlock_t slock;
52282 - u32 toggle_edge_mode;
52283 - u32 recalced_mask;
52284 - u32 route_mask;
52285 -};
52291 @@ -196,6 +85,21 @@ struct rockchip_pin_bank {
52313 @@ -290,118 +194,24 @@ struct rockchip_pin_bank {
52317 -/**
52318 - * struct rockchip_mux_recalced_data: represent a pin iomux data.
52319 - * @num: bank number.
52320 - * @pin: pin number.
52321 - * @bit: index at register.
52322 - * @reg: register offset.
52323 - * @mask: mask bit
52324 - */
52325 -struct rockchip_mux_recalced_data {
52326 - u8 num;
52327 - u8 pin;
52328 - u32 reg;
52329 - u8 bit;
52330 - u8 mask;
52331 -};
52332 -
52333 -enum rockchip_mux_route_location {
52334 - ROCKCHIP_ROUTE_SAME = 0,
52335 - ROCKCHIP_ROUTE_PMU,
52336 - ROCKCHIP_ROUTE_GRF,
52337 -};
52338 -
52339 -/**
52340 - * struct rockchip_mux_recalced_data: represent a pin iomux data.
52341 - * @bank_num: bank number.
52342 - * @pin: index at register or used to calc index.
52343 - * @func: the min pin.
52344 - * @route_location: the mux route location (same, pmu, grf).
52345 - * @route_offset: the max pin.
52346 - * @route_val: the register offset.
52347 - */
52348 -struct rockchip_mux_route_data {
52349 - u8 bank_num;
52350 - u8 pin;
52351 - u8 func;
52352 - enum rockchip_mux_route_location route_location;
52353 - u32 route_offset;
52354 - u32 route_val;
52355 -};
52356 -
52357 -struct rockchip_pin_ctrl {
52358 - struct rockchip_pin_bank *pin_banks;
52359 - u32 nr_banks;
52360 - u32 nr_pins;
52361 - char *label;
52362 - enum rockchip_pinctrl_type type;
52363 - int grf_mux_offset;
52364 - int pmu_mux_offset;
52365 - int grf_drv_offset;
52366 - int pmu_drv_offset;
52367 - struct rockchip_mux_recalced_data *iomux_recalced;
52368 - u32 niomux_recalced;
52369 - struct rockchip_mux_route_data *iomux_routes;
52370 - u32 niomux_routes;
52371 -
52372 - void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
52373 - int pin_num, struct regmap **regmap,
52374 - int *reg, u8 *bit);
52375 - void (*drv_calc_reg)(struct rockchip_pin_bank *bank,
52376 - int pin_num, struct regmap **regmap,
52377 - int *reg, u8 *bit);
52378 - int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
52379 - int pin_num, struct regmap **regmap,
52380 - int *reg, u8 *bit);
52381 -};
52382 -
52383 -struct rockchip_pin_config {
52384 - unsigned int func;
52385 - unsigned long *configs;
52386 - unsigned int nconfigs;
52387 -};
52398 -/**
52399 - * struct rockchip_pin_group: represent group of pins of a pinmux function.
52400 - * @name: name of the pin group, used to lookup the group.
52401 - * @pins: the pins included in this group.
52402 - * @npins: number of pins included in this group.
52403 - * @data: local pin configuration
52404 - */
52405 -struct rockchip_pin_group {
52406 - const char *name;
52407 - unsigned int npins;
52408 - unsigned int *pins;
52409 - struct rockchip_pin_config *data;
52410 -};
52414 -/**
52415 - * struct rockchip_pmx_func: represent a pin function.
52416 - * @name: name of the pin function, used to lookup the function.
52417 - * @groups: one or more names of pin groups that provide this function.
52418 - * @ngroups: number of groups included in @groups.
52419 - */
52420 -struct rockchip_pmx_func {
52421 - const char *name;
52422 - const char **groups;
52423 - u8 ngroups;
52424 -};
52428 -struct rockchip_pinctrl {
52429 - struct regmap *regmap_base;
52430 - int reg_size;
52431 - struct regmap *regmap_pull;
52432 - struct regmap *regmap_pmu;
52433 - struct device *dev;
52434 - struct rockchip_pin_ctrl *ctrl;
52435 - struct pinctrl_desc pctl;
52436 - struct pinctrl_dev *pctl_dev;
52437 - struct rockchip_pin_group *groups;
52438 - unsigned int ngroups;
52439 - struct rockchip_pmx_func *functions;
52440 - unsigned int nfunctions;
52441 -};
52447 @@ -627,6 +437,37 @@ static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
52485 @@ -772,11 +613,47 @@ static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
52533 @@ -792,6 +669,103 @@ static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
52637 @@ -815,598 +789,218 @@ static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int p…
52638 *bit = data->bit;
52656 - {
52657 - /* cif-d2m0 */
52658 - .bank_num = 2,
52659 - .pin = 0,
52660 - .func = 1,
52661 - .route_offset = 0x184,
52662 - .route_val = BIT(16 + 7),
52663 - }, {
52664 - /* cif-d2m1 */
52665 - .bank_num = 3,
52666 - .pin = 3,
52667 - .func = 3,
52668 - .route_offset = 0x184,
52669 - .route_val = BIT(16 + 7) | BIT(7),
52670 - }, {
52671 - /* pdm-m0 */
52672 - .bank_num = 3,
52673 - .pin = 22,
52674 - .func = 2,
52675 - .route_offset = 0x184,
52676 - .route_val = BIT(16 + 8),
52677 - }, {
52678 - /* pdm-m1 */
52679 - .bank_num = 2,
52680 - .pin = 22,
52681 - .func = 1,
52682 - .route_offset = 0x184,
52683 - .route_val = BIT(16 + 8) | BIT(8),
52684 - }, {
52685 - /* uart2-rxm0 */
52686 - .bank_num = 1,
52687 - .pin = 27,
52688 - .func = 2,
52689 - .route_offset = 0x184,
52690 - .route_val = BIT(16 + 10),
52691 - }, {
52692 - /* uart2-rxm1 */
52693 - .bank_num = 2,
52694 - .pin = 14,
52695 - .func = 2,
52696 - .route_offset = 0x184,
52697 - .route_val = BIT(16 + 10) | BIT(10),
52698 - }, {
52699 - /* uart3-rxm0 */
52700 - .bank_num = 0,
52701 - .pin = 17,
52702 - .func = 2,
52703 - .route_offset = 0x184,
52704 - .route_val = BIT(16 + 9),
52705 - }, {
52706 - /* uart3-rxm1 */
52707 - .bank_num = 1,
52708 - .pin = 15,
52709 - .func = 2,
52710 - .route_offset = 0x184,
52711 - .route_val = BIT(16 + 9) | BIT(9),
52712 - },
52713 + RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */
52714 + RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */
52715 + RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */
52716 + RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */
52717 + RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */
52718 + RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */
52719 + RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */
52720 + RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */
52724 - {
52725 - /* spi-0 */
52726 - .bank_num = 1,
52727 - .pin = 10,
52728 - .func = 1,
52729 - .route_offset = 0x144,
52730 - .route_val = BIT(16 + 3) | BIT(16 + 4),
52731 - }, {
52732 - /* spi-1 */
52733 - .bank_num = 1,
52734 - .pin = 27,
52735 - .func = 3,
52736 - .route_offset = 0x144,
52737 - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3),
52738 - }, {
52739 - /* spi-2 */
52740 - .bank_num = 0,
52741 - .pin = 13,
52742 - .func = 2,
52743 - .route_offset = 0x144,
52744 - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4),
52745 - }, {
52746 - /* i2s-0 */
52747 - .bank_num = 1,
52748 - .pin = 5,
52749 - .func = 1,
52750 - .route_offset = 0x144,
52751 - .route_val = BIT(16 + 5),
52752 - }, {
52753 - /* i2s-1 */
52754 - .bank_num = 0,
52755 - .pin = 14,
52756 - .func = 1,
52757 - .route_offset = 0x144,
52758 - .route_val = BIT(16 + 5) | BIT(5),
52759 - }, {
52760 - /* emmc-0 */
52761 - .bank_num = 1,
52762 - .pin = 22,
52763 - .func = 2,
52764 - .route_offset = 0x144,
52765 - .route_val = BIT(16 + 6),
52766 - }, {
52767 - /* emmc-1 */
52768 - .bank_num = 2,
52769 - .pin = 4,
52770 - .func = 2,
52771 - .route_offset = 0x144,
52772 - .route_val = BIT(16 + 6) | BIT(6),
52773 - },
52774 + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */
52775 + RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */
52776 + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */
52777 + RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */
52778 + RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */
52779 + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */
52780 + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */
52784 - {
52785 - /* non-iomuxed emmc/flash pins on flash-dqs */
52786 - .bank_num = 0,
52787 - .pin = 24,
52788 - .func = 1,
52789 - .route_location = ROCKCHIP_ROUTE_GRF,
52790 - .route_offset = 0xa0,
52791 - .route_val = BIT(16 + 11),
52792 - }, {
52793 - /* non-iomuxed emmc/flash pins on emmc-clk */
52794 - .bank_num = 0,
52795 - .pin = 24,
52796 - .func = 2,
52797 - .route_location = ROCKCHIP_ROUTE_GRF,
52798 - .route_offset = 0xa0,
52799 - .route_val = BIT(16 + 11) | BIT(11),
52800 - },
52801 + RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
52802 …UTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
52806 - {
52807 - /* pwm0-0 */
52808 - .bank_num = 0,
52809 - .pin = 26,
52810 - .func = 1,
52811 - .route_offset = 0x50,
52812 - .route_val = BIT(16),
52813 - }, {
52814 - /* pwm0-1 */
52815 - .bank_num = 3,
52816 - .pin = 21,
52817 - .func = 1,
52818 - .route_offset = 0x50,
52819 - .route_val = BIT(16) | BIT(0),
52820 - }, {
52821 - /* pwm1-0 */
52822 - .bank_num = 0,
52823 - .pin = 27,
52824 - .func = 1,
52825 - .route_offset = 0x50,
52826 - .route_val = BIT(16 + 1),
52827 - }, {
52828 - /* pwm1-1 */
52829 - .bank_num = 0,
52830 - .pin = 30,
52831 - .func = 2,
52832 - .route_offset = 0x50,
52833 - .route_val = BIT(16 + 1) | BIT(1),
52834 - }, {
52835 - /* pwm2-0 */
52836 - .bank_num = 0,
52837 - .pin = 28,
52838 - .func = 1,
52839 - .route_offset = 0x50,
52840 - .route_val = BIT(16 + 2),
52841 - }, {
52842 - /* pwm2-1 */
52843 - .bank_num = 1,
52844 - .pin = 12,
52845 - .func = 2,
52846 - .route_offset = 0x50,
52847 - .route_val = BIT(16 + 2) | BIT(2),
52848 - }, {
52849 - /* pwm3-0 */
52850 - .bank_num = 3,
52851 - .pin = 26,
52852 - .func = 1,
52853 - .route_offset = 0x50,
52854 - .route_val = BIT(16 + 3),
52855 - }, {
52856 - /* pwm3-1 */
52857 - .bank_num = 1,
52858 - .pin = 11,
52859 - .func = 2,
52860 - .route_offset = 0x50,
52861 - .route_val = BIT(16 + 3) | BIT(3),
52862 - }, {
52863 - /* sdio-0_d0 */
52864 - .bank_num = 1,
52865 - .pin = 1,
52866 - .func = 1,
52867 - .route_offset = 0x50,
52868 - .route_val = BIT(16 + 4),
52869 - }, {
52870 - /* sdio-1_d0 */
52871 - .bank_num = 3,
52872 - .pin = 2,
52873 - .func = 1,
52874 - .route_offset = 0x50,
52875 - .route_val = BIT(16 + 4) | BIT(4),
52876 - }, {
52877 - /* spi-0_rx */
52878 - .bank_num = 0,
52879 - .pin = 13,
52880 - .func = 2,
52881 - .route_offset = 0x50,
52882 - .route_val = BIT(16 + 5),
52883 - }, {
52884 - /* spi-1_rx */
52885 - .bank_num = 2,
52886 - .pin = 0,
52887 - .func = 2,
52888 - .route_offset = 0x50,
52889 - .route_val = BIT(16 + 5) | BIT(5),
52890 - }, {
52891 - /* emmc-0_cmd */
52892 - .bank_num = 1,
52893 - .pin = 22,
52894 - .func = 2,
52895 - .route_offset = 0x50,
52896 - .route_val = BIT(16 + 7),
52897 - }, {
52898 - /* emmc-1_cmd */
52899 - .bank_num = 2,
52900 - .pin = 4,
52901 - .func = 2,
52902 - .route_offset = 0x50,
52903 - .route_val = BIT(16 + 7) | BIT(7),
52904 - }, {
52905 - /* uart2-0_rx */
52906 - .bank_num = 1,
52907 - .pin = 19,
52908 - .func = 2,
52909 - .route_offset = 0x50,
52910 - .route_val = BIT(16 + 8),
52911 - }, {
52912 - /* uart2-1_rx */
52913 - .bank_num = 1,
52914 - .pin = 10,
52915 - .func = 2,
52916 - .route_offset = 0x50,
52917 - .route_val = BIT(16 + 8) | BIT(8),
52918 - }, {
52919 - /* uart1-0_rx */
52920 - .bank_num = 1,
52921 - .pin = 10,
52922 - .func = 1,
52923 - .route_offset = 0x50,
52924 - .route_val = BIT(16 + 11),
52925 - }, {
52926 - /* uart1-1_rx */
52927 - .bank_num = 3,
52928 - .pin = 13,
52929 - .func = 1,
52930 - .route_offset = 0x50,
52931 - .route_val = BIT(16 + 11) | BIT(11),
52932 - },
52933 + RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */
52934 + RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */
52935 + RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */
52936 + RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */
52937 + RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */
52938 + RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */
52939 + RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */
52940 + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */
52941 + RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */
52942 + RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */
52943 + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */
52944 + RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */
52945 + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */
52946 + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */
52947 + RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */
52948 + RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */
52949 + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */
52950 + RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */
52954 - {
52955 - /* edphdmi_cecinoutt1 */
52956 - .bank_num = 7,
52957 - .pin = 16,
52958 - .func = 2,
52959 - .route_offset = 0x264,
52960 - .route_val = BIT(16 + 12) | BIT(12),
52961 - }, {
52962 - /* edphdmi_cecinout */
52963 - .bank_num = 7,
52964 - .pin = 23,
52965 - .func = 4,
52966 - .route_offset = 0x264,
52967 - .route_val = BIT(16 + 12),
52968 - },
52974 - {
52975 - /* rtc_clk */
52976 - .bank_num = 0,
52977 - .pin = 19,
52978 - .func = 1,
52979 - .route_offset = 0x314,
52980 - .route_val = BIT(16 + 0) | BIT(0),
52981 - }, {
52982 - /* uart2_rxm0 */
52983 - .bank_num = 1,
52984 - .pin = 22,
52985 - .func = 2,
52986 - .route_offset = 0x314,
52987 - .route_val = BIT(16 + 2) | BIT(16 + 3),
52988 - }, {
52989 - /* uart2_rxm1 */
52990 - .bank_num = 4,
52991 - .pin = 26,
52992 - .func = 2,
52993 - .route_offset = 0x314,
52994 - .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
52995 - }, {
52996 - /* i2c3_sdam0 */
52997 - .bank_num = 0,
52998 - .pin = 15,
52999 - .func = 2,
53000 - .route_offset = 0x608,
53001 - .route_val = BIT(16 + 8) | BIT(16 + 9),
53002 - }, {
53003 - /* i2c3_sdam1 */
53004 - .bank_num = 3,
53005 - .pin = 12,
53006 - .func = 2,
53007 - .route_offset = 0x608,
53008 - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8),
53009 - }, {
53010 - /* i2c3_sdam2 */
53011 - .bank_num = 2,
53012 - .pin = 0,
53013 - .func = 3,
53014 - .route_offset = 0x608,
53015 - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9),
53016 - }, {
53017 - /* i2s-8ch-1-sclktxm0 */
53018 - .bank_num = 1,
53019 - .pin = 3,
53020 - .func = 2,
53021 - .route_offset = 0x308,
53022 - .route_val = BIT(16 + 3),
53023 - }, {
53024 - /* i2s-8ch-1-sclkrxm0 */
53025 - .bank_num = 1,
53026 - .pin = 4,
53027 - .func = 2,
53028 - .route_offset = 0x308,
53029 - .route_val = BIT(16 + 3),
53030 - }, {
53031 - /* i2s-8ch-1-sclktxm1 */
53032 - .bank_num = 1,
53033 - .pin = 13,
53034 - .func = 2,
53035 - .route_offset = 0x308,
53036 - .route_val = BIT(16 + 3) | BIT(3),
53037 - }, {
53038 - /* i2s-8ch-1-sclkrxm1 */
53039 - .bank_num = 1,
53040 - .pin = 14,
53041 - .func = 2,
53042 - .route_offset = 0x308,
53043 - .route_val = BIT(16 + 3) | BIT(3),
53044 - }, {
53045 - /* pdm-clkm0 */
53046 - .bank_num = 1,
53047 - .pin = 4,
53048 - .func = 3,
53049 - .route_offset = 0x308,
53050 - .route_val = BIT(16 + 12) | BIT(16 + 13),
53051 - }, {
53052 - /* pdm-clkm1 */
53053 - .bank_num = 1,
53054 - .pin = 14,
53055 - .func = 4,
53056 - .route_offset = 0x308,
53057 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
53058 - }, {
53059 - /* pdm-clkm2 */
53060 - .bank_num = 2,
53061 - .pin = 6,
53062 - .func = 2,
53063 - .route_offset = 0x308,
53064 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
53065 - }, {
53066 - /* pdm-clkm-m2 */
53067 - .bank_num = 2,
53068 - .pin = 4,
53069 - .func = 3,
53070 - .route_offset = 0x600,
53071 - .route_val = BIT(16 + 2) | BIT(2),
53072 - }, {
53073 - /* spi1_miso */
53074 - .bank_num = 3,
53075 - .pin = 10,
53076 - .func = 3,
53077 - .route_offset = 0x314,
53078 - .route_val = BIT(16 + 9),
53079 - }, {
53080 - /* spi1_miso_m1 */
53081 - .bank_num = 2,
53082 - .pin = 4,
53083 - .func = 2,
53084 - .route_offset = 0x314,
53085 - .route_val = BIT(16 + 9) | BIT(9),
53086 - }, {
53087 - /* owire_m0 */
53088 - .bank_num = 0,
53089 - .pin = 11,
53090 - .func = 3,
53091 - .route_offset = 0x314,
53092 - .route_val = BIT(16 + 10) | BIT(16 + 11),
53093 - }, {
53094 - /* owire_m1 */
53095 - .bank_num = 1,
53096 - .pin = 22,
53097 - .func = 7,
53098 - .route_offset = 0x314,
53099 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
53100 - }, {
53101 - /* owire_m2 */
53102 - .bank_num = 2,
53103 - .pin = 2,
53104 - .func = 5,
53105 - .route_offset = 0x314,
53106 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
53107 - }, {
53108 - /* can_rxd_m0 */
53109 - .bank_num = 0,
53110 - .pin = 11,
53111 - .func = 2,
53112 - .route_offset = 0x314,
53113 - .route_val = BIT(16 + 12) | BIT(16 + 13),
53114 - }, {
53115 - /* can_rxd_m1 */
53116 - .bank_num = 1,
53117 - .pin = 22,
53118 - .func = 5,
53119 - .route_offset = 0x314,
53120 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
53121 - }, {
53122 - /* can_rxd_m2 */
53123 - .bank_num = 2,
53124 - .pin = 2,
53125 - .func = 4,
53126 - .route_offset = 0x314,
53127 - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
53128 - }, {
53129 - /* mac_rxd0_m0 */
53130 - .bank_num = 1,
53131 - .pin = 20,
53132 - .func = 3,
53133 - .route_offset = 0x314,
53134 - .route_val = BIT(16 + 14),
53135 - }, {
53136 - /* mac_rxd0_m1 */
53137 - .bank_num = 4,
53138 - .pin = 2,
53139 - .func = 2,
53140 - .route_offset = 0x314,
53141 - .route_val = BIT(16 + 14) | BIT(14),
53142 - }, {
53143 - /* uart3_rx */
53144 - .bank_num = 3,
53145 - .pin = 12,
53146 - .func = 4,
53147 - .route_offset = 0x314,
53148 - .route_val = BIT(16 + 15),
53149 - }, {
53150 - /* uart3_rx_m1 */
53151 - .bank_num = 0,
53152 - .pin = 17,
53153 - .func = 3,
53154 - .route_offset = 0x314,
53155 - .route_val = BIT(16 + 15) | BIT(15),
53156 - },
53163 + RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */
53164 + RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */
53165 + RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */
53166 + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */
53167 + RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */
53168 + RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */
53169 + RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */
53170 + RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */
53186 - {
53187 - /* uart2dbg_rxm0 */
53188 - .bank_num = 1,
53189 - .pin = 1,
53190 - .func = 2,
53191 - .route_offset = 0x50,
53192 - .route_val = BIT(16) | BIT(16 + 1),
53193 - }, {
53194 - /* uart2dbg_rxm1 */
53195 - .bank_num = 2,
53196 - .pin = 1,
53197 - .func = 1,
53198 - .route_offset = 0x50,
53199 - .route_val = BIT(16) | BIT(16 + 1) | BIT(0),
53200 - }, {
53201 - /* gmac-m1_rxd0 */
53202 - .bank_num = 1,
53203 - .pin = 11,
53204 - .func = 2,
53205 - .route_offset = 0x50,
53206 - .route_val = BIT(16 + 2) | BIT(2),
53207 - }, {
53208 - /* gmac-m1-optimized_rxd3 */
53209 - .bank_num = 1,
53210 - .pin = 14,
53211 - .func = 2,
53212 - .route_offset = 0x50,
53213 - .route_val = BIT(16 + 10) | BIT(10),
53214 - }, {
53215 - /* pdm_sdi0m0 */
53216 - .bank_num = 2,
53217 - .pin = 19,
53218 - .func = 2,
53219 - .route_offset = 0x50,
53220 - .route_val = BIT(16 + 3),
53221 - }, {
53222 - /* pdm_sdi0m1 */
53223 - .bank_num = 1,
53224 - .pin = 23,
53225 - .func = 3,
53226 - .route_offset = 0x50,
53227 - .route_val = BIT(16 + 3) | BIT(3),
53228 - }, {
53229 - /* spi_rxdm2 */
53230 - .bank_num = 3,
53231 - .pin = 2,
53232 - .func = 4,
53233 - .route_offset = 0x50,
53234 - .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5),
53235 - }, {
53236 - /* i2s2_sdim0 */
53237 - .bank_num = 1,
53238 - .pin = 24,
53239 - .func = 1,
53240 - .route_offset = 0x50,
53241 - .route_val = BIT(16 + 6),
53242 - }, {
53243 - /* i2s2_sdim1 */
53244 - .bank_num = 3,
53245 - .pin = 2,
53246 - .func = 6,
53247 - .route_offset = 0x50,
53248 - .route_val = BIT(16 + 6) | BIT(6),
53249 - }, {
53250 - /* card_iom1 */
53251 - .bank_num = 2,
53252 - .pin = 22,
53253 - .func = 3,
53254 - .route_offset = 0x50,
53255 - .route_val = BIT(16 + 7) | BIT(7),
53256 - }, {
53257 - /* tsp_d5m1 */
53258 - .bank_num = 2,
53259 - .pin = 16,
53260 - .func = 3,
53261 - .route_offset = 0x50,
53262 - .route_val = BIT(16 + 8) | BIT(8),
53263 - }, {
53264 - /* cif_data5m1 */
53265 - .bank_num = 2,
53266 - .pin = 16,
53267 - .func = 4,
53268 - .route_offset = 0x50,
53269 - .route_val = BIT(16 + 9) | BIT(9),
53270 - },
53273 + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */
53274 + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */
53286 - {
53287 - /* uart2dbga_rx */
53288 - .bank_num = 4,
53289 - .pin = 8,
53290 - .func = 2,
53291 - .route_offset = 0xe21c,
53292 - .route_val = BIT(16 + 10) | BIT(16 + 11),
53293 - }, {
53294 - /* uart2dbgb_rx */
53295 - .bank_num = 4,
53296 - .pin = 16,
53297 - .func = 2,
53298 - .route_offset = 0xe21c,
53299 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
53300 - }, {
53301 - /* uart2dbgc_rx */
53302 - .bank_num = 4,
53303 - .pin = 19,
53304 - .func = 1,
53305 - .route_offset = 0xe21c,
53306 - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
53307 - }, {
53308 - /* pcie_clkreqn */
53309 - .bank_num = 2,
53310 - .pin = 26,
53311 - .func = 2,
53312 - .route_offset = 0xe21c,
53313 - .route_val = BIT(16 + 14),
53314 - }, {
53315 - /* pcie_clkreqnb */
53316 - .bank_num = 4,
53317 - .pin = 24,
53318 - .func = 1,
53319 - .route_offset = 0xe21c,
53320 - .route_val = BIT(16 + 14) | BIT(14),
53321 - },
53426 @@ -1454,8 +1048,12 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
53427 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
53430 - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53431 - ? info->regmap_pmu : info->regmap_base;
53432 + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53433 + regmap = info->regmap_pmu;
53434 + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
53435 + regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base;
53437 + regmap = info->regmap_base;
53440 mux_type = bank->iomux[iomux_num].type;
53441 @@ -1542,8 +1140,12 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
53442 dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
53443 bank->bank_num, pin, mux);
53445 - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53446 - ? info->regmap_pmu : info->regmap_base;
53447 + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
53448 + regmap = info->regmap_pmu;
53449 + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
53450 + regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base;
53452 + regmap = info->regmap_base;
53455 mux_type = bank->iomux[iomux_num].type;
53456 @@ -1566,6 +1168,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
53457 if (bank->recalced_mask & BIT(pin))
53461 + return -EINVAL;
53463 if (bank->route_mask & BIT(pin)) {
53466 @@ -1587,10 +1192,20 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mu…
53470 - data = (mask << (bit + 16));
53471 - rmask = data | (data >> 16);
53472 - data |= (mux & mask) << bit;
53473 - ret = regmap_update_bits(regmap, reg, rmask, data);
53491 @@ -1775,6 +1390,115 @@ static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
53506 + struct rockchip_pinctrl *info = bank->drvdata;
53509 + if (bank->bank_num == 0) {
53511 + *regmap = info->regmap_base;
53513 + *reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4);
53518 + *regmap = info->regmap_pmu;
53522 + *regmap = info->regmap_base;
53523 + *reg += (bank->bank_num - 1) * RV1126_PULL_BANK_STRIDE;
53541 + struct rockchip_pinctrl *info = bank->drvdata;
53544 + if (bank->bank_num == 0) {
53546 + *regmap = info->regmap_base;
53548 + *reg -= (((31 - pin_num) / RV1126_DRV_PINS_PER_REG + 1) * 4);
53549 + *reg -= 0x4;
53554 + *regmap = info->regmap_pmu;
53557 + *regmap = info->regmap_base;
53559 + *reg += (bank->bank_num - 1) * RV1126_DRV_BANK_STRIDE;
53578 + struct rockchip_pinctrl *info = bank->drvdata;
53581 + if (bank->bank_num == 0) {
53583 + *regmap = info->regmap_base;
53585 + *reg -= (((31 - pin_num) / RV1126_SCHMITT_PINS_PER_GRF_REG + 1) * 4);
53589 + *regmap = info->regmap_pmu;
53593 + *regmap = info->regmap_base;
53596 + *reg += (bank->bank_num - 1) * RV1126_SCHMITT_BANK_STRIDE;
53607 @@ -1795,6 +1519,111 @@ static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
53621 + struct rockchip_pinctrl *info = bank->drvdata;
53623 + if (bank->bank_num == 0) {
53624 + *regmap = info->regmap_pmu;
53628 + *regmap = info->regmap_base;
53629 + *reg += (bank->bank_num - 1) * RK1808_PULL_BANK_STRIDE;
53648 + struct rockchip_pinctrl *info = bank->drvdata;
53650 + if (bank->bank_num == 0) {
53651 + *regmap = info->regmap_pmu;
53654 + *regmap = info->regmap_base;
53656 + *reg += (bank->bank_num - 1) * RK1808_DRV_BANK_STRIDE;
53674 + struct rockchip_pinctrl *info = bank->drvdata;
53676 + if (bank->bank_num == 0) {
53677 + *regmap = info->regmap_pmu;
53680 + *regmap = info->regmap_base;
53682 + *reg += (bank->bank_num - 1) * RK1808_SR_BANK_STRIDE;
53700 + struct rockchip_pinctrl *info = bank->drvdata;
53702 + if (bank->bank_num == 0) {
53703 + *regmap = info->regmap_pmu;
53706 + *regmap = info->regmap_base;
53708 + *reg += (bank->bank_num - 1) * RK1808_SCHMITT_BANK_STRIDE;
53719 @@ -2117,6 +1946,100 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
53733 + struct rockchip_pinctrl *info = bank->drvdata;
53735 + if (bank->bank_num == 0) {
53736 + *regmap = info->regmap_pmu;
53739 + *regmap = info->regmap_base;
53741 + *reg += (bank->bank_num - 1) * RK3568_SR_BANK_STRIDE;
53759 + struct rockchip_pinctrl *info = bank->drvdata;
53761 + if (bank->bank_num == 0) {
53762 + *regmap = info->regmap_pmu;
53764 + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
53770 + *regmap = info->regmap_base;
53772 + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
53790 + struct rockchip_pinctrl *info = bank->drvdata;
53793 + if (bank->bank_num == 0) {
53794 + *regmap = info->regmap_pmu;
53801 + *regmap = info->regmap_base;
53803 + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
53811 + if ((bank->bank_num == 1 && (pin_num == 15 || pin_num == 23 || pin_num == 31)) ||
53812 + ((bank->bank_num == 2 || bank->bank_num == 3 || bank->bank_num == 4) &&
53814 + *bit -= RK3568_DRV_BITS_PER_PIN;
53818 { 2, 4, 8, 12, -1, -1, -1, -1 },
53819 { 3, 6, 9, 12, -1, -1, -1, -1 },
53820 @@ -2217,6 +2140,15 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
53821 bank->bank_num, pin_num, strength);
53823 ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
53824 + if (ctrl->type == RV1126) {
53828 + } else if (ctrl->type == RK3568) {
53830 + ret = (1 << (strength + 1)) - 1;
53834 ret = -EINVAL;
53836 @@ -2286,14 +2218,42 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
53837 return -EINVAL;
53842 data = ((1 << rmask_bits) - 1) << (bit + 16);
53850 - return ret;
53851 + if (ctrl->type == RK3568 && rockchip_get_cpu_version() == 0) {
53852 + if (bank->bank_num == 1 && pin_num == 21)
53854 + else if (bank->bank_num == 2 && pin_num == 2)
53856 + else if (bank->bank_num == 2 && pin_num == 8)
53858 + else if (bank->bank_num == 3 && pin_num == 0)
53860 + else if (bank->bank_num == 3 && pin_num == 6)
53862 + else if (bank->bank_num == 4 && pin_num == 0)
53867 + data = ((1 << rmask_bits) - 1) << 16;
53869 + data |= (1 << (strength + 1)) - 1;
53880 @@ -2338,11 +2298,14 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
53892 pull_type = bank->pull_type[pin_num / 8];
53894 data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
53895 @@ -2383,11 +2346,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
53907 pull_type = bank->pull_type[pin_num / 8];
53908 ret = -EINVAL;
53910 @@ -2397,6 +2363,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
53915 + * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6,
53918 + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
53924 dev_err(info->dev, "unsupported pull setting %d\n",
53925 @@ -2441,6 +2415,35 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
53940 + struct rockchip_pinctrl *info = bank->drvdata;
53942 + if (bank->bank_num == 0) {
53943 + *regmap = info->regmap_pmu;
53946 + *regmap = info->regmap_base;
53948 + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
53960 struct rockchip_pinctrl *info = bank->drvdata;
53961 @@ -2459,10 +2462,17 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
53965 - return data & 0x1;
53966 -}
53967 -
53968 -static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
53969 + switch (ctrl->type) {
53971 + return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1);
53982 struct rockchip_pinctrl *info = bank->drvdata;
53983 @@ -2480,7 +2490,91 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
53987 - data = BIT(bit + 16) | (enable << bit);
53988 + switch (ctrl->type) {
53990 + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
54014 + struct rockchip_pinctrl *info = bank->drvdata;
54017 + if (bank->bank_num == 0) {
54018 + *regmap = info->regmap_pmu;
54022 + *regmap = info->regmap_base;
54025 + *reg += (bank->bank_num - 1) * PX30_SLEW_RATE_BANK_STRIDE;
54035 + struct rockchip_pinctrl *info = bank->drvdata;
54036 + struct rockchip_pin_ctrl *ctrl = info->ctrl;
54042 + ret = ctrl->slew_rate_calc_reg(bank, pin_num, &regmap, &reg, &bit);
54057 + struct rockchip_pinctrl *info = bank->drvdata;
54058 + struct rockchip_pin_ctrl *ctrl = info->ctrl;
54064 + dev_dbg(info->dev, "setting slew rate of GPIO%d-%d to %d\n",
54065 + bank->bank_num, pin_num, speed);
54067 + ret = ctrl->slew_rate_calc_reg(bank, pin_num, &regmap, &reg, &bit);
54076 @@ -2541,9 +2635,9 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
54080 - if (ret) {
54083 - for (cnt--; cnt >= 0; cnt--)
54084 + for (cnt--; cnt >= 0 && !data[cnt].func; cnt--)
54085 rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
54088 @@ -2552,86 +2646,11 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
54092 -static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
54093 -{
54094 - struct rockchip_pin_bank *bank = gpiochip_get_data(chip);
54095 - u32 data;
54096 - int ret;
54097 -
54098 - ret = clk_enable(bank->clk);
54099 - if (ret < 0) {
54100 - dev_err(bank->drvdata->dev,
54101 - "failed to enable clock for bank %s\n", bank->name);
54102 - return ret;
54103 - }
54104 - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
54105 - clk_disable(bank->clk);
54106 -
54107 - if (data & BIT(offset))
54108 - return GPIO_LINE_DIRECTION_OUT;
54109 -
54110 - return GPIO_LINE_DIRECTION_IN;
54111 -}
54112 -
54113 -/*
54114 - * The calls to gpio_direction_output() and gpio_direction_input()
54115 - * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
54116 - * function called from the gpiolib interface).
54117 - */
54118 -static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
54119 - int pin, bool input)
54120 -{
54121 - struct rockchip_pin_bank *bank;
54122 - int ret;
54123 - unsigned long flags;
54124 - u32 data;
54125 -
54126 - bank = gpiochip_get_data(chip);
54127 -
54128 - ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
54129 - if (ret < 0)
54130 - return ret;
54131 -
54132 - clk_enable(bank->clk);
54133 - raw_spin_lock_irqsave(&bank->slock, flags);
54134 -
54135 - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
54136 - /* set bit to 1 for output, 0 for input */
54137 - if (!input)
54138 - data |= BIT(pin);
54139 - else
54140 - data &= ~BIT(pin);
54141 - writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
54142 -
54143 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54144 - clk_disable(bank->clk);
54145 -
54146 - return 0;
54147 -}
54148 -
54149 -static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
54150 - struct pinctrl_gpio_range *range,
54151 - unsigned offset, bool input)
54152 -{
54153 - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
54154 - struct gpio_chip *chip;
54155 - int pin;
54156 -
54157 - chip = range->gc;
54158 - pin = offset - chip->base;
54159 - dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
54160 - offset, range->name, pin, input ? "input" : "output");
54161 -
54162 - return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base,
54163 - input);
54164 -}
54165 -
54171 - .gpio_set_direction = rockchip_pmx_gpio_set_direction,
54175 @@ -2650,26 +2669,27 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
54193 -static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
54194 -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset);
54195 -
54202 + struct gpio_chip *gpio = &bank->gpio_chip;
54206 @@ -2702,10 +2722,13 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int p…
54210 - rockchip_gpio_set(&bank->gpio_chip,
54211 - pin - bank->pin_base, arg);
54212 - rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip,
54213 - pin - bank->pin_base, false);
54214 + rc = rockchip_get_mux(bank, pin - bank->pin_base);
54216 + dev_err(info->dev, "pin-%d has been mux to func%d\n", pin, rc);
54217 + return -EINVAL;
54220 + rc = gpio->direction_output(gpio, pin - bank->pin_base, arg);
54224 @@ -2728,9 +2751,17 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pi…
54229 + if (!info->ctrl->slew_rate_calc_reg)
54230 + return -ENOTSUPP;
54233 + pin - bank->pin_base, arg);
54238 return -ENOTSUPP;
54239 - break;
54243 @@ -2743,6 +2774,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
54247 + struct gpio_chip *gpio = &bank->gpio_chip;
54251 @@ -2768,10 +2800,12 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int p…
54254 rc = rockchip_get_mux(bank, pin - bank->pin_base);
54255 - if (rc != RK_FUNC_GPIO)
54257 + dev_err(info->dev, "pin-%d has been mux to func%d\n", pin, rc);
54258 return -EINVAL;
54261 - rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base);
54262 + rc = gpio->get(gpio, pin - bank->pin_base);
54266 @@ -2796,11 +2830,20 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int p…
54273 + if (!info->ctrl->slew_rate_calc_reg)
54274 + return -ENOTSUPP;
54276 + rc = rockchip_get_slew_rate(bank, pin - bank->pin_base);
54283 return -ENOTSUPP;
54284 - break;
54288 @@ -2863,716 +2906,173 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
54289 return -EINVAL;
54292 - grp->npins = size / 4;
54293 -
54294 - grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int),
54295 - GFP_KERNEL);
54296 - grp->data = devm_kcalloc(info->dev,
54297 - grp->npins,
54298 - sizeof(struct rockchip_pin_config),
54299 - GFP_KERNEL);
54300 - if (!grp->pins || !grp->data)
54301 - return -ENOMEM;
54302 -
54303 - for (i = 0, j = 0; i < size; i += 4, j++) {
54304 - const __be32 *phandle;
54305 - struct device_node *np_config;
54306 -
54307 - num = be32_to_cpu(*list++);
54308 - bank = bank_num_to_bank(info, num);
54309 - if (IS_ERR(bank))
54310 - return PTR_ERR(bank);
54311 -
54312 - grp->pins[j] = bank->pin_base + be32_to_cpu(*list++);
54313 - grp->data[j].func = be32_to_cpu(*list++);
54314 -
54315 - phandle = list++;
54316 - if (!phandle)
54317 - return -EINVAL;
54318 -
54319 - np_config = of_find_node_by_phandle(be32_to_cpup(phandle));
54320 - ret = pinconf_generic_parse_dt_config(np_config, NULL,
54321 - &grp->data[j].configs, &grp->data[j].nconfigs);
54322 - if (ret)
54323 - return ret;
54324 - }
54325 -
54326 - return 0;
54327 -}
54328 -
54329 -static int rockchip_pinctrl_parse_functions(struct device_node *np,
54330 - struct rockchip_pinctrl *info,
54331 - u32 index)
54332 -{
54333 - struct device_node *child;
54334 - struct rockchip_pmx_func *func;
54335 - struct rockchip_pin_group *grp;
54336 - int ret;
54337 - static u32 grp_index;
54338 - u32 i = 0;
54339 -
54340 - dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
54341 -
54342 - func = &info->functions[index];
54343 -
54344 - /* Initialise function */
54345 - func->name = np->name;
54346 - func->ngroups = of_get_child_count(np);
54347 - if (func->ngroups <= 0)
54348 - return 0;
54349 -
54350 - func->groups = devm_kcalloc(info->dev,
54351 - func->ngroups, sizeof(char *), GFP_KERNEL);
54352 - if (!func->groups)
54353 - return -ENOMEM;
54354 -
54355 - for_each_child_of_node(np, child) {
54356 - func->groups[i] = child->name;
54357 - grp = &info->groups[grp_index++];
54358 - ret = rockchip_pinctrl_parse_groups(child, grp, info, i++);
54359 - if (ret) {
54360 - of_node_put(child);
54361 - return ret;
54362 - }
54363 - }
54364 -
54365 - return 0;
54366 -}
54367 -
54368 -static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
54369 - struct rockchip_pinctrl *info)
54370 -{
54371 - struct device *dev = &pdev->dev;
54372 - struct device_node *np = dev->of_node;
54373 - struct device_node *child;
54374 - int ret;
54375 - int i;
54376 -
54377 - rockchip_pinctrl_child_count(info, np);
54378 -
54379 - dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
54380 - dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
54381 -
54382 - info->functions = devm_kcalloc(dev,
54383 - info->nfunctions,
54384 - sizeof(struct rockchip_pmx_func),
54385 - GFP_KERNEL);
54386 - if (!info->functions)
54387 - return -ENOMEM;
54388 -
54389 - info->groups = devm_kcalloc(dev,
54390 - info->ngroups,
54391 - sizeof(struct rockchip_pin_group),
54392 - GFP_KERNEL);
54393 - if (!info->groups)
54394 - return -ENOMEM;
54395 -
54396 - i = 0;
54397 -
54398 - for_each_child_of_node(np, child) {
54399 - if (of_match_node(rockchip_bank_match, child))
54400 - continue;
54401 -
54402 - ret = rockchip_pinctrl_parse_functions(child, info, i++);
54403 - if (ret) {
54404 - dev_err(&pdev->dev, "failed to parse function\n");
54405 - of_node_put(child);
54406 - return ret;
54407 - }
54408 - }
54409 -
54410 - return 0;
54411 -}
54412 -
54413 -static int rockchip_pinctrl_register(struct platform_device *pdev,
54414 - struct rockchip_pinctrl *info)
54415 -{
54416 - struct pinctrl_desc *ctrldesc = &info->pctl;
54417 - struct pinctrl_pin_desc *pindesc, *pdesc;
54418 - struct rockchip_pin_bank *pin_bank;
54419 - int pin, bank, ret;
54420 - int k;
54421 -
54422 - ctrldesc->name = "rockchip-pinctrl";
54423 - ctrldesc->owner = THIS_MODULE;
54424 - ctrldesc->pctlops = &rockchip_pctrl_ops;
54425 - ctrldesc->pmxops = &rockchip_pmx_ops;
54426 - ctrldesc->confops = &rockchip_pinconf_ops;
54427 -
54428 - pindesc = devm_kcalloc(&pdev->dev,
54429 - info->ctrl->nr_pins, sizeof(*pindesc),
54430 - GFP_KERNEL);
54431 - if (!pindesc)
54432 - return -ENOMEM;
54433 -
54434 - ctrldesc->pins = pindesc;
54435 - ctrldesc->npins = info->ctrl->nr_pins;
54436 -
54437 - pdesc = pindesc;
54438 - for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) {
54439 - pin_bank = &info->ctrl->pin_banks[bank];
54440 - for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) {
54441 - pdesc->number = k;
54442 - pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
54443 - pin_bank->name, pin);
54444 - pdesc++;
54445 - }
54446 - }
54447 -
54448 - ret = rockchip_pinctrl_parse_dt(pdev, info);
54449 - if (ret)
54450 - return ret;
54451 -
54452 - info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
54453 - if (IS_ERR(info->pctl_dev)) {
54454 - dev_err(&pdev->dev, "could not register pinctrl driver\n");
54455 - return PTR_ERR(info->pctl_dev);
54456 - }
54457 -
54458 - for (bank = 0; bank < info->ctrl->nr_banks; ++bank) {
54459 - pin_bank = &info->ctrl->pin_banks[bank];
54460 - pin_bank->grange.name = pin_bank->name;
54461 - pin_bank->grange.id = bank;
54462 - pin_bank->grange.pin_base = pin_bank->pin_base;
54463 - pin_bank->grange.base = pin_bank->gpio_chip.base;
54464 - pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
54465 - pin_bank->grange.gc = &pin_bank->gpio_chip;
54466 - pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange);
54467 - }
54468 -
54469 - return 0;
54470 -}
54471 -
54472 -/*
54473 - * GPIO handling
54474 - */
54475 -
54476 -static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
54477 -{
54478 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54479 - void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR;
54480 - unsigned long flags;
54481 - u32 data;
54482 -
54483 - clk_enable(bank->clk);
54484 - raw_spin_lock_irqsave(&bank->slock, flags);
54485 -
54486 - data = readl(reg);
54487 - data &= ~BIT(offset);
54488 - if (value)
54489 - data |= BIT(offset);
54490 - writel(data, reg);
54491 -
54492 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54493 - clk_disable(bank->clk);
54494 -}
54495 -
54496 -/*
54497 - * Returns the level of the pin for input direction and setting of the DR
54498 - * register for output gpios.
54499 - */
54500 -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset)
54501 -{
54502 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54503 - u32 data;
54504 -
54505 - clk_enable(bank->clk);
54506 - data = readl(bank->reg_base + GPIO_EXT_PORT);
54507 - clk_disable(bank->clk);
54508 - data >>= offset;
54509 - data &= 1;
54510 - return data;
54511 -}
54512 -
54513 -/*
54514 - * gpiolib gpio_direction_input callback function. The setting of the pin
54515 - * mux function as 'gpio input' will be handled by the pinctrl subsystem
54516 - * interface.
54517 - */
54518 -static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
54519 -{
54520 - return pinctrl_gpio_direction_input(gc->base + offset);
54521 -}
54522 -
54523 -/*
54524 - * gpiolib gpio_direction_output callback function. The setting of the pin
54525 - * mux function as 'gpio output' will be handled by the pinctrl subsystem
54526 - * interface.
54527 - */
54528 -static int rockchip_gpio_direction_output(struct gpio_chip *gc,
54529 - unsigned offset, int value)
54530 -{
54531 - rockchip_gpio_set(gc, offset, value);
54532 - return pinctrl_gpio_direction_output(gc->base + offset);
54533 -}
54534 -
54535 -static void rockchip_gpio_set_debounce(struct gpio_chip *gc,
54536 - unsigned int offset, bool enable)
54537 -{
54538 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54539 - void __iomem *reg = bank->reg_base + GPIO_DEBOUNCE;
54540 - unsigned long flags;
54541 - u32 data;
54542 -
54543 - clk_enable(bank->clk);
54544 - raw_spin_lock_irqsave(&bank->slock, flags);
54545 -
54546 - data = readl(reg);
54547 - if (enable)
54548 - data |= BIT(offset);
54549 - else
54550 - data &= ~BIT(offset);
54551 - writel(data, reg);
54552 -
54553 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54554 - clk_disable(bank->clk);
54555 -}
54556 -
54557 -/*
54558 - * gpiolib set_config callback function. The setting of the pin
54559 - * mux function as 'gpio output' will be handled by the pinctrl subsystem
54560 - * interface.
54561 - */
54562 -static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
54563 - unsigned long config)
54564 -{
54565 - enum pin_config_param param = pinconf_to_config_param(config);
54566 -
54567 - switch (param) {
54568 - case PIN_CONFIG_INPUT_DEBOUNCE:
54569 - rockchip_gpio_set_debounce(gc, offset, true);
54570 - /*
54571 - * Rockchip's gpio could only support up to one period
54572 - * of the debounce clock(pclk), which is far away from
54573 - * satisftying the requirement, as pclk is usually near
54574 - * 100MHz shared by all peripherals. So the fact is it
54575 - * has crippled debounce capability could only be useful
54576 - * to prevent any spurious glitches from waking up the system
54577 - * if the gpio is conguired as wakeup interrupt source. Let's
54578 - * still return -ENOTSUPP as before, to make sure the caller
54579 - * of gpiod_set_debounce won't change its behaviour.
54580 - */
54581 - return -ENOTSUPP;
54582 - default:
54583 - return -ENOTSUPP;
54584 - }
54585 -}
54586 -
54587 -/*
54588 - * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
54589 - * and a virtual IRQ, if not already present.
54590 - */
54591 -static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
54592 -{
54593 - struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
54594 - unsigned int virq;
54595 -
54596 - if (!bank->domain)
54597 - return -ENXIO;
54598 -
54599 - clk_enable(bank->clk);
54600 - virq = irq_create_mapping(bank->domain, offset);
54601 - clk_disable(bank->clk);
54602 -
54603 - return (virq) ? : -ENXIO;
54604 -}
54605 -
54606 -static const struct gpio_chip rockchip_gpiolib_chip = {
54607 - .request = gpiochip_generic_request,
54608 - .free = gpiochip_generic_free,
54609 - .set = rockchip_gpio_set,
54610 - .get = rockchip_gpio_get,
54611 - .get_direction = rockchip_gpio_get_direction,
54612 - .direction_input = rockchip_gpio_direction_input,
54613 - .direction_output = rockchip_gpio_direction_output,
54614 - .set_config = rockchip_gpio_set_config,
54615 - .to_irq = rockchip_gpio_to_irq,
54616 - .owner = THIS_MODULE,
54617 -};
54618 -
54619 -/*
54620 - * Interrupt handling
54621 - */
54622 -
54623 -static void rockchip_irq_demux(struct irq_desc *desc)
54624 -{
54625 - struct irq_chip *chip = irq_desc_get_chip(desc);
54626 - struct rockchip_pin_bank *bank = irq_desc_get_handler_data(desc);
54627 - u32 pend;
54628 -
54629 - dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);
54630 -
54631 - chained_irq_enter(chip, desc);
54632 -
54633 - pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS);
54634 -
54635 - while (pend) {
54636 - unsigned int irq, virq;
54637 -
54638 - irq = __ffs(pend);
54639 - pend &= ~BIT(irq);
54640 - virq = irq_find_mapping(bank->domain, irq);
54641 -
54642 - if (!virq) {
54643 - dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq);
54644 - continue;
54645 - }
54646 -
54647 - dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq);
54648 -
54649 - /*
54650 - * Triggering IRQ on both rising and falling edge
54651 - * needs manual intervention.
54652 - */
54653 - if (bank->toggle_edge_mode & BIT(irq)) {
54654 - u32 data, data_old, polarity;
54655 - unsigned long flags;
54656 -
54657 - data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
54658 - do {
54659 - raw_spin_lock_irqsave(&bank->slock, flags);
54660 -
54661 - polarity = readl_relaxed(bank->reg_base +
54662 - GPIO_INT_POLARITY);
54663 - if (data & BIT(irq))
54664 - polarity &= ~BIT(irq);
54665 - else
54666 - polarity |= BIT(irq);
54667 - writel(polarity,
54668 - bank->reg_base + GPIO_INT_POLARITY);
54669 -
54670 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54671 -
54672 - data_old = data;
54673 - data = readl_relaxed(bank->reg_base +
54674 - GPIO_EXT_PORT);
54675 - } while ((data & BIT(irq)) != (data_old & BIT(irq)));
54676 - }
54677 -
54678 - generic_handle_irq(virq);
54679 - }
54680 -
54681 - chained_irq_exit(chip, desc);
54682 -}
54683 -
54684 -static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
54685 -{
54686 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
54687 - struct rockchip_pin_bank *bank = gc->private;
54688 - u32 mask = BIT(d->hwirq);
54689 - u32 polarity;
54690 - u32 level;
54691 - u32 data;
54692 - unsigned long flags;
54693 - int ret;
54694 -
54695 - /* make sure the pin is configured as gpio input */
54696 - ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
54697 - if (ret < 0)
54698 - return ret;
54699 -
54700 - clk_enable(bank->clk);
54701 - raw_spin_lock_irqsave(&bank->slock, flags);
54702 -
54703 - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
54704 - data &= ~mask;
54705 - writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
54706 -
54707 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54708 -
54709 - if (type & IRQ_TYPE_EDGE_BOTH)
54710 - irq_set_handler_locked(d, handle_edge_irq);
54711 - else
54712 - irq_set_handler_locked(d, handle_level_irq);
54713 -
54714 - raw_spin_lock_irqsave(&bank->slock, flags);
54715 - irq_gc_lock(gc);
54716 -
54717 - level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
54718 - polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY);
54719 -
54720 - switch (type) {
54721 - case IRQ_TYPE_EDGE_BOTH:
54722 - bank->toggle_edge_mode |= mask;
54723 - level |= mask;
54724 -
54725 - /*
54726 - * Determine gpio state. If 1 next interrupt should be falling
54727 - * otherwise rising.
54728 - */
54729 - data = readl(bank->reg_base + GPIO_EXT_PORT);
54730 - if (data & mask)
54731 - polarity &= ~mask;
54732 - else
54733 - polarity |= mask;
54734 - break;
54735 - case IRQ_TYPE_EDGE_RISING:
54736 - bank->toggle_edge_mode &= ~mask;
54737 - level |= mask;
54738 - polarity |= mask;
54739 - break;
54740 - case IRQ_TYPE_EDGE_FALLING:
54741 - bank->toggle_edge_mode &= ~mask;
54742 - level |= mask;
54743 - polarity &= ~mask;
54744 - break;
54745 - case IRQ_TYPE_LEVEL_HIGH:
54746 - bank->toggle_edge_mode &= ~mask;
54747 - level &= ~mask;
54748 - polarity |= mask;
54749 - break;
54750 - case IRQ_TYPE_LEVEL_LOW:
54751 - bank->toggle_edge_mode &= ~mask;
54752 - level &= ~mask;
54753 - polarity &= ~mask;
54754 - break;
54755 - default:
54756 - irq_gc_unlock(gc);
54757 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54758 - clk_disable(bank->clk);
54759 - return -EINVAL;
54760 - }
54761 -
54762 - writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL);
54763 - writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
54764 -
54765 - irq_gc_unlock(gc);
54766 - raw_spin_unlock_irqrestore(&bank->slock, flags);
54767 - clk_disable(bank->clk);
54768 -
54769 - return 0;
54770 -}
54771 -
54772 -static void rockchip_irq_suspend(struct irq_data *d)
54773 -{
54774 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
54775 - struct rockchip_pin_bank *bank = gc->private;
54776 + grp->npins = size / 4;
54778 - clk_enable(bank->clk);
54779 - bank->saved_masks = irq_reg_readl(gc, GPIO_INTMASK);
54780 - irq_reg_writel(gc, ~gc->wake_active, GPIO_INTMASK);
54781 - clk_disable(bank->clk);
54782 -}
54783 + grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int),
54785 + grp->data = devm_kcalloc(info->dev,
54786 + grp->npins,
54789 + if (!grp->pins || !grp->data)
54790 + return -ENOMEM;
54792 -static void rockchip_irq_resume(struct irq_data *d)
54793 -{
54794 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
54795 - struct rockchip_pin_bank *bank = gc->private;
54800 - clk_enable(bank->clk);
54801 - irq_reg_writel(gc, bank->saved_masks, GPIO_INTMASK);
54802 - clk_disable(bank->clk);
54803 -}
54809 -static void rockchip_irq_enable(struct irq_data *d)
54810 -{
54811 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
54812 - struct rockchip_pin_bank *bank = gc->private;
54813 + grp->pins[j] = bank->pin_base + be32_to_cpu(*list++);
54814 + grp->data[j].func = be32_to_cpu(*list++);
54816 - clk_enable(bank->clk);
54817 - irq_gc_mask_clr_bit(d);
54818 -}
54821 + return -EINVAL;
54823 -static void rockchip_irq_disable(struct irq_data *d)
54824 -{
54825 - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
54826 - struct rockchip_pin_bank *bank = gc->private;
54829 + &grp->data[j].configs, &grp->data[j].nconfigs);
54834 - irq_gc_mask_set_bit(d);
54835 - clk_disable(bank->clk);
54839 -static int rockchip_interrupts_register(struct platform_device *pdev,
54840 - struct rockchip_pinctrl *info)
54845 - struct rockchip_pin_ctrl *ctrl = info->ctrl;
54846 - struct rockchip_pin_bank *bank = ctrl->pin_banks;
54847 - unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
54848 - struct irq_chip_generic *gc;
54853 - int i;
54857 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
54858 - if (!bank->valid) {
54859 - dev_warn(&pdev->dev, "bank %s is not valid\n",
54860 - bank->name);
54861 - continue;
54862 - }
54863 + dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
54865 - ret = clk_enable(bank->clk);
54866 - if (ret) {
54867 - dev_err(&pdev->dev, "failed to enable clock for bank %s\n",
54868 - bank->name);
54869 - continue;
54870 - }
54871 + func = &info->functions[index];
54873 - bank->domain = irq_domain_add_linear(bank->of_node, 32,
54874 - &irq_generic_chip_ops, NULL);
54875 - if (!bank->domain) {
54876 - dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n",
54877 - bank->name);
54878 - clk_disable(bank->clk);
54879 - continue;
54880 - }
54882 + func->name = np->name;
54883 + func->ngroups = of_get_child_count(np);
54884 + if (func->ngroups <= 0)
54887 + func->groups = devm_kcalloc(info->dev,
54888 + func->ngroups, sizeof(char *), GFP_KERNEL);
54889 + if (!func->groups)
54890 + return -ENOMEM;
54892 - ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1,
54893 - "rockchip_gpio_irq", handle_level_irq,
54894 - clr, 0, 0);
54896 + func->groups[i] = child->name;
54897 + grp = &info->groups[grp_index++];
54900 - dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n",
54901 - bank->name);
54902 - irq_domain_remove(bank->domain);
54903 - clk_disable(bank->clk);
54904 - continue;
54908 -
54909 - gc = irq_get_domain_generic_chip(bank->domain, 0);
54910 - gc->reg_base = bank->reg_base;
54911 - gc->private = bank;
54912 - gc->chip_types[0].regs.mask = GPIO_INTMASK;
54913 - gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;
54914 - gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
54915 - gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
54916 - gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
54917 - gc->chip_types[0].chip.irq_enable = rockchip_irq_enable;
54918 - gc->chip_types[0].chip.irq_disable = rockchip_irq_disable;
54919 - gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
54920 - gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
54921 - gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
54922 - gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
54923 - gc->wake_enabled = IRQ_MSK(bank->nr_pins);
54924 -
54925 - /*
54926 - * Linux assumes that all interrupts start out disabled/masked.
54927 - * Our driver only uses the concept of masked and always keeps
54928 - * things enabled, so for us that's all masked and all enabled.
54929 - */
54930 - writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTMASK);
54931 - writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTEN);
54932 - gc->mask_cache = 0xffffffff;
54933 -
54934 - irq_set_chained_handler_and_data(bank->irq,
54935 - rockchip_irq_demux, bank);
54936 - clk_disable(bank->clk);
54942 -static int rockchip_gpiolib_register(struct platform_device *pdev,
54943 - struct rockchip_pinctrl *info)
54947 - struct rockchip_pin_ctrl *ctrl = info->ctrl;
54948 - struct rockchip_pin_bank *bank = ctrl->pin_banks;
54949 - struct gpio_chip *gc;
54950 + struct device *dev = &pdev->dev;
54951 + struct device_node *np = dev->of_node;
54956 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
54957 - if (!bank->valid) {
54958 - dev_warn(&pdev->dev, "bank %s is not valid\n",
54959 - bank->name);
54960 - continue;
54961 - }
54962 -
54963 - bank->gpio_chip = rockchip_gpiolib_chip;
54966 - gc = &bank->gpio_chip;
54967 - gc->base = bank->pin_base;
54968 - gc->ngpio = bank->nr_pins;
54969 - gc->parent = &pdev->dev;
54970 - gc->of_node = bank->of_node;
54971 - gc->label = bank->name;
54972 + dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
54973 + dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
54975 - ret = gpiochip_add_data(gc, bank);
54976 - if (ret) {
54977 - dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
54978 - gc->label, ret);
54979 - goto fail;
54980 - }
54981 - }
54982 + info->functions = devm_kcalloc(dev,
54983 + info->nfunctions,
54986 + if (!info->functions)
54987 + return -ENOMEM;
54989 - rockchip_interrupts_register(pdev, info);
54990 + info->groups = devm_kcalloc(dev,
54991 + info->ngroups,
54994 + if (!info->groups)
54995 + return -ENOMEM;
54997 - return 0;
55000 -fail:
55001 - for (--i, --bank; i >= 0; --i, --bank) {
55002 - if (!bank->valid)
55006 - gpiochip_remove(&bank->gpio_chip);
55007 - }
55008 - return ret;
55009 -}
55010 -
55011 -static int rockchip_gpiolib_unregister(struct platform_device *pdev,
55012 - struct rockchip_pinctrl *info)
55013 -{
55014 - struct rockchip_pin_ctrl *ctrl = info->ctrl;
55015 - struct rockchip_pin_bank *bank = ctrl->pin_banks;
55016 - int i;
55018 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
55019 - if (!bank->valid)
55020 - continue;
55021 - gpiochip_remove(&bank->gpio_chip);
55024 + dev_err(&pdev->dev, "failed to parse function\n");
55033 -static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
55034 - struct rockchip_pinctrl *info)
55038 - struct resource res;
55039 - void __iomem *base;
55040 + struct pinctrl_desc *ctrldesc = &info->pctl;
55046 - if (of_address_to_resource(bank->of_node, 0, &res)) {
55047 - dev_err(info->dev, "cannot find IO resource for bank\n");
55048 - return -ENOENT;
55049 - }
55050 + ctrldesc->name = "rockchip-pinctrl";
55051 + ctrldesc->owner = THIS_MODULE;
55052 + ctrldesc->pctlops = &rockchip_pctrl_ops;
55053 + ctrldesc->pmxops = &rockchip_pmx_ops;
55054 + ctrldesc->confops = &rockchip_pinconf_ops;
55056 - bank->reg_base = devm_ioremap_resource(info->dev, &res);
55057 - if (IS_ERR(bank->reg_base))
55058 - return PTR_ERR(bank->reg_base);
55059 + pindesc = devm_kcalloc(&pdev->dev,
55060 + info->ctrl->nr_pins, sizeof(*pindesc),
55063 + return -ENOMEM;
55065 - /*
55066 - * special case, where parts of the pull setting-registers are
55067 - * part of the PMU register space
55068 - */
55069 - if (of_device_is_compatible(bank->of_node,
55070 - "rockchip,rk3188-gpio-bank0")) {
55071 - struct device_node *node;
55072 -
55073 - node = of_parse_phandle(bank->of_node->parent,
55074 - "rockchip,pmu", 0);
55075 - if (!node) {
55076 - if (of_address_to_resource(bank->of_node, 1, &res)) {
55077 - dev_err(info->dev, "cannot find IO resource for bank\n");
55078 - return -ENOENT;
55079 - }
55080 + ctrldesc->pins = pindesc;
55081 + ctrldesc->npins = info->ctrl->nr_pins;
55083 - base = devm_ioremap_resource(info->dev, &res);
55084 - if (IS_ERR(base))
55085 - return PTR_ERR(base);
55086 - rockchip_regmap_config.max_register =
55087 - resource_size(&res) - 4;
55088 - rockchip_regmap_config.name =
55089 - "rockchip,rk3188-gpio-bank0-pull";
55090 - bank->regmap_pull = devm_regmap_init_mmio(info->dev,
55091 - base,
55092 - &rockchip_regmap_config);
55094 + for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) {
55095 + pin_bank = &info->ctrl->pin_banks[bank];
55096 + for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) {
55097 + pdesc->number = k;
55098 + pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
55099 + pin_bank->name, pin);
55102 - of_node_put(node);
55105 - bank->irq = irq_of_parse_and_map(bank->of_node, 0);
55110 - bank->clk = of_clk_get(bank->of_node, 0);
55111 - if (IS_ERR(bank->clk))
55112 - return PTR_ERR(bank->clk);
55113 + info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
55114 + if (IS_ERR(info->pctl_dev)) {
55115 + dev_err(&pdev->dev, "could not register pinctrl driver\n");
55116 + return PTR_ERR(info->pctl_dev);
55119 - return clk_prepare(bank->clk);
55124 @@ -3584,7 +3084,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55127 struct device_node *node = pdev->dev.of_node;
55128 - struct device_node *np;
55132 @@ -3592,23 +3091,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55134 ctrl = (struct rockchip_pin_ctrl *)match->data;
55136 - for_each_child_of_node(node, np) {
55137 - if (!of_find_property(np, "gpio-controller", NULL))
55138 - continue;
55139 -
55140 - bank = ctrl->pin_banks;
55141 - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
55142 - if (!strcmp(bank->name, np->name)) {
55143 - bank->of_node = np;
55144 -
55145 - if (!rockchip_get_bank_data(bank, d))
55146 - bank->valid = true;
55147 -
55148 - break;
55149 - }
55150 - }
55151 - }
55152 -
55153 grf_offs = ctrl->grf_mux_offset;
55154 pmu_offs = ctrl->pmu_mux_offset;
55155 drv_pmu_offs = ctrl->pmu_drv_offset;
55156 @@ -3633,12 +3115,13 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55159 if (iom->offset >= 0) {
55160 - if (iom->type & IOMUX_SOURCE_PMU)
55161 + if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
55162 pmu_offs = iom->offset;
55164 grf_offs = iom->offset;
55166 - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
55167 + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
55168 + (iom->type & IOMUX_L_SOURCE_PMU)) ?
55172 @@ -3663,7 +3146,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
55173 inc = (iom->type & (IOMUX_WIDTH_4BIT |
55176 - if (iom->type & IOMUX_SOURCE_PMU)
55177 + if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
55181 @@ -3758,6 +3241,46 @@ static int __maybe_unused rockchip_pinctrl_resume(struct device *dev)
55209 + ret = regmap_write(info->regmap_base, RK3308_GRF_SOC_CON13,
55216 + ret = regmap_write(info->regmap_base, RK3308_GRF_SOC_CON15,
55228 @@ -3831,17 +3354,25 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
55229 return PTR_ERR(info->regmap_pmu);
55232 - ret = rockchip_gpiolib_register(pdev, info);
55234 + if (ctrl->soc_data_init) {
55235 + ret = ctrl->soc_data_init(info);
55244 - ret = rockchip_pinctrl_register(pdev, info);
55249 - rockchip_gpiolib_unregister(pdev, info);
55250 + dev_err(&pdev->dev, "failed to register gpio device\n");
55253 -
55254 - platform_set_drvdata(pdev, info);
55259 @@ -3881,6 +3412,7 @@ static struct rockchip_pin_ctrl px30_pin_ctrl = {
55267 @@ -3907,6 +3439,86 @@ static struct rockchip_pin_ctrl rv1108_pin_ctrl = {
55283 + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2",
55300 + .label = "RV1126-GPIO",
55322 + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
55339 + .label = "RK1808-GPIO",
55354 @@ -4029,9 +3641,9 @@ static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
55358 - PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
55359 - IOMUX_SOURCE_PMU,
55360 - IOMUX_SOURCE_PMU,
55367 @@ -4106,6 +3718,7 @@ static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
55375 @@ -4230,11 +3843,55 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
55388 + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
55405 + .label = "RK3568-GPIO",
55420 { .compatible = "rockchip,px30-pinctrl",
55422 { .compatible = "rockchip,rv1108-pinctrl",
55424 + { .compatible = "rockchip,rv1126-pinctrl",
55426 + { .compatible = "rockchip,rk1808-pinctrl",
55428 { .compatible = "rockchip,rk2928-pinctrl",
55430 { .compatible = "rockchip,rk3036-pinctrl",
55431 @@ -4259,6 +3916,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
55433 { .compatible = "rockchip,rk3399-pinctrl",
55435 + { .compatible = "rockchip,rk3568-pinctrl",
55440 @@ -4276,3 +3935,14 @@ static int __init rockchip_pinctrl_drv_register(void)
55453 +MODULE_ALIAS("platform:pinctrl-rockchip");
55455 diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
55457 --- a/drivers/power/reset/gpio-poweroff.c
55458 +++ b/drivers/power/reset/gpio-poweroff.c
55459 @@ -90,7 +90,6 @@ static const struct of_device_id of_gpio_poweroff_match[] = {
55460 { .compatible = "gpio-poweroff", },
55463 -MODULE_DEVICE_TABLE(of, of_gpio_poweroff_match);
55467 diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
55469 --- a/drivers/power/supply/Kconfig
55471 @@ -692,8 +692,7 @@ config BATTERY_GOLDFISH
55475 - depends on I2C
55476 - select REGMAP_I2C
55481 @@ -776,4 +775,18 @@ config RN5T618_POWER
55500 diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
55502 --- a/drivers/power/supply/Makefile
55504 @@ -98,3 +98,4 @@ obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o
55505 obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o
55506 obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o
55507 obj-$(CONFIG_RN5T618_POWER) += rn5t618_power.o
55508 +obj-y += ../../$(VENDOR_DRIVER_DIR)/power/supply/
55509 diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
55511 --- a/drivers/pwm/Kconfig
55513 @@ -408,6 +408,12 @@ config PWM_ROCKCHIP
55526 diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
55528 --- a/drivers/pwm/pwm-rockchip.c
55529 +++ b/drivers/pwm/pwm-rockchip.c
55530 @@ -11,6 +11,7 @@
55538 @@ -26,15 +27,25 @@
55564 @@ -49,7 +60,9 @@ struct rockchip_pwm_data {
55574 @@ -63,7 +76,6 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
55577 u32 enable_conf = pc->data->enable_conf;
55578 - unsigned long clk_rate;
55582 @@ -72,15 +84,13 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
55586 - clk_rate = clk_get_rate(pc->clk);
55587 -
55588 tmp = readl_relaxed(pc->base + pc->data->regs.period);
55589 tmp *= pc->data->prescaler * NSEC_PER_SEC;
55590 - state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
55591 + state->period = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
55593 tmp = readl_relaxed(pc->base + pc->data->regs.duty);
55594 tmp *= pc->data->prescaler * NSEC_PER_SEC;
55595 - state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
55596 + state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
55598 val = readl_relaxed(pc->base + pc->data->regs.ctrl);
55599 state->enabled = (val & enable_conf) == enable_conf;
55600 @@ -98,28 +108,48 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
55604 - u64 clk_rate, div;
55609 - clk_rate = clk_get_rate(pc->clk);
55610 -
55616 - div = clk_rate * state->period;
55617 + div = (u64)pc->clk_rate * state->period;
55619 pc->data->prescaler * NSEC_PER_SEC);
55621 - div = clk_rate * state->duty_cycle;
55622 + div = (u64)pc->clk_rate * state->duty_cycle;
55623 duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
55630 ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
55631 + if (pc->data->vop_pwm) {
55632 + if (pc->vop_pwm_en)
55639 + if (state->oneshot_count > PWM_ONESHOT_COUNT_MAX) {
55640 + pc->oneshot = false;
55641 + dev_err(chip->dev, "Oneshot_count value overflow.\n");
55642 + } else if (state->oneshot_count > 0) {
55643 + pc->oneshot = true;
55644 + ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
55646 + pc->oneshot = false;
55651 if (pc->data->supports_lock) {
55653 writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl);
55654 @@ -145,6 +175,7 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
55657 writel(ctrl, pc->base + pc->data->regs.ctrl);
55662 @@ -163,13 +194,24 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
55665 val = readl_relaxed(pc->base + pc->data->regs.ctrl);
55666 + val &= ~pc->data->enable_conf_mask;
55668 - if (enable)
55669 + if (PWM_OUTPUT_CENTER & pc->data->enable_conf_mask) {
55670 + if (pc->center_aligned)
55676 - else
55677 + if (pc->oneshot)
55683 writel_relaxed(val, pc->base + pc->data->regs.ctrl);
55684 + if (pc->data->vop_pwm)
55685 + pc->vop_pwm_en = enable;
55688 clk_disable(pc->clk);
55689 @@ -207,6 +249,8 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
55693 + if (state->enabled)
55694 + ret = pinctrl_select_state(pc->pinctrl, pc->active_state);
55696 clk_disable(pc->pclk);
55698 @@ -229,7 +273,9 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
55708 @@ -242,8 +288,10 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
55719 @@ -256,8 +304,10 @@ static const struct rockchip_pwm_data pwm_data_vop = {
55730 @@ -270,8 +320,10 @@ static const struct rockchip_pwm_data pwm_data_v3 = {
55741 @@ -301,7 +353,8 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55742 return -ENOMEM;
55745 - pc->base = devm_ioremap_resource(&pdev->dev, r);
55746 + pc->base = devm_ioremap(&pdev->dev, r->start,
55748 if (IS_ERR(pc->base))
55749 return PTR_ERR(pc->base);
55751 @@ -339,6 +392,18 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55755 + pc->pinctrl = devm_pinctrl_get(&pdev->dev);
55756 + if (IS_ERR(pc->pinctrl)) {
55757 + dev_err(&pdev->dev, "Get pinctrl failed!\n");
55758 + return PTR_ERR(pc->pinctrl);
55761 + pc->active_state = pinctrl_lookup_state(pc->pinctrl, "active");
55762 + if (IS_ERR(pc->active_state)) {
55763 + dev_err(&pdev->dev, "No active pinctrl state\n");
55764 + return PTR_ERR(pc->active_state);
55769 pc->data = id->data;
55770 @@ -346,6 +411,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55771 pc->chip.ops = &rockchip_pwm_ops;
55772 pc->chip.base = -1;
55773 pc->chip.npwm = 1;
55774 + pc->clk_rate = clk_get_rate(pc->clk);
55776 if (pc->data->supports_polarity) {
55777 pc->chip.of_xlate = of_pwm_xlate_with_flags;
55778 @@ -356,6 +422,9 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
55779 ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
55782 + pc->center_aligned =
55783 + device_property_read_bool(&pdev->dev, "center-aligned");
55785 ret = pwmchip_add(&pc->chip);
55787 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
55788 @@ -396,7 +465,21 @@ static struct platform_driver rockchip_pwm_driver = {
55810 diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
55812 --- a/drivers/pwm/sysfs.c
55814 @@ -103,6 +103,43 @@ static ssize_t duty_cycle_store(struct device *child,
55836 + struct pwm_device *pwm = export->pwm;
55845 + mutex_lock(&export->lock);
55849 + mutex_unlock(&export->lock);
55858 @@ -217,6 +254,9 @@ static ssize_t capture_show(struct device *child,
55868 @@ -224,6 +264,9 @@ static DEVICE_ATTR_RO(capture);
55878 diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
55880 --- a/drivers/regulator/Kconfig
55882 @@ -904,11 +904,11 @@ config REGULATOR_RC5T583
55886 - tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
55890 Select this option to enable the power regulator of ROCKCHIP
55891 - PMIC RK805,RK809&RK817,RK808 and RK818.
55896 @@ -1279,5 +1279,11 @@ config REGULATOR_QCOM_LABIBB
55908 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
55910 --- a/drivers/regulator/Makefile
55912 @@ -157,5 +157,6 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
55913 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
55914 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
55915 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
55916 +obj-$(CONFIG_REGULATOR_XZ3216) += ../$(VENDOR_DRIVER_DIR)/regulator/
55918 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
55919 diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
55921 --- a/drivers/regulator/core.c
55923 @@ -51,6 +51,7 @@ static LIST_HEAD(regulator_map_list);
55931 @@ -92,6 +93,11 @@ struct regulator_supply_alias {
55943 @@ -4940,11 +4946,265 @@ static void regulator_dev_release(struct device *dev)
55962 + rdev_err(regulator->rdev, "enable failed, ret=%d\n",
55967 + rdev_err(regulator->rdev, "disable failed, ret=%d\n",
55982 + rdev_err(regulator->rdev, "force_disable failed, ret=%d\n",
55995 + struct regulator *regulator = file->private_data;
55996 + struct regulator_dev *rdev = regulator->rdev;
56001 + int min_uV, max_uV = -1;
56005 + return -EFAULT;
56012 + rdev_err(regulator->rdev, "incorrect values specified: \"%s\"; should be: \"target_uV\"\n",
56014 + return -EINVAL;
56017 + max_uV = rdev->constraints->max_uV;
56019 + list_for_each_entry(reg, &rdev->consumer_list, list) {
56020 + if ((!reg->voltage->min_uV && !reg->voltage->max_uV) ||
56023 + reg->voltage->min_uV = min_uV;
56024 + reg->voltage->max_uV = max_uV;
56029 + rdev_err(regulator->rdev, "set voltage(%d, %d) failed, ret=%d\n",
56034 + rdev_err(regulator->rdev, "voltage request string exceeds maximum buffer size\n");
56035 + return -EINVAL;
56049 + rdev_err(regulator->rdev, "set mode=%u failed, ret=%d\n",
56063 + rdev_err(regulator->rdev, "set load=%d failed, ret=%d\n",
56095 + struct regulator *regulator = file->private_data;
56101 + ret = snprintf(buf, MAX_DEBUG_BUF_LEN - 1, "%d\n", voltage);
56108 + file->private_data = inode->i_private;
56126 + rdev_err(regulator->rdev, "get mode failed, ret=%d\n", mode);
56142 + struct regulator_dev *rdev = m->private;
56149 + if (rdev->open_count)
56150 + seq_printf(m, "%-32s Min_uV Max_uV load_uA\n",
56151 + "Device-Supply");
56153 + list_for_each_entry(reg, &rdev->consumer_list, list) {
56154 + if (reg->supply_name)
56155 + supply_name = reg->supply_name;
56157 + supply_name = "(null)-(null)";
56159 + seq_printf(m, "%-32s %8d %8d %8d\n", supply_name,
56160 + reg->voltage->min_uV, reg->voltage->max_uV, reg->uA_load);
56170 + return single_open(file, reg_debug_consumers_show, inode->i_private);
56185 + debugfs_remove_recursive(rdev->debugfs);
56188 + if (reg_debug->reg->rdev == rdev) {
56189 + reg_debug->reg->debugfs = NULL;
56190 + list_del(&reg_debug->list);
56191 + regulator_put(reg_debug->reg);
56199 struct device *parent = rdev->dev.parent;
56208 if (parent && rname == rdev->desc->name) {
56209 @@ -4965,8 +5225,88 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
56210 &rdev->open_count);
56211 debugfs_create_u32("bypass_count", 0444, rdev->debugfs,
56212 &rdev->bypass_count);
56213 + debugfs_create_file("consumers", 0444, rdev->debugfs, rdev,
56228 + reg_debug->reg = regulator;
56229 + list_add(&reg_debug->list, &regulator_debug_list);
56231 + ops = rdev->desc->ops;
56237 + debugfs_create_file("enable", mode, rdev->debugfs, regulator,
56241 + if (ops->is_enabled)
56244 + if (ops->disable)
56248 + debugfs_create_file("force_disable", mode, rdev->debugfs,
56252 + if (ops->get_voltage || ops->get_voltage_sel)
56255 + if (ops->set_voltage || ops->set_voltage_sel)
56259 + debugfs_create_file("voltage", mode, rdev->debugfs, regulator,
56263 + if (ops->get_mode)
56266 + if (ops->set_mode)
56270 + debugfs_create_file("mode", mode, rdev->debugfs, regulator,
56274 + if (ops->get_mode)
56277 + if (ops->set_load || (ops->get_optimum_mode && ops->set_mode))
56281 + debugfs_create_file("load", mode, rdev->debugfs, regulator,
56298 @@ -5445,6 +5785,7 @@ void regulator_unregister(struct regulator_dev *rdev)
56303 WARN_ON(rdev->open_count);
56306 @@ -5875,7 +6216,11 @@ static int __init regulator_init(void)
56318 diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
56320 --- a/drivers/regulator/fan53555.c
56322 @@ -20,10 +20,23 @@
56346 @@ -36,6 +49,7 @@
56354 @@ -47,13 +61,25 @@
56358 -#define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
56359 -#define FAN53526_NVOLTAGES 128
56382 @@ -88,8 +114,10 @@ enum {
56393 @@ -97,17 +125,52 @@ struct fan53555_device_info {
56408 - unsigned int vsel_count;
56409 - /* Mode */
56410 - unsigned int mode_reg;
56411 - unsigned int mode_mask;
56433 + if (di->vendor == FAN53555_VENDOR_RK) {
56434 + ret = regmap_read(di->regmap, RK860X_MAX_SET, &val);
56450 @@ -118,8 +181,8 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
56454 - ret = regmap_update_bits(rdev->regmap, di->sleep_reg,
56455 - di->desc.vsel_mask, ret);
56456 + ret = regmap_update_bits(di->regmap, di->sleep_reg,
56457 + di->vol_mask, ret);
56461 @@ -133,7 +196,7 @@ static int fan53555_set_suspend_enable(struct regulator_dev *rdev)
56465 - return regmap_update_bits(rdev->regmap, di->sleep_reg,
56466 + return regmap_update_bits(di->regmap, di->sleep_en_reg,
56470 @@ -141,21 +204,69 @@ static int fan53555_set_suspend_disable(struct regulator_dev *rdev)
56474 - return regmap_update_bits(rdev->regmap, di->sleep_reg,
56475 + return regmap_update_bits(di->regmap, di->sleep_en_reg,
56483 + if (di->vsel_gpio) {
56484 + gpiod_set_raw_value(di->vsel_gpio, !di->sleep_vsel_id);
56488 + return regmap_update_bits(di->regmap, di->en_reg,
56496 + if (di->vsel_gpio) {
56497 + gpiod_set_raw_value(di->vsel_gpio, di->sleep_vsel_id);
56501 + return regmap_update_bits(di->regmap, di->en_reg,
56511 + if (di->vsel_gpio) {
56512 + if (di->sleep_vsel_id)
56513 + return !gpiod_get_raw_value(di->vsel_gpio);
56515 + return gpiod_get_raw_value(di->vsel_gpio);
56518 + ret = regmap_read(di->regmap, di->en_reg, &val);
56533 - regmap_update_bits(rdev->regmap, di->mode_reg,
56534 + regmap_update_bits(di->regmap, di->mode_reg,
56535 di->mode_mask, di->mode_mask);
56538 - regmap_update_bits(rdev->regmap, di->vol_reg, di->mode_mask, 0);
56539 + regmap_update_bits(di->regmap, di->mode_reg, di->mode_mask, 0);
56542 return -EINVAL;
56543 @@ -169,7 +280,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
56547 - ret = regmap_read(rdev->regmap, di->mode_reg, &val);
56548 + ret = regmap_read(di->regmap, di->mode_reg, &val);
56551 if (val & di->mode_mask)
56552 @@ -189,13 +300,37 @@ static const int slew_rates[] = {
56566 int regval = -1, i;
56570 - for (i = 0; i < ARRAY_SIZE(slew_rates); i++) {
56571 - if (ramp <= slew_rates[i])
56572 + switch (di->vendor) {
56584 + return -EINVAL;
56592 @@ -206,20 +341,20 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
56593 return -EINVAL;
56596 - return regmap_update_bits(rdev->regmap, FAN53555_CONTROL,
56597 - CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT);
56598 + return regmap_update_bits(di->regmap, di->slew_reg,
56599 + di->slew_mask, regval << di->slew_shift);
56604 - .get_voltage_sel = regulator_get_voltage_sel_regmap,
56610 - .enable = regulator_enable_regmap,
56611 - .disable = regulator_disable_regmap,
56612 - .is_enabled = regulator_is_enabled_regmap,
56619 @@ -250,7 +385,7 @@ static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di)
56620 return -EINVAL;
56623 - di->vsel_count = FAN53526_NVOLTAGES;
56624 + di->n_voltages = FAN53555_NVOLTAGES_64;
56628 @@ -292,8 +427,58 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
56629 "Chip ID %d not supported!\n", di->chip_id);
56630 return -EINVAL;
56632 + di->vol_mask = VSEL_NSEL_MASK;
56633 + di->mode_reg = di->vol_reg;
56634 + di->mode_mask = VSEL_MODE;
56635 + di->slew_reg = FAN53555_CONTROL;
56636 + di->slew_mask = CTL_SLEW_MASK;
56637 + di->slew_shift = CTL_SLEW_SHIFT;
56638 + di->n_voltages = FAN53555_NVOLTAGES_64;
56640 - di->vsel_count = FAN53555_NVOLTAGES;
56649 + if (di->sleep_vsel_id) {
56650 + di->sleep_reg = RK860X_VSEL1;
56651 + di->vol_reg = RK860X_VSEL0;
56652 + di->mode_reg = FAN53555_VSEL0;
56653 + di->en_reg = FAN53555_VSEL0;
56654 + di->sleep_en_reg = FAN53555_VSEL1;
56656 + di->sleep_reg = RK860X_VSEL0;
56657 + di->vol_reg = RK860X_VSEL1;
56658 + di->mode_reg = FAN53555_VSEL1;
56659 + di->en_reg = FAN53555_VSEL1;
56660 + di->sleep_en_reg = FAN53555_VSEL0;
56663 + di->mode_mask = VSEL_MODE;
56664 + di->vol_mask = RK_VSEL_NSEL_MASK;
56665 + di->slew_reg = FAN53555_CONTROL;
56666 + di->slew_mask = CTL_SLEW_MASK;
56667 + di->slew_shift = CTL_SLEW_SHIFT;
56670 + di->vsel_min = 500000;
56671 + di->vsel_step = 6250;
56672 + di->n_voltages = FAN53555_NVOLTAGES_160;
56674 + if (pdata->limit_volt) {
56675 + if (pdata->limit_volt < di->vsel_min ||
56676 + pdata->limit_volt > 1500000)
56677 + pdata->limit_volt = 1500000;
56678 + val = (pdata->limit_volt - di->vsel_min) / di->vsel_step;
56679 + ret = regmap_write(di->regmap, RK860X_MAX_SET, val);
56681 + dev_err(di->dev, "Failed to set limit voltage!\n");
56688 @@ -312,8 +497,43 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
56689 "Chip ID %d not supported!\n", di->chip_id);
56690 return -EINVAL;
56692 + di->vol_mask = VSEL_NSEL_MASK;
56693 + di->mode_reg = di->vol_reg;
56694 + di->mode_mask = VSEL_MODE;
56695 + di->slew_reg = FAN53555_CONTROL;
56696 + di->slew_reg = FAN53555_CONTROL;
56697 + di->slew_mask = CTL_SLEW_MASK;
56698 + di->slew_shift = CTL_SLEW_SHIFT;
56699 + di->n_voltages = FAN53555_NVOLTAGES_64;
56701 - di->vsel_count = FAN53555_NVOLTAGES;
56707 + if (di->sleep_vsel_id) {
56708 + di->sleep_reg = TCS452X_VSEL1;
56709 + di->vol_reg = TCS452X_VSEL0;
56710 + di->mode_mask = TCS_VSEL0_MODE;
56712 + di->sleep_reg = TCS452X_VSEL0;
56713 + di->vol_reg = TCS452X_VSEL1;
56714 + di->mode_mask = TCS_VSEL1_MODE;
56717 + di->mode_reg = TCS452X_COMMAND;
56718 + di->vol_mask = TCS_VSEL_NSEL_MASK;
56719 + di->slew_reg = TCS452X_TIME;
56720 + di->slew_mask = TCS_SLEW_MASK;
56721 + di->slew_shift = TCS_SLEW_MASK;
56724 + di->vsel_min = 600000;
56725 + di->vsel_step = 6250;
56726 + di->n_voltages = FAN53555_NVOLTAGES_127;
56728 + di->en_reg = di->vol_reg;
56729 + di->sleep_en_reg = di->sleep_reg;
56733 @@ -343,7 +563,10 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
56734 return -EINVAL;
56737 - /* Setup mode control register */
56738 + di->en_reg = di->vol_reg;
56739 + di->sleep_en_reg = di->sleep_reg;
56742 switch (di->vendor) {
56744 di->mode_reg = FAN53555_CONTROL;
56745 @@ -356,28 +579,20 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
56746 di->mode_mask = CTL_MODE_VSEL0_MODE;
56749 - break;
56750 - case FAN53555_VENDOR_FAIRCHILD:
56751 - case FAN53555_VENDOR_SILERGY:
56752 - di->mode_reg = di->vol_reg;
56753 - di->mode_mask = VSEL_MODE;
56754 - break;
56755 - default:
56756 - dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
56757 - return -EINVAL;
56758 - }
56759 -
56760 - /* Setup voltage range */
56761 - switch (di->vendor) {
56762 - case FAN53526_VENDOR_FAIRCHILD:
56778 dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
56779 return -EINVAL;
56780 @@ -390,23 +605,23 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
56783 struct regulator_desc *rdesc = &di->desc;
56784 - struct regulator_dev *rdev;
56786 rdesc->name = "fan53555-reg";
56787 rdesc->supply_name = "vin";
56788 rdesc->ops = &fan53555_regulator_ops;
56789 rdesc->type = REGULATOR_VOLTAGE;
56790 - rdesc->n_voltages = di->vsel_count;
56791 - rdesc->enable_reg = di->vol_reg;
56792 + rdesc->n_voltages = di->n_voltages;
56793 + rdesc->enable_reg = di->en_reg;
56794 rdesc->enable_mask = VSEL_BUCK_EN;
56795 rdesc->min_uV = di->vsel_min;
56796 rdesc->uV_step = di->vsel_step;
56797 rdesc->vsel_reg = di->vol_reg;
56798 - rdesc->vsel_mask = di->vsel_count - 1;
56799 + rdesc->vsel_mask = di->vol_mask;
56800 rdesc->owner = THIS_MODULE;
56801 + rdesc->enable_time = 400;
56803 - rdev = devm_regulator_register(di->dev, &di->desc, config);
56804 - return PTR_ERR_OR_ZERO(rdev);
56805 + di->rdev = devm_regulator_register(di->dev, &di->desc, config);
56806 + return PTR_ERR_OR_ZERO(di->rdev);
56810 @@ -419,7 +634,7 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
56814 - int ret;
56819 @@ -427,12 +642,30 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
56822 pdata->regulator = of_get_regulator_init_data(dev, np, desc);
56823 + pdata->regulator->constraints.initial_state = PM_SUSPEND_MEM;
56825 + if (!(of_property_read_u32(np, "limit-microvolt", &limit_volt)))
56826 + pdata->limit_volt = limit_volt;
56828 ret = of_property_read_u32(np, "fcs,suspend-voltage-selector",
56831 pdata->sleep_vsel_id = tmp;
56833 + if (pdata->sleep_vsel_id)
56838 + pdata->vsel_gpio =
56841 + if (IS_ERR(pdata->vsel_gpio)) {
56842 + ret = PTR_ERR(pdata->vsel_gpio);
56844 + pdata->vsel_gpio = NULL;
56850 @@ -443,12 +676,21 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
56872 @@ -461,7 +703,6 @@ static int fan53555_regulator_probe(struct i2c_client *client,
56876 - struct regmap *regmap;
56880 @@ -470,6 +711,8 @@ static int fan53555_regulator_probe(struct i2c_client *client,
56882 return -ENOMEM;
56884 + di->desc.of_map_mode = fan53555_map_mode;
56886 pdata = dev_get_platdata(&client->dev);
56888 pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
56889 @@ -479,6 +722,9 @@ static int fan53555_regulator_probe(struct i2c_client *client,
56890 return -ENODEV;
56893 + di->vsel_gpio = pdata->vsel_gpio;
56894 + di->sleep_vsel_id = pdata->sleep_vsel_id;
56896 di->regulator = pdata->regulator;
56897 if (client->dev.of_node) {
56898 di->vendor =
56899 @@ -498,22 +744,22 @@ static int fan53555_regulator_probe(struct i2c_client *client,
56900 di->vendor = id->driver_data;
56903 - regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
56904 - if (IS_ERR(regmap)) {
56905 + di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
56906 + if (IS_ERR(di->regmap)) {
56907 dev_err(&client->dev, "Failed to allocate regmap!\n");
56908 - return PTR_ERR(regmap);
56909 + return PTR_ERR(di->regmap);
56911 di->dev = &client->dev;
56914 - ret = regmap_read(regmap, FAN53555_ID1, &val);
56915 + ret = regmap_read(di->regmap, FAN53555_ID1, &val);
56917 dev_err(&client->dev, "Failed to get chip ID!\n");
56920 di->chip_id = val & DIE_ID;
56922 - ret = regmap_read(regmap, FAN53555_ID2, &val);
56923 + ret = regmap_read(di->regmap, FAN53555_ID2, &val);
56925 dev_err(&client->dev, "Failed to get chip Rev!\n");
56927 @@ -530,15 +776,52 @@ static int fan53555_regulator_probe(struct i2c_client *client,
56929 config.dev = di->dev;
56930 config.init_data = di->regulator;
56931 - config.regmap = regmap;
56932 + config.regmap = di->regmap;
56938 dev_err(&client->dev, "Failed to register regulator!\n");
56950 + dev_info(di->dev, "fan53555..... reset\n");
56952 + switch (di->vendor) {
56956 + ret = regmap_update_bits(di->regmap, di->slew_reg,
56960 + ret = regmap_update_bits(di->regmap, TCS452X_LIMCONF,
56964 + * it will return -ENXIO, ignore this error.
56966 + if (ret == -ENXIO)
56970 + ret = -EINVAL;
56975 + dev_err(di->dev, "reset: force fan53555_reset error! ret=%d\n", ret);
56977 + dev_info(di->dev, "reset: force fan53555_reset ok!\n");
56981 @@ -548,12 +831,21 @@ static const struct i2c_device_id fan53555_id[] = {
57003 @@ -565,6 +857,7 @@ static struct i2c_driver fan53555_regulator_driver = {
57011 diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
57013 --- a/drivers/regulator/of_regulator.c
57015 @@ -417,8 +417,12 @@ device_node *regulator_of_get_init_node(struct device *dev,
57018 name = of_get_property(child, "regulator-compatible", NULL);
57019 - if (!name)
57020 - name = child->name;
57022 + if (!desc->of_match_full_name)
57023 + name = child->name;
57025 + name = child->full_name;
57028 if (!strcmp(desc->of_match, name)) {
57030 diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
57032 --- a/drivers/regulator/rk808-regulator.c
57033 +++ b/drivers/regulator/rk808-regulator.c
57034 @@ -34,6 +34,11 @@
57046 @@ -60,8 +65,8 @@
57050 -/* max steps for increase voltage of Buck1/2, equal 100mv*/
57051 -#define MAX_STEPS_ONE_TIME 8
57057 @@ -113,10 +118,15 @@
57067 - _vmask, _ereg, _emask, _etime) \
57070 - _vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops)
57075 @@ -124,9 +134,9 @@
57079 - _vmask, _ereg, _emask, _disval, _etime) \
57082 - _vmask, _ereg, _emask, _emask, _disval, _etime, &rk817_reg_ops)
57087 @@ -145,10 +155,10 @@
57091 -#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \
57095 - _emask, _disval, &rk817_switch_ops)
57100 @@ -165,11 +175,33 @@ static const int rk808_buck_config_regs[] = {
57105 + REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), /* 0.7125v - 1.45v */
57106 + REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),/* 1.8v - 2.2v */
57107 + REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0), /* 2.3v - 2.3v */
57111 + REGULATOR_LINEAR_RANGE(800000, 0, 26, 100000), /* 0.8v - 3.4v */
57121 + REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), /* 0.7125v - 1.45v */
57122 + REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),/* 1.8v - 2.2v */
57123 + REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0), /* 2.3v - 2.3v */
57127 + REGULATOR_LINEAR_RANGE(800000, 0, 26, 100000), /* 0.8v - 3.4 */
57134 @@ -287,6 +319,58 @@ static int rk808_buck1_2_i2c_set_voltage_sel(struct regulator_dev *rdev,
57151 + regmap_read(rdev->regmap, RK816_CHIP_VER_REG, &rk816_type);
57153 + sel <<= ffs(rdev->desc->vsel_mask) - 1;
57163 + ret = regmap_update_bits(rdev->regmap,
57164 + rdev->desc->vsel_reg,
57165 + rdev->desc->vsel_mask, sel);
57170 + ret = regmap_update_bits(rdev->regmap,
57178 + regmap_read(rdev->regmap,
57179 + rdev->desc->vsel_reg, &real_sel);
57180 + real_sel &= rdev->desc->vsel_mask;
57181 + delay--;
57193 @@ -340,6 +424,33 @@ static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev,
57217 + rdev->desc->name, ramp_delay);
57220 + return regmap_update_bits(rdev->regmap, reg,
57227 @@ -366,6 +477,16 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
57233 + struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
57235 + if (rk808->variant == RK805_ID)
57244 @@ -428,9 +549,14 @@ static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
57248 - unsigned int reg;
57251 - reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57252 + if (rdev->desc->id >= RK805_ID_LDO1)
57257 + reg = rdev->desc->enable_reg + offset;
57259 return regmap_update_bits(rdev->regmap, reg,
57260 rdev->desc->enable_mask,
57261 @@ -439,18 +565,77 @@ static int rk805_set_suspend_enable(struct regulator_dev *rdev)
57265 - unsigned int reg;
57268 - reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57269 + if (rdev->desc->id >= RK805_ID_LDO1)
57274 + reg = rdev->desc->enable_reg + offset;
57276 return regmap_update_bits(rdev->regmap, reg,
57277 rdev->desc->enable_mask,
57285 + if (rdev->desc->id <= RK816_ID_DCDC4) {
57286 + reg = rdev->desc->enable_reg +
57288 + val = 1 << rdev->desc->id;
57289 + } else if ((rdev->desc->id > RK816_ID_DCDC4) &&
57290 + (rdev->desc->id <= RK816_ID_LDO4)) {
57291 + reg = rdev->desc->enable_reg -
57293 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57295 + reg = rdev->desc->enable_reg -
57297 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57300 + return regmap_update_bits(rdev->regmap, reg,
57309 + if (rdev->desc->id <= RK816_ID_DCDC4) {
57310 + reg = rdev->desc->enable_reg +
57312 + val = 1 << rdev->desc->id;
57313 + } else if ((rdev->desc->id > RK816_ID_DCDC4) &&
57314 + (rdev->desc->id <= RK816_ID_LDO4)) {
57315 + reg = rdev->desc->enable_reg -
57317 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57319 + reg = rdev->desc->enable_reg -
57321 + val = 1 << (rdev->desc->id - RK816_ID_LDO1);
57324 + return regmap_update_bits(rdev->regmap, reg,
57332 + struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
57334 + if (rk808->variant == RK816_ID)
57336 + else if (rk808->variant == RK805_ID)
57339 reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57341 @@ -462,6 +647,12 @@ static int rk808_set_suspend_enable(struct regulator_dev *rdev)
57345 + struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
57347 + if (rk808->variant == RK816_ID)
57349 + else if (rk808->variant == RK805_ID)
57352 reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
57354 @@ -560,6 +751,22 @@ static unsigned int rk8xx_get_mode(struct regulator_dev *rdev)
57360 + return regmap_update_bits(rdev->regmap,
57361 + rdev->desc->enable_reg,
57362 + rdev->desc->enable_mask,
57363 + rdev->desc->enable_mask);
57368 + return regmap_update_bits(rdev->regmap,
57369 + rdev->desc->enable_reg,
57370 + rdev->desc->enable_mask,
57371 + rdev->desc->disable_val);
57377 @@ -569,17 +776,7 @@ static int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
57381 - /* add write mask bit */
57382 - val |= (rdev->desc->enable_mask & 0xf0);
57383 - val &= rdev->desc->enable_mask;
57384 -
57385 - if (rdev->desc->enable_is_inverted) {
57386 - if (rdev->desc->enable_val)
57387 - return val != rdev->desc->enable_val;
57388 - return (val == 0);
57389 - }
57390 - if (rdev->desc->enable_val)
57391 - return val == rdev->desc->enable_val;
57392 + val &= rdev->desc->enable_val;
57396 @@ -595,27 +792,6 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
57400 -static const struct regulator_ops rk805_reg_ops = {
57401 - .list_voltage = regulator_list_voltage_linear,
57402 - .map_voltage = regulator_map_voltage_linear,
57403 - .get_voltage_sel = regulator_get_voltage_sel_regmap,
57404 - .set_voltage_sel = regulator_set_voltage_sel_regmap,
57405 - .enable = regulator_enable_regmap,
57406 - .disable = regulator_disable_regmap,
57407 - .is_enabled = regulator_is_enabled_regmap,
57408 - .set_suspend_voltage = rk808_set_suspend_voltage,
57409 - .set_suspend_enable = rk805_set_suspend_enable,
57410 - .set_suspend_disable = rk805_set_suspend_disable,
57411 -};
57412 -
57413 -static const struct regulator_ops rk805_switch_ops = {
57414 - .enable = regulator_enable_regmap,
57415 - .disable = regulator_disable_regmap,
57416 - .is_enabled = regulator_is_enabled_regmap,
57417 - .set_suspend_enable = rk805_set_suspend_enable,
57418 - .set_suspend_disable = rk805_set_suspend_disable,
57419 -};
57420 -
57424 @@ -625,12 +801,33 @@ static const struct regulator_ops rk808_buck1_2_ops = {
57428 - .set_ramp_delay = rk808_set_ramp_delay,
57459 @@ -652,6 +849,10 @@ static const struct regulator_ops rk808_reg_ops_ranges = {
57470 @@ -661,24 +862,20 @@ static const struct regulator_ops rk808_switch_ops = {
57480 -static const struct linear_range rk805_buck_1_2_voltage_ranges[] = {
57481 - REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500),
57482 - REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),
57483 - REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0),
57484 -};
57485 -
57492 - .enable = regulator_enable_regmap,
57493 - .disable = regulator_disable_regmap,
57499 @@ -690,8 +887,8 @@ static const struct regulator_ops rk817_reg_ops = {
57503 - .enable = regulator_enable_regmap,
57504 - .disable = regulator_disable_regmap,
57510 @@ -703,8 +900,8 @@ static const struct regulator_ops rk817_boost_ops = {
57514 - .enable = regulator_enable_regmap,
57515 - .disable = regulator_disable_regmap,
57521 @@ -716,8 +913,8 @@ static const struct regulator_ops rk817_buck_ops_range = {
57525 - .enable = regulator_enable_regmap,
57526 - .disable = regulator_disable_regmap,
57532 @@ -729,8 +926,8 @@ static const struct regulator_ops rk817_buck_ops_range = {
57536 - .enable = regulator_enable_regmap,
57537 - .disable = regulator_disable_regmap,
57543 @@ -751,7 +948,10 @@ static const struct regulator_desc rk805_reg[] = {
57547 - .enable_mask = BIT(0),
57555 @@ -767,7 +967,10 @@ static const struct regulator_desc rk805_reg[] = {
57559 - .enable_mask = BIT(1),
57567 @@ -775,27 +978,45 @@ static const struct regulator_desc rk805_reg[] = {
57571 - .ops = &rk805_switch_ops,
57576 - .enable_mask = BIT(2),
57603 - RK805_DESC(RK805_ID_DCDC4, "DCDC_REG4", "vcc4", 800, 3400, 100,
57604 - RK805_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
57605 - RK805_DCDC_EN_REG, BIT(3), 0),
57606 -
57609 - BIT(0), 400),
57613 - BIT(1), 400),
57617 - BIT(2), 400),
57622 @@ -892,6 +1113,101 @@ static const struct regulator_desc rk808_reg[] = {
57724 @@ -908,7 +1224,7 @@ static const struct regulator_desc rk809_reg[] = {
57728 - .enable_val = ENABLE_MASK(RK817_ID_DCDC1),
57733 @@ -927,7 +1243,7 @@ static const struct regulator_desc rk809_reg[] = {
57737 - .enable_val = ENABLE_MASK(RK817_ID_DCDC2),
57742 @@ -946,7 +1262,7 @@ static const struct regulator_desc rk809_reg[] = {
57746 - .enable_val = ENABLE_MASK(RK817_ID_DCDC3),
57751 @@ -965,7 +1281,7 @@ static const struct regulator_desc rk809_reg[] = {
57755 - .enable_val = ENABLE_MASK(RK817_ID_DCDC4),
57760 @@ -985,52 +1301,52 @@ static const struct regulator_desc rk809_reg[] = {
57764 - .enable_val = ENABLE_MASK(1),
57772 - RK817_POWER_EN_REG(1), ENABLE_MASK(0),
57777 - RK817_POWER_EN_REG(1), ENABLE_MASK(1),
57782 - RK817_POWER_EN_REG(1), ENABLE_MASK(2),
57787 - RK817_POWER_EN_REG(1), ENABLE_MASK(3),
57792 - RK817_POWER_EN_REG(2), ENABLE_MASK(0),
57797 - RK817_POWER_EN_REG(2), ENABLE_MASK(1),
57802 - RK817_POWER_EN_REG(2), ENABLE_MASK(2),
57807 - RK817_POWER_EN_REG(2), ENABLE_MASK(3),
57812 - RK817_POWER_EN_REG(3), ENABLE_MASK(0),
57816 - RK817_POWER_EN_REG(3), ENABLE_MASK(2),
57820 - RK817_POWER_EN_REG(3), ENABLE_MASK(3),
57825 @@ -1114,46 +1430,46 @@ static const struct regulator_desc rk817_reg[] = {
57829 - RK817_POWER_EN_REG(1), ENABLE_MASK(0),
57834 - RK817_POWER_EN_REG(1), ENABLE_MASK(1),
57839 - RK817_POWER_EN_REG(1), ENABLE_MASK(2),
57844 - RK817_POWER_EN_REG(1), ENABLE_MASK(3),
57849 - RK817_POWER_EN_REG(2), ENABLE_MASK(0),
57854 - RK817_POWER_EN_REG(2), ENABLE_MASK(1),
57859 - RK817_POWER_EN_REG(2), ENABLE_MASK(2),
57864 - RK817_POWER_EN_REG(2), ENABLE_MASK(3),
57869 - RK817_POWER_EN_REG(3), ENABLE_MASK(0),
57874 - RK817_POWER_EN_REG(3), ENABLE_MASK(1), ENABLE_MASK(1),
57876 DISABLE_VAL(1), 400, 3500 - 5400),
57878 - RK817_POWER_EN_REG(3), ENABLE_MASK(2),
57883 @@ -1331,6 +1647,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
57894 @@ -1370,9 +1690,23 @@ static struct platform_driver rk808_regulator_driver = {
57914 -MODULE_DESCRIPTION("regulator driver for the RK805/RK808/RK818 series PMICs");
57916 MODULE_AUTHOR("Tony xie <tony.xie@rock-chips.com>");
57917 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
57918 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
57919 diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
57921 --- a/drivers/rtc/rtc-hym8563.c
57922 +++ b/drivers/rtc/rtc-hym8563.c
57923 @@ -96,13 +96,13 @@ static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
57927 -
57930 dev_warn(&client->dev,
57932 return -EINVAL;
57934 -
57936 tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK);
57937 tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK);
57938 tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK);
57939 @@ -232,12 +232,39 @@ static int hym8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
57940 if (alm_tm->tm_hour >= 24) {
57941 alm_tm->tm_hour = 0;
57942 alm_tm->tm_mday++;
57943 - if (alm_tm->tm_mday > 31)
57944 - alm_tm->tm_mday = 0;
57945 + alm_tm->tm_wday++;
57946 + if (alm_tm->tm_wday > 6)
57947 + alm_tm->tm_wday = 0;
57948 + switch (alm_tm->tm_mon + 1) {
57956 + if (alm_tm->tm_mday > 31)
57957 + alm_tm->tm_mday = 1;
57963 + if (alm_tm->tm_mday > 30)
57964 + alm_tm->tm_mday = 1;
57967 + if (alm_tm->tm_year / 4 == 0) {
57968 + if (alm_tm->tm_mday > 29)
57969 + alm_tm->tm_mday = 1;
57970 + } else if (alm_tm->tm_mday > 28) {
57971 + alm_tm->tm_mday = 1;
57978 -
57982 @@ -519,6 +546,19 @@ static int hym8563_probe(struct i2c_client *client,
58000 hym8563 = devm_kzalloc(&client->dev, sizeof(*hym8563), GFP_KERNEL);
58002 @@ -527,7 +567,7 @@ static int hym8563_probe(struct i2c_client *client,
58003 hym8563->client = client;
58006 - device_set_wakeup_capable(&client->dev, true);
58007 + // device_set_wakeup_capable(&client->dev, true);
58011 @@ -547,14 +587,24 @@ static int hym8563_probe(struct i2c_client *client,
58015 + if (client->irq > 0 ||
58016 + device_property_read_bool(&client->dev, "wakeup-source")) {
58017 + device_init_wakeup(&client->dev, true);
58025 - dev_dbg(&client->dev, "rtc information is %s\n",
58026 + dev_info(&client->dev, "rtc information is %s\n",
58029 + hym8563_rtc_read_time(&client->dev, &tm_read);
58031 + (tm_read.tm_mon == -1) || (rtc_valid_tm(&tm_read) != 0))
58032 + hym8563_rtc_set_time(&client->dev, &tm);
58034 hym8563->rtc = devm_rtc_device_register(&client->dev, client->name,
58036 if (IS_ERR(hym8563->rtc))
58037 diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
58039 --- a/drivers/soc/rockchip/Kconfig
58041 @@ -1,19 +1,49 @@
58042 # SPDX-License-Identifier: GPL-2.0-only
58075 - bool "Rockchip General Register Files support" if COMPILE_TEST
58076 - default y if ARCH_ROCKCHIP
58080 special additional settings registers for a lot of soc-components.
58087 + This driver support Decompress IP built-in Rockchip SoC, support
58093 @@ -22,8 +52,24 @@ config ROCKCHIP_IODOMAIN
58108 + tristate "Rockchip OPP select support"
58114 - bool "Rockchip generic power domain"
58117 select PM_GENERIC_DOMAINS
58119 @@ -34,4 +80,71 @@ config ROCKCHIP_PM_DOMAINS
58127 + The Process-Voltage-Temperature Monitor (PVTM) is used to monitor
58191 diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
58193 --- a/drivers/soc/rockchip/Makefile
58195 @@ -2,6 +2,21 @@
58199 +obj-$(CONFIG_ROCKCHIP_CPUINFO) += rockchip-cpuinfo.o
58200 obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
58201 +obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS) += rockchip_decompress.o
58202 obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o
58203 obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
58204 +obj-$(CONFIG_ROCKCHIP_FIQ_DEBUGGER) += rk_fiq_debugger.o
58205 +obj-$(CONFIG_ROCKCHIP_VENDOR_STORAGE) += rk_vendor_storage.o
58206 +obj-$(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE) += sdmmc_vendor_storage.o
58207 +obj-$(CONFIG_ROCKCHIP_FLASH_VENDOR_STORAGE) += flash_vendor_storage.o
58208 +obj-$(CONFIG_ROCKCHIP_MTD_VENDOR_STORAGE) += mtd_vendor_storage.o
58209 +obj-$(CONFIG_ROCKCHIP_IPA) += rockchip_ipa.o
58210 +obj-$(CONFIG_ROCKCHIP_OPP) += rockchip_opp_select.o
58211 +obj-$(CONFIG_ROCKCHIP_PVTM) += rockchip_pvtm.o
58212 +obj-$(CONFIG_ROCKCHIP_SUSPEND_MODE) += rockchip_pm_config.o
58213 +obj-$(CONFIG_ROCKCHIP_SYSTEM_MONITOR) += rockchip_system_monitor.o
58214 +obj-$(CONFIG_ROCKCHIP_DEBUG) += rockchip_debug.o
58216 +ccflags-y +=-I$(KERNEL_SOURCE_PATH)/drivers/mmc/host/
58218 diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c
58220 --- a/drivers/soc/rockchip/grf.c
58222 @@ -7,6 +7,7 @@
58230 @@ -25,6 +26,21 @@ struct rockchip_grf_info {
58252 @@ -86,6 +102,17 @@ static const struct rockchip_grf_info rk3328_grf __initconst = {
58270 @@ -108,8 +135,37 @@ static const struct rockchip_grf_info rk3399_grf __initconst = {
58302 + .compatible = "rockchip,px30-grf",
58305 .compatible = "rockchip,rk3036-grf",
58308 @@ -121,6 +177,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
58310 .compatible = "rockchip,rk3288-grf",
58313 + .compatible = "rockchip,rk3308-grf",
58316 .compatible = "rockchip,rk3328-grf",
58318 @@ -130,6 +189,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
58320 .compatible = "rockchip,rk3399-grf",
58323 + .compatible = "rockchip,rv1126-grf",
58328 @@ -175,3 +237,6 @@ static int __init rockchip_grf_init(void)
58335 diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
58337 --- a/drivers/soc/rockchip/io-domain.c
58338 +++ b/drivers/soc/rockchip/io-domain.c
58339 @@ -51,6 +51,10 @@
58350 @@ -74,8 +78,51 @@ struct rockchip_iodomain {
58360 + struct rockchip_iodomain *iod = supply->iod;
58365 + switch (supply->idx) {
58369 + b = supply->idx;
58371 + b = supply->idx + 4;
58374 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
58375 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
58385 + b = supply->idx - 1;
58389 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
58390 + regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
58393 + return -EINVAL;
58402 @@ -139,7 +186,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
58406 - ret = rockchip_iodomain_write(supply, uV);
58407 + ret = supply->iod->write(supply, uV);
58411 @@ -401,6 +448,21 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
58433 @@ -431,6 +493,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
58455 .compatible = "rockchip,px30-io-voltage-domain",
58456 @@ -472,6 +550,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
58457 .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
58461 + .compatible = "rockchip,rk3568-pmu-io-voltage-domain",
58465 .compatible = "rockchip,rv1108-io-voltage-domain",
58467 @@ -480,6 +562,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
58468 .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
58472 + .compatible = "rockchip,rv1126-pmu-io-voltage-domain",
58478 @@ -505,6 +591,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
58480 iod->soc_data = match->data;
58482 + if (match->data == &soc_data_rk3568_pmu)
58483 + iod->write = rk3568_pmu_iodomain_write;
58485 + iod->write = rockchip_iodomain_write;
58487 parent = pdev->dev.parent;
58488 if (parent && parent->of_node) {
58489 iod->grf = syscon_node_to_regmap(parent->of_node);
58490 @@ -565,7 +656,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
58491 supply->reg = reg;
58492 supply->nb.notifier_call = rockchip_iodomain_notify;
58494 - ret = rockchip_iodomain_write(supply, uV);
58495 + ret = iod->write(supply, uV);
58497 supply->reg = NULL;
58499 diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
58501 --- a/drivers/soc/rockchip/pm_domains.c
58503 @@ -5,6 +5,7 @@
58511 @@ -15,7 +16,12 @@
58521 #include <dt-bindings/power/px30-power.h>
58522 #include <dt-bindings/power/rk3036-power.h>
58523 #include <dt-bindings/power/rk3066-power.h>
58524 @@ -29,6 +35,7 @@
58525 #include <dt-bindings/power/rk3399-power.h>
58532 @@ -37,6 +44,10 @@ struct rockchip_domain_info {
58543 @@ -45,6 +56,7 @@ struct rockchip_pmu_info {
58551 @@ -72,6 +84,9 @@ struct rockchip_pm_domain {
58561 @@ -83,32 +98,89 @@ struct rockchip_pmu {
58574 + mutex_lock(&pd->pmu->mutex);
58581 + mutex_unlock(&pd->pmu->mutex);
58586 -#define DOMAIN(pwr, status, req, idle, ack, wakeup) \
58629 -#define DOMAIN_M(pwr, status, req, idle, ack, wakeup) \
58647 -#define DOMAIN_RK3036(req, ack, idle, wakeup) \
58654 @@ -116,20 +188,53 @@ struct rockchip_pmu {
58658 -#define DOMAIN_PX30(pwr, status, req, wakeup) \
58659 - DOMAIN_M(pwr, status, req, (req) << 16, req, wakeup)
58687 -#define DOMAIN_RK3288(pwr, status, req, wakeup) \
58688 - DOMAIN(pwr, status, req, req, (req) << 16, wakeup)
58692 -#define DOMAIN_RK3328(pwr, status, req, wakeup) \
58693 - DOMAIN_M(pwr, pwr, req, (req) << 10, req, wakeup)
58697 -#define DOMAIN_RK3368(pwr, status, req, wakeup) \
58698 - DOMAIN(pwr, status, req, (req) << 16, req, wakeup)
58702 -#define DOMAIN_RK3399(pwr, status, req, wakeup) \
58703 - DOMAIN(pwr, status, req, req, req, wakeup)
58718 @@ -155,20 +260,25 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
58719 const struct rockchip_domain_info *pd_info = pd->info;
58720 struct generic_pm_domain *genpd = &pd->genpd;
58721 struct rockchip_pmu *pmu = pd->pmu;
58726 - int ret;
58729 + if (pd_info->req_offset)
58730 + pd_req_offset = pd_info->req_offset;
58732 if (pd_info->req_mask == 0)
58734 else if (pd_info->req_w_mask)
58735 - regmap_write(pmu->regmap, pmu->info->req_offset,
58736 + regmap_write(pmu->regmap, pmu->info->req_offset + pd_req_offset,
58737 idle ? (pd_info->req_mask | pd_info->req_w_mask) :
58738 pd_info->req_w_mask);
58740 - regmap_update_bits(pmu->regmap, pmu->info->req_offset,
58741 - pd_info->req_mask, idle ? -1U : 0);
58742 + regmap_update_bits(pmu->regmap, pmu->info->req_offset +
58743 + pd_req_offset, pd_info->req_mask,
58744 + idle ? -1U : 0);
58748 @@ -179,22 +289,48 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
58751 dev_err(pmu->dev,
58752 - "failed to get ack on domain '%s', val=0x%x\n",
58753 - genpd->name, val);
58754 - return ret;
58756 + genpd->name, idle, target_ack, val);
58763 dev_err(pmu->dev,
58764 - "failed to set idle on domain '%s', val=%d\n",
58765 - genpd->name, is_idle);
58766 - return ret;
58768 + genpd->name, idle, is_idle);
58772 - return 0;
58786 + return -EINVAL;
58788 + if (IS_ERR_OR_NULL(dev->pm_domain))
58789 + return -EINVAL;
58791 + genpd = pd_to_genpd(dev->pm_domain);
58804 @@ -245,11 +381,63 @@ static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
58815 + return -EINVAL;
58817 + if (IS_ERR_OR_NULL(dev->pm_domain))
58818 + return -EINVAL;
58820 + genpd = pd_to_genpd(dev->pm_domain);
58838 + return -EINVAL;
58840 + if (IS_ERR_OR_NULL(dev->pm_domain))
58841 + return -EINVAL;
58843 + genpd = pd_to_genpd(dev->pm_domain);
58856 struct rockchip_pmu *pmu = pd->pmu;
58859 + if (pd->info->repair_status_mask) {
58860 + regmap_read(pmu->regmap, pmu->info->repair_status_offset, &val);
58862 + return val & pd->info->repair_status_mask;
58865 /* check idle status for idle-only domains */
58866 if (pd->info->status_mask == 0)
58868 @@ -260,76 +448,131 @@ static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
58869 return !(val & pd->info->status_mask);
58872 -static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
58873 - bool on)
58877 struct rockchip_pmu *pmu = pd->pmu;
58878 struct generic_pm_domain *genpd = &pd->genpd;
58883 + if (pd->info->pwr_offset)
58884 + pd_pwr_offset = pd->info->pwr_offset;
58886 if (pd->info->pwr_mask == 0)
58887 - return;
58889 else if (pd->info->pwr_w_mask)
58890 - regmap_write(pmu->regmap, pmu->info->pwr_offset,
58891 + regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset,
58892 on ? pd->info->pwr_w_mask :
58893 (pd->info->pwr_mask | pd->info->pwr_w_mask));
58895 - regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
58896 - pd->info->pwr_mask, on ? 0 : -1U);
58897 + regmap_update_bits(pmu->regmap, pmu->info->pwr_offset +
58898 + pd_pwr_offset, pd->info->pwr_mask,
58899 + on ? 0 : -1U);
58903 - if (readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
58904 - is_on == on, 0, 10000)) {
58908 dev_err(pmu->dev,
58909 - "failed to set domain '%s', val=%d\n",
58910 - genpd->name, is_on);
58911 - return;
58913 + genpd->name, on, is_on);
58925 struct rockchip_pmu *pmu = pd->pmu;
58926 - int ret;
58928 + struct generic_pm_domain *genpd = &pd->genpd;
58930 - mutex_lock(&pmu->mutex);
58937 + if (IS_ERR_OR_NULL(pd->supply) &&
58938 + PTR_ERR(pd->supply) != -ENODEV)
58939 + pd->supply = devm_regulator_get_optional(pd->pmu->dev,
58940 + genpd->name);
58942 + if (power_on && !IS_ERR(pd->supply)) {
58943 + ret = regulator_enable(pd->supply);
58945 + dev_err(pd->pmu->dev, "failed to set vdd supply enable '%s',\n",
58946 + genpd->name);
58952 ret = clk_bulk_enable(pd->num_clks, pd->clks);
58954 dev_err(pmu->dev, "failed to enable clocks\n");
58955 - mutex_unlock(&pmu->mutex);
58962 + pd->is_qos_saved = true;
58965 - rockchip_pmu_set_idle_request(pd, true);
58968 + dev_err(pd->pmu->dev, "failed to set idle request '%s',\n",
58969 + genpd->name);
58974 - rockchip_do_pmu_set_power_domain(pd, power_on);
58977 + dev_err(pd->pmu->dev, "failed to set power '%s' = %d,\n",
58978 + genpd->name, power_on);
58984 - rockchip_pmu_set_idle_request(pd, false);
58987 + dev_err(pd->pmu->dev, "failed to set deidle request '%s',\n",
58988 + genpd->name);
58992 - rockchip_pmu_restore_qos(pd);
58993 + if (pd->is_qos_saved)
58998 clk_bulk_disable(pd->num_clks, pd->clks);
59000 + if (!power_on && !IS_ERR(pd->supply))
59001 + ret = regulator_disable(pd->supply);
59004 - mutex_unlock(&pmu->mutex);
59005 - return 0;
59014 + if (pd->is_ignore_pwr)
59020 @@ -337,9 +580,71 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain)
59024 + if (pd->is_ignore_pwr)
59036 + return -EINVAL;
59038 + if (IS_ERR_OR_NULL(dev->pm_domain))
59039 + return -EINVAL;
59041 + genpd = pd_to_genpd(dev->pm_domain);
59054 + return -EINVAL;
59056 + if (IS_ERR_OR_NULL(dev->pm_domain))
59057 + return -EINVAL;
59059 + genpd = pd_to_genpd(dev->pm_domain);
59075 + if (IS_ERR_OR_NULL(dev->pm_domain))
59078 + genpd = pd_to_genpd(dev->pm_domain);
59092 @@ -378,15 +683,58 @@ static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
59105 + for (i = 0; i < pd->num_qos; i++) {
59107 + regmap_write(pd->qos_regmap[i],
59109 + pd->qos_save_regs[0][i]);
59112 + regmap_write(pd->qos_regmap[i],
59114 + pd->qos_save_regs[1][i]);
59117 + regmap_write(pd->qos_regmap[i],
59119 + pd->qos_save_regs[2][i]);
59122 + regmap_write(pd->qos_regmap[i],
59124 + pd->qos_save_regs[3][i]);
59127 + regmap_write(pd->qos_regmap[i],
59129 + pd->qos_save_regs[4][i]);
59144 - u32 id;
59152 @@ -401,6 +749,8 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59154 return -EINVAL;
59156 + if (pmu->genpd_data.domains[id])
59159 pd_info = &pmu->info->domain_info[id];
59161 @@ -415,6 +765,8 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59163 pd->info = pd_info;
59164 pd->pmu = pmu;
59165 + if (!pd_info->pwr_mask)
59166 + pd->is_ignore_pwr = true;
59168 pd->num_clks = of_clk_get_parent_count(node);
59169 if (pd->num_clks > 0) {
59170 @@ -443,8 +795,14 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59174 - pd->num_qos = of_count_phandle_with_args(node, "pm_qos",
59175 - NULL);
59181 + pd->num_qos++;
59185 if (pd->num_qos > 0) {
59186 pd->qos_regmap = devm_kcalloc(pmu->dev, pd->num_qos,
59187 @@ -455,55 +813,127 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
59191 - for (j = 0; j < MAX_QOS_REGS_NUM; j++) {
59192 - pd->qos_save_regs[j] = devm_kcalloc(pmu->dev,
59193 - pd->num_qos,
59194 - sizeof(u32),
59195 - GFP_KERNEL);
59196 - if (!pd->qos_save_regs[j]) {
59197 - error = -ENOMEM;
59198 - goto err_unprepare_clocks;
59199 - }
59200 + pd->qos_save_regs[0] = (u32 *)devm_kmalloc(pmu->dev,
59203 + pd->num_qos,
59205 + if (!pd->qos_save_regs[0]) {
59206 + error = -ENOMEM;
59211 + pd->num_qos,
59214 + error = -ENOMEM;
59218 + pd->qos_save_regs[i] = pd->qos_save_regs[i - 1] +
59220 + qos_is_need_init[i] = qos_is_need_init[i - 1] + num_qos;
59223 - for (j = 0; j < pd->num_qos; j++) {
59227 error = -ENODEV;
59230 - pd->qos_regmap[j] = syscon_node_to_regmap(qos_node);
59231 - if (IS_ERR(pd->qos_regmap[j])) {
59232 - error = -ENODEV;
59233 - of_node_put(qos_node);
59234 - goto err_unprepare_clocks;
59236 + pd->qos_regmap[num_qos_reg] =
59238 + if (IS_ERR(pd->qos_regmap[num_qos_reg])) {
59239 + error = -ENODEV;
59244 + "priority-init",
59246 + pd->qos_save_regs[0][j] = val;
59252 + "mode-init",
59254 + pd->qos_save_regs[1][j] = val;
59260 + "bandwidth-init",
59262 + pd->qos_save_regs[2][j] = val;
59268 + "saturation-init",
59270 + pd->qos_save_regs[3][j] = val;
59276 + "extcontrol-init",
59278 + pd->qos_save_regs[4][j] = val;
59286 + if (num_qos_reg > pd->num_qos)
59291 - error = rockchip_pd_power(pd, true);
59292 - if (error) {
59293 - dev_err(pmu->dev,
59294 - "failed to power on domain '%pOFn': %d\n",
59295 - node, error);
59296 - goto err_unprepare_clocks;
59297 - }
59298 -
59299 - pd->genpd.name = node->name;
59300 + if (pd->info->name)
59301 + pd->genpd.name = pd->info->name;
59303 + pd->genpd.name = kbasename(node->full_name);
59304 pd->genpd.power_off = rockchip_pd_power_off;
59305 pd->genpd.power_on = rockchip_pd_power_on;
59306 pd->genpd.attach_dev = rockchip_pd_attach_dev;
59307 pd->genpd.detach_dev = rockchip_pd_detach_dev;
59308 - pd->genpd.flags = GENPD_FLAG_PM_CLK;
59309 if (pd_info->active_wakeup)
59310 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
59311 - pm_genpd_init(&pd->genpd, NULL, false);
59313 + if (pd_info->keepon_startup) {
59314 + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
59318 + dev_err(pmu->dev,
59320 + node->name, error);
59331 + pm_genpd_init(&pd->genpd, NULL, !rockchip_pmu_domain_is_on(pd));
59333 pmu->genpd_data.domains[id] = &pd->genpd;
59338 clk_bulk_unprepare(pd->num_clks, pd->clks);
59340 clk_bulk_put(pd->num_clks, pd->clks);
59341 @@ -527,9 +957,9 @@ static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
59342 clk_bulk_put(pd->num_clks, pd->clks);
59344 /* protect the zeroing of pm->num_clks */
59345 - mutex_lock(&pd->pmu->mutex);
59347 pd->num_clks = 0;
59348 - mutex_unlock(&pd->pmu->mutex);
59353 @@ -566,6 +996,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
59361 @@ -606,6 +1037,17 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
59362 parent_domain->name, child_domain->name);
59373 + if (!parent_pd->is_ignore_pwr)
59374 + child_pd->is_ignore_pwr = false;
59379 @@ -616,6 +1058,75 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
59390 + pd->genpd.flags &= (~GENPD_FLAG_ALWAYS_ON);
59391 + list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
59392 + if (!atomic_read(&pm_data->dev->power.usage_count)) {
59394 + if (!pm_runtime_enabled(pm_data->dev)) {
59395 + pm_runtime_enable(pm_data->dev);
59398 + pm_runtime_get_sync(pm_data->dev);
59399 + pm_runtime_put_sync(pm_data->dev);
59401 + pm_runtime_disable(pm_data->dev);
59415 + for (i = 0; i < g_pmu->genpd_data.num_domains; i++) {
59416 + genpd = g_pmu->genpd_data.domains[i];
59419 + if (pd->info->keepon_startup)
59454 struct device *dev = &pdev->dev;
59455 @@ -626,6 +1137,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59463 @@ -666,6 +1178,14 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59464 return PTR_ERR(pmu->regmap);
59467 + reg_base = of_iomap(parent->of_node, 0);
59470 + return -ENOMEM;
59478 @@ -708,6 +1228,10 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59489 @@ -716,129 +1240,129 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
59493 - [PX30_PD_USB] = DOMAIN_PX30(BIT(5), BIT(5), BIT(10), false),
59494 - [PX30_PD_SDCARD] = DOMAIN_PX30(BIT(8), BIT(8), BIT(9), false),
59495 - [PX30_PD_GMAC] = DOMAIN_PX30(BIT(10), BIT(10), BIT(6), false),
59496 - [PX30_PD_MMC_NAND] = DOMAIN_PX30(BIT(11), BIT(11), BIT(5), false),
59497 - [PX30_PD_VPU] = DOMAIN_PX30(BIT(12), BIT(12), BIT(14), false),
59498 - [PX30_PD_VO] = DOMAIN_PX30(BIT(13), BIT(13), BIT(7), false),
59499 - [PX30_PD_VI] = DOMAIN_PX30(BIT(14), BIT(14), BIT(8), false),
59500 - [PX30_PD_GPU] = DOMAIN_PX30(BIT(15), BIT(15), BIT(2), false),
59512 - [RK3036_PD_MSCH] = DOMAIN_RK3036(BIT(14), BIT(23), BIT(30), true),
59513 - [RK3036_PD_CORE] = DOMAIN_RK3036(BIT(13), BIT(17), BIT(24), false),
59514 - [RK3036_PD_PERI] = DOMAIN_RK3036(BIT(12), BIT(18), BIT(25), false),
59515 - [RK3036_PD_VIO] = DOMAIN_RK3036(BIT(11), BIT(19), BIT(26), false),
59516 - [RK3036_PD_VPU] = DOMAIN_RK3036(BIT(10), BIT(20), BIT(27), false),
59517 - [RK3036_PD_GPU] = DOMAIN_RK3036(BIT(9), BIT(21), BIT(28), false),
59518 - [RK3036_PD_SYS] = DOMAIN_RK3036(BIT(8), BIT(22), BIT(29), false),
59529 - [RK3066_PD_GPU] = DOMAIN(BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
59530 - [RK3066_PD_VIDEO] = DOMAIN(BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
59531 - [RK3066_PD_VIO] = DOMAIN(BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
59532 - [RK3066_PD_PERI] = DOMAIN(BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
59533 - [RK3066_PD_CPU] = DOMAIN(0, BIT(5), BIT(1), BIT(26), BIT(31), false),
59542 - [RK3128_PD_CORE] = DOMAIN_RK3288(BIT(0), BIT(0), BIT(4), false),
59543 - [RK3128_PD_MSCH] = DOMAIN_RK3288(0, 0, BIT(6), true),
59544 - [RK3128_PD_VIO] = DOMAIN_RK3288(BIT(3), BIT(3), BIT(2), false),
59545 - [RK3128_PD_VIDEO] = DOMAIN_RK3288(BIT(2), BIT(2), BIT(1), false),
59546 - [RK3128_PD_GPU] = DOMAIN_RK3288(BIT(1), BIT(1), BIT(3), false),
59555 - [RK3188_PD_GPU] = DOMAIN(BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
59556 - [RK3188_PD_VIDEO] = DOMAIN(BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
59557 - [RK3188_PD_VIO] = DOMAIN(BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
59558 - [RK3188_PD_PERI] = DOMAIN(BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
59559 - [RK3188_PD_CPU] = DOMAIN(BIT(5), BIT(5), BIT(1), BIT(26), BIT(31), false),
59568 - [RK3228_PD_CORE] = DOMAIN_RK3036(BIT(0), BIT(0), BIT(16), true),
59569 - [RK3228_PD_MSCH] = DOMAIN_RK3036(BIT(1), BIT(1), BIT(17), true),
59570 - [RK3228_PD_BUS] = DOMAIN_RK3036(BIT(2), BIT(2), BIT(18), true),
59571 - [RK3228_PD_SYS] = DOMAIN_RK3036(BIT(3), BIT(3), BIT(19), true),
59572 - [RK3228_PD_VIO] = DOMAIN_RK3036(BIT(4), BIT(4), BIT(20), false),
59573 - [RK3228_PD_VOP] = DOMAIN_RK3036(BIT(5), BIT(5), BIT(21), false),
59574 - [RK3228_PD_VPU] = DOMAIN_RK3036(BIT(6), BIT(6), BIT(22), false),
59575 - [RK3228_PD_RKVDEC] = DOMAIN_RK3036(BIT(7), BIT(7), BIT(23), false),
59576 - [RK3228_PD_GPU] = DOMAIN_RK3036(BIT(8), BIT(8), BIT(24), false),
59577 - [RK3228_PD_PERI] = DOMAIN_RK3036(BIT(9), BIT(9), BIT(25), true),
59578 - [RK3228_PD_GMAC] = DOMAIN_RK3036(BIT(10), BIT(10), BIT(26), false),
59593 - [RK3288_PD_VIO] = DOMAIN_RK3288(BIT(7), BIT(7), BIT(4), false),
59594 - [RK3288_PD_HEVC] = DOMAIN_RK3288(BIT(14), BIT(10), BIT(9), false),
59595 - [RK3288_PD_VIDEO] = DOMAIN_RK3288(BIT(8), BIT(8), BIT(3), false),
59596 - [RK3288_PD_GPU] = DOMAIN_RK3288(BIT(9), BIT(9), BIT(2), false),
59604 - [RK3328_PD_CORE] = DOMAIN_RK3328(0, BIT(0), BIT(0), false),
59605 - [RK3328_PD_GPU] = DOMAIN_RK3328(0, BIT(1), BIT(1), false),
59606 - [RK3328_PD_BUS] = DOMAIN_RK3328(0, BIT(2), BIT(2), true),
59607 - [RK3328_PD_MSCH] = DOMAIN_RK3328(0, BIT(3), BIT(3), true),
59608 - [RK3328_PD_PERI] = DOMAIN_RK3328(0, BIT(4), BIT(4), true),
59609 - [RK3328_PD_VIDEO] = DOMAIN_RK3328(0, BIT(5), BIT(5), false),
59610 - [RK3328_PD_HEVC] = DOMAIN_RK3328(0, BIT(6), BIT(6), false),
59611 - [RK3328_PD_VIO] = DOMAIN_RK3328(0, BIT(8), BIT(8), false),
59612 - [RK3328_PD_VPU] = DOMAIN_RK3328(0, BIT(9), BIT(9), false),
59625 - [RK3366_PD_PERI] = DOMAIN_RK3368(BIT(10), BIT(10), BIT(6), true),
59626 - [RK3366_PD_VIO] = DOMAIN_RK3368(BIT(14), BIT(14), BIT(8), false),
59627 - [RK3366_PD_VIDEO] = DOMAIN_RK3368(BIT(13), BIT(13), BIT(7), false),
59628 - [RK3366_PD_RKVDEC] = DOMAIN_RK3368(BIT(11), BIT(11), BIT(7), false),
59629 - [RK3366_PD_WIFIBT] = DOMAIN_RK3368(BIT(8), BIT(8), BIT(9), false),
59630 - [RK3366_PD_VPU] = DOMAIN_RK3368(BIT(12), BIT(12), BIT(7), false),
59631 - [RK3366_PD_GPU] = DOMAIN_RK3368(BIT(15), BIT(15), BIT(2), false),
59642 - [RK3368_PD_PERI] = DOMAIN_RK3368(BIT(13), BIT(12), BIT(6), true),
59643 - [RK3368_PD_VIO] = DOMAIN_RK3368(BIT(15), BIT(14), BIT(8), false),
59644 - [RK3368_PD_VIDEO] = DOMAIN_RK3368(BIT(14), BIT(13), BIT(7), false),
59645 - [RK3368_PD_GPU_0] = DOMAIN_RK3368(BIT(16), BIT(15), BIT(2), false),
59646 - [RK3368_PD_GPU_1] = DOMAIN_RK3368(BIT(17), BIT(16), BIT(2), false),
59655 - [RK3399_PD_TCPD0] = DOMAIN_RK3399(BIT(8), BIT(8), 0, false),
59656 - [RK3399_PD_TCPD1] = DOMAIN_RK3399(BIT(9), BIT(9), 0, false),
59657 - [RK3399_PD_CCI] = DOMAIN_RK3399(BIT(10), BIT(10), 0, true),
59658 - [RK3399_PD_CCI0] = DOMAIN_RK3399(0, 0, BIT(15), true),
59659 - [RK3399_PD_CCI1] = DOMAIN_RK3399(0, 0, BIT(16), true),
59660 - [RK3399_PD_PERILP] = DOMAIN_RK3399(BIT(11), BIT(11), BIT(1), true),
59661 - [RK3399_PD_PERIHP] = DOMAIN_RK3399(BIT(12), BIT(12), BIT(2), true),
59662 - [RK3399_PD_CENTER] = DOMAIN_RK3399(BIT(13), BIT(13), BIT(14), true),
59663 - [RK3399_PD_VIO] = DOMAIN_RK3399(BIT(14), BIT(14), BIT(17), false),
59664 - [RK3399_PD_GPU] = DOMAIN_RK3399(BIT(15), BIT(15), BIT(0), false),
59665 - [RK3399_PD_VCODEC] = DOMAIN_RK3399(BIT(16), BIT(16), BIT(3), false),
59666 - [RK3399_PD_VDU] = DOMAIN_RK3399(BIT(17), BIT(17), BIT(4), false),
59667 - [RK3399_PD_RGA] = DOMAIN_RK3399(BIT(18), BIT(18), BIT(5), false),
59668 - [RK3399_PD_IEP] = DOMAIN_RK3399(BIT(19), BIT(19), BIT(6), false),
59669 - [RK3399_PD_VO] = DOMAIN_RK3399(BIT(20), BIT(20), 0, false),
59670 - [RK3399_PD_VOPB] = DOMAIN_RK3399(0, 0, BIT(7), false),
59671 - [RK3399_PD_VOPL] = DOMAIN_RK3399(0, 0, BIT(8), false),
59672 - [RK3399_PD_ISP0] = DOMAIN_RK3399(BIT(22), BIT(22), BIT(9), false),
59673 - [RK3399_PD_ISP1] = DOMAIN_RK3399(BIT(23), BIT(23), BIT(10), false),
59674 - [RK3399_PD_HDCP] = DOMAIN_RK3399(BIT(24), BIT(24), BIT(11), false),
59675 - [RK3399_PD_GMAC] = DOMAIN_RK3399(BIT(25), BIT(25), BIT(23), true),
59676 - [RK3399_PD_EMMC] = DOMAIN_RK3399(BIT(26), BIT(26), BIT(24), true),
59677 - [RK3399_PD_USB3] = DOMAIN_RK3399(BIT(27), BIT(27), BIT(12), true),
59678 - [RK3399_PD_EDP] = DOMAIN_RK3399(BIT(28), BIT(28), BIT(22), false),
59679 - [RK3399_PD_GIC] = DOMAIN_RK3399(BIT(29), BIT(29), BIT(27), true),
59680 - [RK3399_PD_SD] = DOMAIN_RK3399(BIT(30), BIT(30), BIT(28), true),
59681 - [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(BIT(31), BIT(31), BIT(29), true),
59712 @@ -1023,6 +1547,7 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
59720 @@ -1043,3 +1568,12 @@ static int __init rockchip_pm_domain_drv_register(void)
59733 diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
59735 --- a/drivers/spi/spi-rockchip.c
59736 +++ b/drivers/spi/spi-rockchip.c
59737 @@ -10,6 +10,7 @@
59745 @@ -107,6 +108,8 @@
59754 @@ -116,13 +119,14 @@
59758 -/* Bit fields in SR, 5bit */
59759 -#define SR_MASK 0x1f
59771 @@ -130,7 +134,8 @@
59775 -#define INT_RF_FULL (1 << 4)
59781 @@ -149,6 +154,8 @@
59789 * SPI_CTRLR1 is 16-bits, so we should support lengths of 0xffff + 1. However,
59790 @@ -156,7 +163,8 @@
59794 -#define ROCKCHIP_SPI_MAX_CS_NUM 2
59795 +/* 2 for native cs, 2 for cs-gpio */
59800 @@ -187,7 +195,10 @@ struct rockchip_spi {
59811 @@ -195,13 +206,19 @@ static inline void spi_enable_chip(struct rockchip_spi *rs, bool enable)
59812 writel_relaxed((enable ? 1U : 0U), rs->regs + ROCKCHIP_SPI_SSIENR);
59815 -static inline void wait_for_idle(struct rockchip_spi *rs)
59821 - if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
59822 - return;
59824 + if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_SLAVE_TX_BUSY) &&
59825 + !((readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)))
59828 + if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
59833 dev_warn(rs->dev, "spi controller is in busy state!\n");
59834 @@ -226,7 +243,7 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
59836 struct spi_controller *ctlr = spi->controller;
59838 - bool cs_asserted = !enable;
59839 + bool cs_asserted = spi->mode & SPI_CS_HIGH ? enable : !enable;
59841 /* Return immediately for no-op */
59842 if (cs_asserted == rs->cs_asserted[spi->chip_select])
59843 @@ -236,11 +253,15 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
59845 pm_runtime_get_sync(rs->dev);
59847 - ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER,
59848 - BIT(spi->chip_select));
59849 + if (spi->cs_gpiod)
59850 + ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
59852 + ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
59854 - ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER,
59855 - BIT(spi->chip_select));
59856 + if (spi->cs_gpiod)
59857 + ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
59859 + ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
59862 pm_runtime_put(rs->dev);
59863 @@ -327,6 +348,15 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
59868 + if (rs->cs_inactive && readl_relaxed(rs->regs + ROCKCHIP_SPI_IMR) & INT_CS_INACTIVE) {
59869 + ctlr->slave_abort(ctlr);
59870 + writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
59871 + writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
59876 if (rs->tx_left)
59879 @@ -334,6 +364,7 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
59880 if (!rs->rx_left) {
59882 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
59883 + writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
59887 @@ -341,14 +372,18 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
59891 - struct spi_transfer *xfer)
59895 rs->tx = xfer->tx_buf;
59896 rs->rx = xfer->rx_buf;
59897 rs->tx_left = rs->tx ? xfer->len / rs->n_bytes : 0;
59898 rs->rx_left = xfer->len / rs->n_bytes;
59900 - writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
59901 + if (rs->cs_inactive)
59902 + writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
59904 + writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
59907 if (rs->tx_left)
59908 @@ -367,6 +402,9 @@ static void rockchip_spi_dma_rxcb(void *data)
59909 if (state & TXDMA && !rs->slave_abort)
59912 + if (rs->cs_inactive)
59913 + writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
59918 @@ -381,7 +419,7 @@ static void rockchip_spi_dma_txcb(void *data)
59922 - wait_for_idle(rs);
59923 + wait_for_tx_idle(rs, ctlr->slave);
59927 @@ -407,14 +445,16 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs,
59929 atomic_set(&rs->state, 0);
59931 + rs->tx = xfer->tx_buf;
59932 + rs->rx = xfer->rx_buf;
59935 if (xfer->rx_buf) {
59938 .src_addr = rs->dma_addr_rx,
59939 .src_addr_width = rs->n_bytes,
59940 - .src_maxburst = rockchip_spi_calc_burst_size(xfer->len /
59941 - rs->n_bytes),
59942 + .src_maxburst = rockchip_spi_calc_burst_size(xfer->len / rs->n_bytes),
59945 dmaengine_slave_config(ctlr->dma_rx, &rxconf);
59946 @@ -458,10 +498,13 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs,
59949 atomic_or(RXDMA, &rs->state);
59950 - dmaengine_submit(rxdesc);
59951 + ctlr->dma_rx->cookie = dmaengine_submit(rxdesc);
59952 dma_async_issue_pending(ctlr->dma_rx);
59955 + if (rs->cs_inactive)
59956 + writel_relaxed(INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
59961 @@ -493,6 +536,8 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
59962 cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET;
59963 if (spi->mode & SPI_LSB_FIRST)
59965 + if (spi->mode & SPI_CS_HIGH)
59966 + cr0 |= BIT(spi->chip_select) << CR0_SOI_OFFSET;
59968 if (xfer->rx_buf && xfer->tx_buf)
59970 @@ -531,6 +576,19 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
59978 + if (rs->high_speed_state) {
59979 + if (rs->freq > IO_DRIVER_4MA_MAX_SCLK_OUT)
59980 + pinctrl_select_state(rs->dev->pins->p,
59981 + rs->high_speed_state);
59983 + pinctrl_select_state(rs->dev->pins->p,
59984 + rs->dev->pins->default_state);
59987 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
59988 writel_relaxed(cr1, rs->regs + ROCKCHIP_SPI_CTRLR1);
59990 @@ -538,12 +596,12 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
59994 - if (xfer->len < rs->fifo_len)
59995 - writel_relaxed(xfer->len - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
59996 + if ((xfer->len / rs->n_bytes) < rs->fifo_len)
59997 + writel_relaxed(xfer->len / rs->n_bytes - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
59999 writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
60001 - writel_relaxed(rs->fifo_len / 2, rs->regs + ROCKCHIP_SPI_DMATDLR);
60002 + writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_DMATDLR);
60003 writel_relaxed(rockchip_spi_calc_burst_size(xfer->len / rs->n_bytes) - 1,
60004 rs->regs + ROCKCHIP_SPI_DMARDLR);
60005 writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR);
60006 @@ -566,12 +624,45 @@ static size_t rockchip_spi_max_transfer_size(struct spi_device *spi)
60010 -
60011 - if (atomic_read(&rs->state) & RXDMA)
60017 + if (atomic_read(&rs->state) & RXDMA) {
60018 + dmaengine_pause(ctlr->dma_rx);
60019 + status = dmaengine_tx_status(ctlr->dma_rx, ctlr->dma_rx->cookie, &state);
60020 dmaengine_terminate_sync(ctlr->dma_rx);
60021 - if (atomic_read(&rs->state) & TXDMA)
60022 - dmaengine_terminate_sync(ctlr->dma_tx);
60023 - atomic_set(&rs->state, 0);
60024 + atomic_set(&rs->state, 0);
60026 + rs->rx = rs->xfer->rx_buf;
60027 + rs->xfer->len = 0;
60028 + rx_fifo_left = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
60029 + for (; rx_fifo_left; rx_fifo_left--)
60030 + readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
60033 + rs->rx += rs->xfer->len - rs->n_bytes * state.residue;
60037 + /* Get the valid data left in rx fifo and set rs->xfer->len real rx size */
60038 + if (rs->rx) {
60039 + rx_fifo_left = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
60040 + for (; rx_fifo_left; rx_fifo_left--) {
60041 + u32 rxw = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
60043 + if (rs->n_bytes == 1)
60044 + *(u8 *)rs->rx = (u8)rxw;
60046 + *(u16 *)rs->rx = (u16)rxw;
60047 + rs->rx += rs->n_bytes;
60050 + rs->xfer->len = (unsigned int)(rs->rx - rs->xfer->rx_buf);
60055 rs->slave_abort = true;
60056 complete(&ctlr->xfer_completion);
60057 @@ -588,12 +679,6 @@ static int rockchip_spi_transfer_one(
60061 - /* Zero length transfers won't trigger an interrupt on completion */
60062 - if (!xfer->len) {
60063 - spi_finalize_current_transfer(ctlr);
60064 - return 1;
60065 - }
60066 -
60067 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
60068 (readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY));
60070 @@ -608,7 +693,7 @@ static int rockchip_spi_transfer_one(
60073 rs->n_bytes = xfer->bits_per_word <= 8 ? 1 : 2;
60074 -
60075 + rs->xfer = xfer;
60076 use_dma = ctlr->can_dma ? ctlr->can_dma(ctlr, spi, xfer) : false;
60078 ret = rockchip_spi_config(rs, spi, xfer, use_dma, ctlr->slave);
60079 @@ -618,7 +703,7 @@ static int rockchip_spi_transfer_one(
60083 - return rockchip_spi_prepare_irq(rs, xfer);
60088 @@ -642,8 +727,9 @@ static int rockchip_spi_probe(struct platform_device *pdev)
60091 struct device_node *np = pdev->dev.of_node;
60092 - u32 rsd_nsecs, num_cs;
60097 slave_mode = of_property_read_bool(np, "spi-slave");
60099 @@ -750,9 +836,8 @@ static int rockchip_spi_probe(struct platform_device *pdev)
60101 * if num-cs is missing in the dts, default to 1
60103 - if (of_property_read_u32(np, "num-cs", &num_cs))
60104 - num_cs = 1;
60105 - ctlr->num_chipselect = num_cs;
60106 + if (of_property_read_u16(np, "num-cs", &ctlr->num_chipselect))
60107 + ctlr->num_chipselect = 1;
60108 ctlr->use_gpio_descriptors = true;
60110 ctlr->dev.of_node = pdev->dev.of_node;
60111 @@ -792,6 +877,28 @@ static int rockchip_spi_probe(struct platform_device *pdev)
60112 ctlr->can_dma = rockchip_spi_can_dma;
60115 + switch (readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION)) {
60117 + ctlr->mode_bits |= SPI_CS_HIGH;
60118 + if (ctlr->can_dma && slave_mode)
60119 + rs->cs_inactive = true;
60121 + rs->cs_inactive = false;
60124 + rs->cs_inactive = false;
60128 + pinctrl = devm_pinctrl_get(&pdev->dev);
60130 + rs->high_speed_state = pinctrl_lookup_state(pinctrl, "high_speed");
60131 + if (IS_ERR_OR_NULL(rs->high_speed_state)) {
60132 + dev_warn(&pdev->dev, "no high_speed pinctrl state\n");
60133 + rs->high_speed_state = NULL;
60137 ret = devm_spi_register_controller(&pdev->dev, ctlr);
60139 dev_err(&pdev->dev, "Failed to register controller\n");
60140 diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
60142 --- a/drivers/spi/spidev.c
60144 @@ -682,6 +682,7 @@ static const struct of_device_id spidev_dt_ids[] = {
60146 { .compatible = "dh,dhcom-board" },
60152 diff --git a/drivers/staging/blackbox/Kconfig b/drivers/staging/blackbox/Kconfig
60154 --- a/drivers/staging/blackbox/Kconfig
60156 @@ -106,3 +106,14 @@ config DEF_BLACKBOX_STORAGE
60171 diff --git a/drivers/staging/blackbox/Makefile b/drivers/staging/blackbox/Makefile
60173 --- a/drivers/staging/blackbox/Makefile
60175 @@ -3,3 +3,5 @@
60176 obj-$(CONFIG_BLACKBOX) += blackbox_core.o \
60180 +obj-$(CONFIG_BLACKBOX_ROCKCHIP) += ../../$(VENDOR_DRIVER_DIR)/staging/blackbox/rockchip/
60181 diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
60183 --- a/drivers/thermal/rockchip_thermal.c
60185 @@ -18,6 +18,7 @@
60189 +#include <linux/nvmem-consumer.h>
60193 @@ -26,7 +27,7 @@
60197 - TSHUT_MODE_GPIO,
60202 @@ -71,12 +72,17 @@ enum adc_sort_mode {
60220 @@ -94,6 +100,8 @@ struct chip_tsadc_table {
60222 * @set_tshut_temp: set the hardware-controlled shutdown temperature
60223 * @set_tshut_mode: set the hardware-controlled shutdown mode
60226 * @table: the chip-specific conversion table
60229 @@ -119,7 +127,11 @@ struct rockchip_tsadc_chip {
60233 - void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m);
60240 /* Per-table methods */
60242 @@ -143,13 +155,18 @@ struct rockchip_thermal_sensor {
60246 - * @clk: the controller clock is divided by the exteral 24MHz
60247 - * @pclk: the advanced peripherals bus clock
60252 * @tshut_temp: the hardware-controlled shutdown temperature value
60254 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
60255 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
60257 + * @gpio_state: pinctrl select gpio function
60258 + * @otp_state: pinctrl select otp out function
60263 @@ -158,15 +175,21 @@ struct rockchip_thermal_data {
60267 - struct clk *clk;
60268 - struct clk *pclk;
60287 @@ -210,8 +233,11 @@ struct rockchip_thermal_data {
60299 @@ -219,13 +245,33 @@ struct rockchip_thermal_data {
60325 +#define MIN_TEMP (-40000)
60326 +#define LOWEST_TEMP (-273000)
60331 * struct tsadc_table - code to temperature conversion table
60333 @@ -241,6 +287,7 @@ struct tsadc_table {
60339 {0, -40000},
60340 {374, -40000},
60341 @@ -280,6 +327,45 @@ static const struct tsadc_table rv1108_table[] = {
60346 + {0, -40000},
60347 + {3455, -40000},
60348 + {3463, -35000},
60349 + {3471, -30000},
60350 + {3479, -25000},
60351 + {3487, -20000},
60352 + {3495, -15000},
60353 + {3503, -10000},
60354 + {3511, -5000},
60385 {0, -40000},
60386 {588, -40000},
60387 @@ -474,6 +560,45 @@ static const struct tsadc_table rk3399_code_table[] = {
60392 + {0, -40000},
60393 + {1584, -40000},
60394 + {1620, -35000},
60395 + {1652, -30000},
60396 + {1688, -25000},
60397 + {1720, -20000},
60398 + {1756, -15000},
60399 + {1788, -10000},
60400 + {1824, -5000},
60433 @@ -482,6 +607,9 @@ static u32 rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table,
60435 u32 error = table->data_mask;
60437 + if (table->kNum)
60438 + return (((temp / 1000) * table->kNum) / 1000 + table->bNum);
60441 high = (table->length - 1) - 1; /* ignore the last check for table */
60443 @@ -535,6 +663,13 @@ static int rk_tsadcv2_code_to_temp(const struct chip_tsadc_table *table,
60447 + if (table->kNum) {
60448 + *temp = (((int)code - table->bNum) * 10000 / table->kNum) * 100;
60450 + return -EAGAIN;
60454 WARN_ON(table->length < 2);
60456 switch (table->mode) {
60457 @@ -701,6 +836,70 @@ static void rk_tsadcv4_initialize(struct regmap *grf, void __iomem *regs,
60528 @@ -815,23 +1014,69 @@ static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table,
60532 -static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
60558 - if (mode == TSHUT_MODE_GPIO) {
60580 + const struct chip_tsadc_table *table = &thermal->chip->table;
60584 + base_code = trim_base * table->kNum / 1000 + table->bNum;
60585 + trim_code = code - base_code - 10;
60594 + return thermal->trim * 500;
60600 @@ -860,7 +1105,7 @@ static const struct rockchip_tsadc_chip rv1108_tsadc_data = {
60604 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60609 @@ -880,11 +1125,61 @@ static const struct rockchip_tsadc_chip rv1108_tsadc_data = {
60667 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60672 @@ -909,7 +1204,7 @@ static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
60676 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60681 @@ -957,7 +1252,7 @@ static const struct rockchip_tsadc_chip rk3366_tsadc_data = {
60685 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60690 @@ -982,7 +1277,7 @@ static const struct rockchip_tsadc_chip rk3368_tsadc_data = {
60694 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60699 @@ -1007,7 +1302,7 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
60703 - .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
60708 @@ -1027,6 +1322,31 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
60738 { .compatible = "rockchip,px30-tsadc",
60740 @@ -1035,6 +1355,14 @@ static const struct of_device_id of_rockchip_thermal_match[] = {
60741 .compatible = "rockchip,rv1108-tsadc",
60745 + .compatible = "rockchip,rv1126-tsadc",
60749 + .compatible = "rockchip,rk1808-tsadc",
60753 .compatible = "rockchip,rk3228-tsadc",
60755 @@ -1059,6 +1387,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = {
60756 .compatible = "rockchip,rk3399-tsadc",
60760 + .compatible = "rockchip,rk3568-tsadc",
60766 @@ -1099,6 +1431,9 @@ static int rockchip_thermal_set_trips(void *_sensor, int low, int high)
60767 dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n",
60768 __func__, sensor->id, low, high);
60770 + if (tsadc->trim_temp)
60771 + high += tsadc->trim_temp(thermal->pdev);
60773 return tsadc->set_alarm_temp(&tsadc->table,
60774 sensor->id, thermal->regs, high);
60776 @@ -1112,6 +1447,8 @@ static int rockchip_thermal_get_temp(void *_sensor, int *out_temp)
60778 retval = tsadc->get_temp(&tsadc->table,
60779 sensor->id, thermal->regs, out_temp);
60780 + if (tsadc->trim_temp)
60781 + *out_temp -= tsadc->trim_temp(thermal->pdev);
60782 dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n",
60783 sensor->id, *out_temp, retval);
60785 @@ -1123,11 +1460,52 @@ static const struct thermal_zone_of_device_ops rockchip_of_thermal_ops = {
60791 + if (!IS_ERR(thermal->pinctrl) && !IS_ERR_OR_NULL(thermal->otp_state))
60792 + pinctrl_select_state(thermal->pinctrl,
60793 + thermal->otp_state);
60798 + if (!IS_ERR(thermal->pinctrl) && !IS_ERR_OR_NULL(thermal->gpio_state))
60799 + pinctrl_select_state(thermal->pinctrl,
60800 + thermal->gpio_state);
60832 + const struct rockchip_tsadc_chip *tsadc = thermal->chip;
60836 if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) {
60838 @@ -1146,7 +1524,7 @@ static int rockchip_configure_from_dt(struct device *dev,
60839 if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) {
60842 - thermal->chip->tshut_mode == TSHUT_MODE_GPIO ?
60843 + thermal->chip->tshut_mode == TSHUT_MODE_OTP ?
60845 thermal->tshut_mode = thermal->chip->tshut_mode;
60847 @@ -1183,6 +1561,29 @@ static int rockchip_configure_from_dt(struct device *dev,
60848 if (IS_ERR(thermal->grf))
60851 + if (tsadc->trim_temp && tsadc->get_trim_code) {
60864 + thermal->trim = tsadc->get_trim_code(thermal->pdev,
60869 + thermal->trim);
60870 + thermal->tshut_temp += tsadc->trim_temp(thermal->pdev);
60877 @@ -1195,7 +1596,8 @@ rockchip_thermal_register_sensor(struct platform_device *pdev,
60878 const struct rockchip_tsadc_chip *tsadc = thermal->chip;
60881 - tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);
60882 + tsadc->set_tshut_mode(thermal->grf, id, thermal->regs,
60883 + thermal->tshut_mode);
60885 error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs,
60886 thermal->tshut_temp);
60887 @@ -1228,6 +1630,43 @@ static void rockchip_thermal_reset_controller(struct reset_control *reset)
60899 + pdev = thermal->pdev;
60901 + for (i = 0; i < thermal->chip->chn_num; i++) {
60902 + struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
60903 + struct thermal_zone_device *tz = sensor->tzd;
60905 + if (tz->temperature != THERMAL_TEMP_INVALID)
60906 + dev_warn(&pdev->dev, "channal %d: temperature(%d C)\n",
60907 + i, tz->temperature / 1000);
60910 + if (thermal->regs) {
60913 + 32, 4, thermal->regs, 0x88, false);
60930 struct device_node *np = pdev->dev.of_node;
60931 @@ -1262,40 +1701,26 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
60932 if (IS_ERR(thermal->regs))
60933 return PTR_ERR(thermal->regs);
60935 - thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb");
60936 + thermal->reset = devm_reset_control_array_get(&pdev->dev, false, false);
60937 if (IS_ERR(thermal->reset)) {
60938 - error = PTR_ERR(thermal->reset);
60939 - dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error);
60940 - return error;
60941 - }
60942 -
60943 - thermal->clk = devm_clk_get(&pdev->dev, "tsadc");
60944 - if (IS_ERR(thermal->clk)) {
60945 - error = PTR_ERR(thermal->clk);
60946 - dev_err(&pdev->dev, "failed to get tsadc clock: %d\n", error);
60947 - return error;
60948 + if (PTR_ERR(thermal->reset) != -EPROBE_DEFER)
60949 + dev_err(&pdev->dev, "failed to get tsadc reset lines\n");
60950 + return PTR_ERR(thermal->reset);
60953 - thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
60954 - if (IS_ERR(thermal->pclk)) {
60955 - error = PTR_ERR(thermal->pclk);
60956 - dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n",
60957 - error);
60958 - return error;
60959 - }
60960 + thermal->num_clks = devm_clk_bulk_get_all(&pdev->dev, &thermal->clks);
60961 + if (thermal->num_clks < 1)
60962 + return -ENODEV;
60964 - error = clk_prepare_enable(thermal->clk);
60965 + error = clk_bulk_prepare_enable(thermal->num_clks, thermal->clks);
60967 - dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
60968 + dev_err(&pdev->dev, "failed to prepare enable tsadc bulk clks: %d\n",
60974 - error = clk_prepare_enable(thermal->pclk);
60975 - if (error) {
60976 - dev_err(&pdev->dev, "failed to enable pclk: %d\n", error);
60977 - goto err_disable_clk;
60978 - }
60979 + thermal->chip->control(thermal->regs, false);
60981 rockchip_thermal_reset_controller(thermal->reset);
60983 @@ -1303,12 +1728,30 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
60985 dev_err(&pdev->dev, "failed to parse device tree data: %d\n",
60987 - goto err_disable_pclk;
60991 thermal->chip->initialize(thermal->grf, thermal->regs,
60992 thermal->tshut_polarity);
60994 + if (thermal->tshut_mode == TSHUT_MODE_OTP) {
60995 + thermal->pinctrl = devm_pinctrl_get(&pdev->dev);
60996 + if (IS_ERR(thermal->pinctrl))
60997 + dev_err(&pdev->dev, "failed to find thermal pinctrl\n");
60999 + thermal->gpio_state = pinctrl_lookup_state(thermal->pinctrl,
61001 + if (IS_ERR_OR_NULL(thermal->gpio_state))
61002 + dev_err(&pdev->dev, "failed to find thermal gpio state\n");
61004 + thermal->otp_state = pinctrl_lookup_state(thermal->pinctrl,
61006 + if (IS_ERR_OR_NULL(thermal->otp_state))
61007 + dev_err(&pdev->dev, "failed to find thermal otpout state\n");
61012 for (i = 0; i < thermal->chip->chn_num; i++) {
61014 &thermal->sensors[i],
61015 @@ -1317,7 +1760,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61016 dev_err(&pdev->dev,
61019 - goto err_disable_pclk;
61024 @@ -1328,7 +1771,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61026 dev_err(&pdev->dev,
61028 - goto err_disable_pclk;
61032 thermal->chip->control(thermal->regs, true);
61033 @@ -1343,14 +1786,16 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
61037 - platform_set_drvdata(pdev, thermal);
61038 + thermal->panic_nb.notifier_call = rockchip_thermal_panic;
61040 + &thermal->panic_nb);
61042 + dev_info(&pdev->dev, "tsadc is probed successfully!\n");
61046 -err_disable_pclk:
61047 - clk_disable_unprepare(thermal->pclk);
61048 -err_disable_clk:
61049 - clk_disable_unprepare(thermal->clk);
61051 + clk_bulk_disable_unprepare(thermal->num_clks, thermal->clks);
61055 @@ -1369,12 +1814,28 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
61057 thermal->chip->control(thermal->regs, false);
61059 - clk_disable_unprepare(thermal->pclk);
61060 - clk_disable_unprepare(thermal->clk);
61061 + clk_bulk_disable_unprepare(thermal->num_clks, thermal->clks);
61071 + for (i = 0; i < thermal->chip->chn_num; i++) {
61072 + int id = thermal->sensors[i].id;
61074 + if (thermal->tshut_mode != TSHUT_MODE_CRU)
61075 + thermal->chip->set_tshut_mode(thermal->grf, id,
61076 + thermal->regs,
61079 + if (thermal->tshut_mode == TSHUT_MODE_OTP)
61086 @@ -1385,10 +1846,10 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
61088 thermal->chip->control(thermal->regs, false);
61090 - clk_disable(thermal->pclk);
61091 - clk_disable(thermal->clk);
61092 + clk_bulk_disable(thermal->num_clks, thermal->clks);
61094 - pinctrl_pm_select_sleep_state(dev);
61095 + if (thermal->tshut_mode == TSHUT_MODE_OTP)
61100 @@ -1399,13 +1860,10 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
61104 - error = clk_enable(thermal->clk);
61105 - if (error)
61106 - return error;
61107 -
61108 - error = clk_enable(thermal->pclk);
61109 + error = clk_bulk_enable(thermal->num_clks, thermal->clks);
61111 - clk_disable(thermal->clk);
61117 @@ -1417,7 +1875,7 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
61118 for (i = 0; i < thermal->chip->chn_num; i++) {
61119 int id = thermal->sensors[i].id;
61121 - thermal->chip->set_tshut_mode(id, thermal->regs,
61122 + thermal->chip->set_tshut_mode(thermal->grf, id, thermal->regs,
61123 thermal->tshut_mode);
61125 error = thermal->chip->set_tshut_temp(&thermal->chip->table,
61126 @@ -1433,7 +1891,8 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
61127 for (i = 0; i < thermal->chip->chn_num; i++)
61128 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
61130 - pinctrl_pm_select_default_state(dev);
61131 + if (thermal->tshut_mode == TSHUT_MODE_OTP)
61136 @@ -1449,6 +1908,7 @@ static struct platform_driver rockchip_thermal_driver = {
61144 diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
61146 --- a/drivers/thermal/thermal_core.c
61148 @@ -542,6 +542,7 @@ int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
61156 diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
61158 --- a/drivers/thermal/thermal_core.h
61160 @@ -179,6 +179,4 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz)
61164 -int thermal_zone_device_is_enabled(struct thermal_zone_device *tz);
61165 -
61167 diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
61169 --- a/drivers/tty/serial/8250/8250.h
61171 @@ -48,6 +48,9 @@ struct uart_8250_dma {
61181 @@ -158,6 +161,9 @@ static inline bool serial8250_set_THRI(struct uart_8250_port *up)
61182 if (up->ier & UART_IER_THRI)
61184 up->ier |= UART_IER_THRI;
61186 + up->ier |= UART_IER_PTIME;
61188 serial_out(up, UART_IER, up->ier);
61191 @@ -327,6 +333,9 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt)
61201 @@ -339,6 +348,12 @@ static inline int serial8250_rx_dma(struct uart_8250_port *p)
61203 return -1;
61208 + return -1;
61214 diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
61216 --- a/drivers/tty/serial/8250/8250_core.c
61218 @@ -559,6 +559,7 @@ static void __init serial8250_isa_init_ports(void)
61226 @@ -578,6 +579,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
61228 uart_add_one_port(drv, &up->port);
61234 @@ -1023,7 +1025,9 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
61235 uart->rs485_start_tx = up->rs485_start_tx;
61236 uart->rs485_stop_tx = up->rs485_stop_tx;
61237 uart->dma = up->dma;
61238 -
61240 + uart->port.line = up->port.line;
61243 if (uart->port.fifosize && !uart->tx_loadsz)
61244 uart->tx_loadsz = uart->port.fifosize;
61245 @@ -1247,7 +1251,11 @@ static void __exit serial8250_exit(void)
61257 diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
61259 --- a/drivers/tty/serial/8250/8250_dma.c
61261 @@ -11,6 +11,12 @@
61274 @@ -40,6 +46,39 @@ static void __dma_tx_complete(void *param)
61275 spin_unlock_irqrestore(&p->port.lock, flags);
61283 + struct uart_8250_dma *dma = p->dma;
61284 + struct tty_port *tty_port = &p->port.state->port;
61288 + dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
61289 + cur_index = dma->rx_size - state.residue;
61291 + if (cur_index == dma->rx_index)
61293 + else if (cur_index > dma->rx_index)
61294 + count = cur_index - dma->rx_index;
61296 + count = dma->rx_size - dma->rx_index;
61298 + tty_insert_flip_string(tty_port, dma->rx_buf + dma->rx_index, count);
61300 + if (cur_index < dma->rx_index) {
61301 + tty_insert_flip_string(tty_port, dma->rx_buf, cur_index);
61305 + p->port.icount.rx += count;
61306 + dma->rx_index = cur_index;
61314 @@ -59,6 +98,8 @@ static void __dma_rx_complete(void *param)
61322 struct uart_8250_dma *dma = p->dma;
61323 @@ -85,7 +126,12 @@ int serial8250_tx_dma(struct uart_8250_port *p)
61326 dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
61327 -
61329 + if (dma->tx_size < MAX_TX_BYTES) {
61330 + ret = -EBUSY;
61334 desc = dmaengine_prep_slave_single(dma->txchan,
61335 dma->tx_addr + xmit->tail,
61336 dma->tx_size, DMA_MEM_TO_DEV,
61337 @@ -115,6 +161,64 @@ int serial8250_tx_dma(struct uart_8250_port *p)
61347 + struct uart_port *port = &p->port;
61348 + struct tty_port *tty_port = &p->port.state->port;
61350 + struct uart_8250_dma *dma = p->dma;
61356 + dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
61357 + cur_index = dma->rx_size - state.residue;
61358 + } while (cur_index % dma->rxconf.src_maxburst);
61367 + p->port.icount.rx += i;
61371 + serial_port_out(port, UART_FCR, p->fcr);
61377 + struct uart_8250_dma *dma = p->dma;
61380 + desc = dmaengine_prep_dma_cyclic(dma->rxchan, dma->rx_addr,
61381 + dma->rx_size, dma->rx_size,
61385 + return -EBUSY;
61387 + dma->rx_running = 1;
61388 + desc->callback = NULL;
61389 + desc->callback_param = NULL;
61391 + dma->rx_cookie = dmaengine_submit(desc);
61392 + dma_async_issue_pending(dma->rxchan);
61393 + dma->rx_index = 0;
61401 struct uart_8250_dma *dma = p->dma;
61402 @@ -140,6 +244,8 @@ int serial8250_rx_dma(struct uart_8250_port *p)
61410 struct uart_8250_dma *dma = p->dma;
61411 @@ -167,11 +273,19 @@ int serial8250_request_dma(struct uart_8250_port *p)
61412 dma->rxconf.direction = DMA_DEV_TO_MEM;
61413 dma->rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
61414 dma->rxconf.src_addr = rx_dma_addr + UART_RX;
61416 + if ((p->port.fifosize / 4) < 16)
61417 + dma->rxconf.src_maxburst = p->port.fifosize / 4;
61419 + dma->rxconf.src_maxburst = 16;
61422 dma->txconf.direction = DMA_MEM_TO_DEV;
61423 dma->txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
61424 dma->txconf.dst_addr = tx_dma_addr + UART_TX;
61425 -
61427 + dma->txconf.dst_maxburst = 16;
61432 @@ -194,54 +308,52 @@ int serial8250_request_dma(struct uart_8250_port *p)
61434 dmaengine_slave_config(dma->rxchan, &dma->rxconf);
61436 - /* Get a channel for TX */
61437 - dma->txchan = dma_request_slave_channel_compat(mask,
61438 - dma->fn, dma->tx_param,
61439 - p->port.dev, "tx");
61440 - if (!dma->txchan) {
61441 - ret = -ENODEV;
61442 - goto release_rx;
61443 - }
61444 -
61445 - /* 8250 tx dma requires dmaengine driver to support terminate */
61446 - ret = dma_get_slave_caps(dma->txchan, &caps);
61447 - if (ret)
61448 - goto err;
61449 - if (!caps.cmd_terminate) {
61450 - ret = -EINVAL;
61451 - goto err;
61452 - }
61453 -
61454 - dmaengine_slave_config(dma->txchan, &dma->txconf);
61455 -
61458 + if (!dma->rx_size)
61459 + dma->rx_size = PAGE_SIZE * 2;
61461 if (!dma->rx_size)
61462 dma->rx_size = PAGE_SIZE;
61465 dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size,
61466 &dma->rx_addr, GFP_KERNEL);
61467 if (!dma->rx_buf) {
61468 ret = -ENOMEM;
61469 - goto err;
61473 - /* TX buffer */
61474 - dma->tx_addr = dma_map_single(dma->txchan->device->dev,
61475 - p->port.state->xmit.buf,
61476 - UART_XMIT_SIZE,
61477 - DMA_TO_DEVICE);
61478 - if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
61479 - dma_free_coherent(dma->rxchan->device->dev, dma->rx_size,
61480 - dma->rx_buf, dma->rx_addr);
61481 - ret = -ENOMEM;
61482 - goto err;
61483 - }
61485 + dma->txchan = dma_request_slave_channel_compat(mask,
61486 + dma->fn, dma->tx_param,
61487 + p->port.dev, "tx");
61488 + if (dma->txchan) {
61489 + dmaengine_slave_config(dma->txchan, &dma->txconf);
61492 + dma->tx_addr = dma_map_single(dma->txchan->device->dev,
61493 + p->port.state->xmit.buf,
61496 + if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
61497 + dma_free_coherent(dma->rxchan->device->dev,
61498 + dma->rx_size, dma->rx_buf,
61499 + dma->rx_addr);
61500 + dma_release_channel(dma->txchan);
61501 + dma->txchan = NULL;
61504 - dev_dbg_ratelimited(p->port.dev, "got both dma channels\n");
61505 + dev_info_ratelimited(p->port.dev, "got rx and tx dma channels\n");
61507 + dev_info_ratelimited(p->port.dev, "got rx dma channels only\n");
61515 -err:
61516 - dma_release_channel(dma->txchan);
61518 dma_release_channel(dma->rxchan);
61520 @@ -261,15 +373,18 @@ void serial8250_release_dma(struct uart_8250_port *p)
61521 dma->rx_addr);
61522 dma_release_channel(dma->rxchan);
61523 dma->rxchan = NULL;
61524 -
61526 + dma->rx_running = 0;
61529 - dmaengine_terminate_sync(dma->txchan);
61530 - dma_unmap_single(dma->txchan->device->dev, dma->tx_addr,
61531 - UART_XMIT_SIZE, DMA_TO_DEVICE);
61532 - dma_release_channel(dma->txchan);
61533 - dma->txchan = NULL;
61534 - dma->tx_running = 0;
61535 -
61536 + if (dma->txchan) {
61537 + dmaengine_terminate_all(dma->txchan);
61538 + dma_unmap_single(dma->txchan->device->dev, dma->tx_addr,
61540 + dma_release_channel(dma->txchan);
61541 + dma->txchan = NULL;
61542 + dma->tx_running = 0;
61544 dev_dbg_ratelimited(p->port.dev, "dma channels released\n");
61547 diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
61549 --- a/drivers/tty/serial/8250/8250_dw.c
61551 @@ -33,6 +33,7 @@
61559 @@ -49,6 +50,11 @@ struct dw8250_data {
61571 @@ -238,10 +244,9 @@ static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset)
61575 - struct uart_8250_port *up = up_to_u8250p(p);
61576 struct dw8250_data *d = to_dw8250_data(p->private_data);
61577 unsigned int iir = p->serial_in(p, UART_IIR);
61578 - unsigned int status;
61583 @@ -250,15 +255,13 @@ static int dw8250_handle_irq(struct uart_port *p)
61587 - *
61588 - * This problem has only been observed so far when not in DMA mode
61589 - * so we limit the workaround only to non-DMA mode.
61591 - if (!up->dma && ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)) {
61593 spin_lock_irqsave(&p->lock, flags);
61594 + usr = p->serial_in(p, d->usr_reg);
61595 status = p->serial_in(p, UART_LSR);
61596 -
61597 - if (!(status & (UART_LSR_DR | UART_LSR_BI)))
61598 + rfl = p->serial_in(p, DW_UART_RFL);
61600 (void) p->serial_in(p, UART_RX);
61602 spin_unlock_irqrestore(&p->lock, flags);
61603 @@ -332,12 +335,49 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
61610 struct dw8250_data *d = to_dw8250_data(p->private_data);
61618 clk_disable_unprepare(d->clk);
61629 + ret = clk_set_rate(d->clk, rate);
61630 + rate_temp = clk_get_rate(d->clk);
61635 + * the baud rate error must be under -+2%
61637 + if ((rate_temp < rate) && ((rate - rate_temp) > diff)) {
61638 + ret = clk_set_rate(d->clk, rate + diff);
61639 + rate_temp = clk_get_rate(d->clk);
61640 + if ((rate_temp < rate) && ((rate - rate_temp) > diff))
61641 + dev_info(p->dev, "set rate:%ld, but get rate:%d\n",
61643 + else if ((rate < rate_temp) && ((rate_temp - rate) > diff))
61644 + dev_info(p->dev, "set rate:%ld, but get rate:%d\n",
61648 + p->uartclk = rate;
61650 rate = clk_round_rate(d->clk, newrate);
61653 @@ -351,6 +391,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
61655 swap(p->uartclk, rate);
61658 clk_prepare_enable(d->clk);
61660 p->status &= ~UPSTAT_AUTOCTS;
61661 @@ -483,6 +524,9 @@ static int dw8250_probe(struct platform_device *pdev)
61662 data->data.dma.fn = dw8250_fallback_dma_filter;
61663 data->usr_reg = DW_UART_USR;
61664 p->private_data = &data->data;
61666 + data->irq = irq;
61669 data->uart_16550_compatible = device_property_read_bool(dev,
61670 "snps,uart-16550-compatible");
61671 @@ -522,6 +566,13 @@ static int dw8250_probe(struct platform_device *pdev)
61672 data->msr_mask_off |= UART_MSR_TERI;
61676 + if (device_property_read_bool(p->dev, "wakeup-source"))
61677 + data->enable_wakeup = 1;
61679 + data->enable_wakeup = 0;
61683 device_property_read_u32(dev, "clock-frequency", &p->uartclk);
61685 @@ -602,7 +653,10 @@ static int dw8250_probe(struct platform_device *pdev)
61687 queue_work(system_unbound_wq, &data->clk_work);
61689 -
61691 + if (data->enable_wakeup)
61692 + device_init_wakeup(&pdev->dev, true);
61697 @@ -645,6 +699,10 @@ static int dw8250_remove(struct platform_device *pdev)
61702 + if (data->enable_wakeup)
61703 + device_init_wakeup(&pdev->dev, false);
61708 @@ -655,6 +713,13 @@ static int dw8250_suspend(struct device *dev)
61711 serial8250_suspend_port(data->data.line);
61714 + if (!enable_irq_wake(data->irq))
61715 + data->irq_wake = 1;
61722 @@ -664,6 +729,15 @@ static int dw8250_resume(struct device *dev)
61725 serial8250_resume_port(data->data.line);
61728 + if (data->irq_wake) {
61729 + disable_irq_wake(data->irq);
61730 + data->irq_wake = 0;
61738 diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
61740 --- a/drivers/tty/serial/8250/8250_dwlib.c
61742 @@ -106,6 +106,15 @@ void dw8250_setup_port(struct uart_port *p)
61758 @@ -114,6 +123,9 @@ void dw8250_setup_port(struct uart_port *p)
61759 p->type = PORT_16550A;
61760 p->flags |= UPF_FIXED_TYPE;
61761 p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
61763 + up->tx_loadsz = p->fifosize * 3 / 4;
61765 up->capabilities = UART_CAP_FIFO;
61768 diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
61770 --- a/drivers/tty/serial/8250/8250_port.c
61772 @@ -1548,8 +1548,13 @@ static inline void __start_tx(struct uart_port *port)
61777 + if (up->dma && up->dma->txchan && !up->dma->tx_dma(up))
61780 if (up->dma && !up->dma->tx_dma(up))
61785 if (up->bugs & UART_BUG_TXEN) {
61786 @@ -1879,6 +1884,12 @@ EXPORT_SYMBOL_GPL(serial8250_modem_status);
61794 + return up->dma->rx_dma(up);
61799 @@ -1887,6 +1898,7 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
61802 return up->dma->rx_dma(up);
61807 @@ -1897,7 +1909,9 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
61817 @@ -1906,6 +1920,17 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
61823 + int dma_err = -1;
61825 + if (up->dma && up->dma->rxchan)
61828 + if (!up->dma || dma_err)
61835 @@ -1923,11 +1948,34 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
61836 if (!up->dma || handle_rx_dma(up, iir))
61841 - if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE) &&
61842 - (up->ier & UART_IER_THRI))
61844 + if ((!up->dma || (up->dma && (!up->dma->txchan || up->dma->tx_err))) &&
61848 + if ((!up->dma || (up->dma && up->dma->tx_err)) &&
61857 + pr_err("%s: Overrun error!\n", port->name);
61859 + pr_err("%s: Parity error!\n", port->name);
61861 + pr_err("%s: Frame error!\n", port->name);
61863 + pr_err("%s: Break interrupt!\n", port->name);
61866 + port->name);
61872 @@ -2396,7 +2444,11 @@ int serial8250_do_startup(struct uart_port *port)
61882 dev_warn_ratelimited(port->dev, "%s\n", msg);
61883 up->dma = NULL;
61884 @@ -2590,6 +2642,10 @@ void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
61895 @@ -2609,6 +2665,17 @@ void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
61896 serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB);
61901 + dev_warn_ratelimited(port->dev, "ttyS%d set divisor fail, quot:%d != dll,dlh:%d\n",
61904 + if (port->type != PORT_16750)
61905 + serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */
61908 + serial_port_out(port, UART_MCR, up->mcr);
61913 @@ -2788,6 +2855,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
61914 if ((termios->c_cflag & CREAD) == 0)
61915 port->ignore_status_mask |= UART_LSR_DR;
61921 @@ -2801,6 +2869,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
61922 up->ier |= UART_IER_RTOIE;
61924 serial_port_out(port, UART_IER, up->ier);
61927 if (up->capabilities & UART_CAP_EFR) {
61929 @@ -2819,16 +2888,25 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
61941 + up->fcr = UART_FCR_ENABLE_FIFO | UART_FCR_T_TRIG_10 | UART_FCR_R_TRIG_10;
61944 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
61947 - if (port->type == PORT_16750)
61948 + if (port->type == PORT_16750) {
61949 serial_port_out(port, UART_FCR, up->fcr);
61950 + serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */
61953 - serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */
61954 if (port->type != PORT_16750) {
61956 if (up->fcr & UART_FCR_ENABLE_FIFO)
61957 @@ -2836,6 +2914,23 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
61958 serial_port_out(port, UART_FCR, up->fcr); /* set fcr */
61960 serial8250_set_mctrl(port, port->mctrl);
61966 + up->ier &= ~UART_IER_MSI;
61967 + if (!(up->bugs & UART_BUG_NOMSR) &&
61968 + UART_ENABLE_MS(&up->port, termios->c_cflag))
61969 + up->ier |= UART_IER_MSI;
61970 + if (up->capabilities & UART_CAP_UUE)
61971 + up->ier |= UART_IER_UUE;
61972 + if (up->capabilities & UART_CAP_RTOIE)
61973 + up->ier |= UART_IER_RTOIE;
61975 + serial_port_out(port, UART_IER, up->ier);
61978 spin_unlock_irqrestore(&port->lock, flags);
61981 diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
61983 --- a/drivers/tty/vt/keyboard.c
61985 @@ -488,6 +488,7 @@ static void fn_hold(struct vc_data *vc)
61987 struct tty_struct *tty = vc->port.tty;
61993 diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
61995 --- a/drivers/usb/core/hub.c
61997 @@ -1829,7 +1829,8 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *…
62000 if (hdev->parent) { /* normal device */
62001 - usb_enable_autosuspend(hdev);
62002 + if (!(hdev->parent->quirks & USB_QUIRK_AUTO_SUSPEND))
62005 const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
62007 diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
62009 --- a/drivers/usb/core/quirks.c
62011 @@ -322,6 +322,10 @@ static const struct usb_device_id usb_quirk_list[] = {
62022 @@ -414,6 +418,10 @@ static const struct usb_device_id usb_quirk_list[] = {
62033 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
62035 --- a/drivers/usb/gadget/Kconfig
62037 @@ -216,6 +216,12 @@ config USB_F_PRINTER
62047 # this first set of drivers all depend on bulk-capable hardware.
62050 @@ -230,6 +236,14 @@ config USB_CONFIGFS
62065 @@ -371,6 +385,23 @@ config USB_CONFIGFS_F_FS
62073 + select USB_F_ACC
62081 + select SND_PCM
62082 + select USB_F_AUDIO_SRC
62089 diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
62091 --- a/drivers/usb/gadget/composite.c
62093 @@ -13,6 +13,7 @@
62101 @@ -734,47 +735,77 @@ static int bos_desc(struct usb_composite_dev *cdev)
62103 if (gadget_is_superspeed_plus(cdev->gadget)) {
62109 - ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
62110 - bos->bNumDeviceCaps++;
62111 + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x2)
62115 - * Report typical values.
62119 + ssic = (ssac + 1) / 2 - 1;
62121 + ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
62122 + bos->bNumDeviceCaps++;
62124 - le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(1));
62125 - ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1);
62126 + le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(ssac));
62127 + ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(ssac);
62128 ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
62129 ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE;
62130 ssp_cap->bReserved = 0;
62131 ssp_cap->wReserved = 0;
62133 - /* SSAC = 1 (2 attributes) */
62134 - ssp_cap->bmAttributes = cpu_to_le32(1);
62135 + ssp_cap->bmAttributes =
62139 - /* Min RX/TX Lane Count = 1 */
62140 ssp_cap->wFunctionalitySupport =
62141 - cpu_to_le16((1 << 8) | (1 << 12));
62147 - * bmSublinkSpeedAttr[0]:
62148 - * ST = Symmetric, RX
62149 - * LSE = 3 (Gbps)
62150 - * LP = 1 (SuperSpeedPlus)
62151 - * LSM = 10 (10 Gbps)
62152 - */
62153 - ssp_cap->bmSublinkSpeedAttr[0] =
62154 - cpu_to_le32((3 << 4) | (1 << 14) | (0xa << 16));
62155 - /*
62156 - * bmSublinkSpeedAttr[1] =
62157 - * ST = Symmetric, TX
62158 - * LSE = 3 (Gbps)
62159 - * LP = 1 (SuperSpeedPlus)
62160 - * LSM = 10 (10 Gbps)
62163 + * - SSID 0 for symmetric RX/TX sublink speed of 10 Gbps.
62166 + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps.
62169 + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps.
62170 + * - SSID 1 for symmetric RX/TX sublink speed of 10 Gbps.
62172 - ssp_cap->bmSublinkSpeedAttr[1] =
62173 - cpu_to_le32((3 << 4) | (1 << 14) |
62174 - (0xa << 16) | (1 << 7));
62182 + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x1 ||
62183 + cdev->gadget->max_ssp_rate == USB_SSP_GEN_UNKNOWN)
62193 + ssp_cap->bmSublinkSpeedAttr[i] =
62204 return le16_to_cpu(bos->wTotalLength);
62205 @@ -2061,7 +2092,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
62209 -void composite_disconnect(struct usb_gadget *gadget)
62214 @@ -2078,6 +2109,23 @@ void composite_disconnect(struct usb_gadget *gadget)
62215 spin_unlock_irqrestore(&cdev->lock, flags);
62235 /*-------------------------------------------------------------------------*/
62238 @@ -2398,7 +2446,7 @@ static const struct usb_gadget_driver composite_driver_template = {
62242 - .reset = composite_disconnect,
62247 diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
62249 --- a/drivers/usb/gadget/configfs.c
62251 @@ -10,6 +10,32 @@
62276 + return ERR_PTR(-EINVAL);
62284 @@ -51,6 +77,12 @@ struct gadget_info {
62297 @@ -272,7 +304,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
62299 mutex_lock(&gi->lock);
62301 - if (!strlen(name)) {
62306 @@ -1270,6 +1302,9 @@ static void purge_configs_funcs(struct gadget_info *gi)
62307 f->name, f);
62308 f->unbind(c, f);
62311 + if (f->bind_deactivated)
62314 c->next_interface_id = 0;
62315 memset(c->interface, 0, sizeof(c->interface));
62316 @@ -1422,6 +1457,57 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
62324 + struct usb_composite_dev *cdev = &gi->cdev;
62328 + /* 0-connected 1-configured 2-disconnected*/
62333 + spin_lock_irqsave(&cdev->lock, flags);
62334 + if (cdev->config)
62337 + if (gi->connected != gi->sw_connected) {
62338 + if (gi->connected)
62342 + gi->sw_connected = gi->connected;
62344 + spin_unlock_irqrestore(&cdev->lock, flags);
62347 + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected);
62353 + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured);
62359 + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected);
62366 + gi->connected, gi->sw_connected, cdev->config);
62374 @@ -1449,6 +1535,51 @@ static void configfs_composite_unbind(struct usb_gadget *gadget)
62375 spin_unlock_irqrestore(&gi->spinlock, flags);
62385 + int value = -EOPNOTSUPP;
62388 + spin_lock_irqsave(&cdev->lock, flags);
62389 + if (c->bRequest == USB_REQ_GET_DESCRIPTOR &&
62390 + (c->wValue >> 8) == USB_DT_CONFIG && !gi->connected) {
62391 + gi->connected = 1;
62392 + schedule_work(&gi->work);
62394 + spin_unlock_irqrestore(&cdev->lock, flags);
62395 + list_for_each_entry(fi, &gi->available_func, cfs_list) {
62396 + if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
62397 + value = fi->f->setup(fi->f, c);
62411 + spin_lock_irqsave(&cdev->lock, flags);
62412 + if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
62413 + cdev->config) {
62414 + schedule_work(&gi->work);
62416 + spin_unlock_irqrestore(&cdev->lock, flags);
62426 @@ -1474,6 +1605,8 @@ static int configfs_composite_setup(struct usb_gadget *gadget,
62435 @@ -1484,6 +1617,14 @@ static void configfs_composite_disconnect(struct usb_gadget *gadget)
62448 spin_lock_irqsave(&gi->spinlock, flags);
62450 @@ -1492,10 +1633,36 @@ static void configfs_composite_disconnect(struct usb_gadget *gadget)
62455 + gi->connected = 0;
62456 + schedule_work(&gi->work);
62459 spin_unlock_irqrestore(&gi->spinlock, flags);
62473 + spin_lock_irqsave(&gi->spinlock, flags);
62475 + if (!cdev || gi->unbind) {
62476 + spin_unlock_irqrestore(&gi->spinlock, flags);
62481 + spin_unlock_irqrestore(&gi->spinlock, flags);
62487 @@ -1544,10 +1711,13 @@ static const struct usb_gadget_driver configfs_driver_template = {
62495 - .reset = configfs_composite_disconnect,
62499 -
62503 @@ -1559,6 +1729,91 @@ static const struct usb_gadget_driver configfs_driver_template = {
62519 + cdev = &dev->cdev;
62524 + spin_lock_irqsave(&cdev->lock, flags);
62525 + if (cdev->config)
62527 + else if (dev->connected)
62529 + spin_unlock_irqrestore(&cdev->lock, flags);
62546 + INIT_WORK(&gi->work, android_work);
62547 + gi->dev = device_create(android_class, NULL,
62549 + if (IS_ERR(gi->dev))
62550 + return PTR_ERR(gi->dev);
62552 + dev_set_drvdata(gi->dev, gi);
62554 + android_device = gi->dev;
62560 + err = device_create_file(gi->dev, attr);
62562 + device_destroy(gi->dev->class,
62563 + gi->dev->devt);
62578 + device_remove_file(gi->dev, attr);
62579 + device_destroy(gi->dev->class, gi->dev->devt);
62595 @@ -1611,7 +1866,11 @@ static struct config_group *gadgets_make(
62596 if (!gi->composite.gadget_driver.function)
62602 return &gi->group;
62606 return ERR_PTR(-ENOMEM);
62607 @@ -1619,7 +1878,11 @@ static struct config_group *gadgets_make(
62619 @@ -1659,6 +1922,13 @@ static int __init gadget_cfs_init(void)
62633 @@ -1666,5 +1936,10 @@ module_init(gadget_cfs_init);
62644 diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
62646 --- a/drivers/usb/gadget/epautoconf.c
62648 @@ -67,6 +67,9 @@ struct usb_ep *usb_ep_autoconfig_ss(
62653 + u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
62656 if (gadget->ops->match_ep) {
62657 ep = gadget->ops->match_ep(gadget, desc, ep_comp);
62658 @@ -110,6 +113,27 @@ struct usb_ep *usb_ep_autoconfig_ss(
62659 ep->desc = NULL;
62660 ep->comp_desc = NULL;
62661 ep->claimed = true;
62663 + ep->transfer_type = type;
62668 + ep->mult = (ep_comp->bmAttributes & 0x3) + 1;
62672 + ep->maxburst = ep_comp->bMaxBurst + 1;
62680 + ep->mult = usb_endpoint_maxp_mult(desc);
62686 diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
62688 --- a/drivers/usb/gadget/function/f_fs.c
62690 @@ -71,7 +71,7 @@ struct ffs_function {
62694 - u8 eps_revmap[16];
62699 @@ -2827,7 +2827,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
62703 - int idx;
62708 @@ -2900,8 +2900,9 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
62710 ffs_ep->ep = ep;
62711 ffs_ep->req = req;
62712 - func->eps_revmap[ds->bEndpointAddress &
62713 - USB_ENDPOINT_NUMBER_MASK] = idx + 1;
62714 + ep_num = ((ds->bEndpointAddress & USB_ENDPOINT_DIR_MASK) >> 3) |
62715 + (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
62716 + func->eps_revmap[ep_num] = idx + 1;
62720 @@ -3436,7 +3437,10 @@ static void ffs_func_resume(struct usb_function *f)
62724 - num = func->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK];
62728 + num = func->eps_revmap[ep_num];
62729 return num ? num : -EDOM;
62732 diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
62734 --- a/drivers/usb/gadget/function/f_uvc.c
62736 @@ -124,6 +124,18 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt0 = {
62755 @@ -147,6 +159,16 @@ static struct usb_endpoint_descriptor uvc_fs_streaming_ep = {
62772 @@ -158,6 +180,16 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = {
62789 @@ -170,6 +202,17 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep = {
62807 @@ -178,18 +221,36 @@ static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = {
62844 @@ -197,6 +258,12 @@ static const struct usb_descriptor_header * const uvc_ss_streaming[] = {
62854 /* --------------------------------------------------------------------------
62857 @@ -208,6 +275,10 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req)
62863 + uvc->event_setup_out, req->actual);
62865 if (uvc->event_setup_out) {
62866 uvc->event_setup_out = 0;
62868 @@ -226,6 +297,11 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
62874 + ctrl->bRequestType, ctrl->bRequest, le16_to_cpu(ctrl->wValue),
62875 + le16_to_cpu(ctrl->wIndex), le16_to_cpu(ctrl->wLength));
62877 if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) {
62879 return -EINVAL;
62880 @@ -260,15 +336,27 @@ static int
62888 + opts = fi_to_f_uvc_opts(f->fi);
62890 if (interface == uvc->control_intf)
62892 else if (interface != uvc->streaming_intf)
62893 return -EINVAL;
62894 - else
62895 + else if (!opts->streaming_bulk)
62896 return uvc->video.ep->enabled ? 1 : 0;
62900 + * ISOC endpoints as there are different alt-settings for
62901 + * zero-bandwidth and full-bandwidth cases, but the same
62903 + * alt-setting.
62909 @@ -278,10 +366,13 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
62910 struct usb_composite_dev *cdev = f->config->cdev;
62918 + opts = fi_to_f_uvc_opts(f->fi);
62920 if (interface == uvc->control_intf) {
62922 return -EINVAL;
62923 @@ -295,6 +386,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
62925 usb_ep_enable(uvc->control_ep);
62927 + if (uvc->event_suspend) {
62930 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
62931 + uvc->event_suspend = 0;
62935 if (uvc->state == UVC_STATE_DISCONNECTED) {
62938 @@ -310,49 +409,94 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
62939 if (interface != uvc->streaming_intf)
62940 return -EINVAL;
62942 - /* TODO
62943 - if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep))
62944 - return alt ? -EINVAL : 0;
62945 - */
62946 + if (!opts->streaming_bulk) {
62949 + if (uvc->state != UVC_STATE_STREAMING)
62952 + if (uvc->video.ep)
62953 + usb_ep_disable(uvc->video.ep);
62957 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
62959 - switch (alt) {
62960 - case 0:
62961 - if (uvc->state != UVC_STATE_STREAMING)
62962 + uvc->state = UVC_STATE_CONNECTED;
62965 - if (uvc->video.ep)
62966 - usb_ep_disable(uvc->video.ep);
62968 + if (uvc->state != UVC_STATE_CONNECTED)
62971 - memset(&v4l2_event, 0, sizeof(v4l2_event));
62972 - v4l2_event.type = UVC_EVENT_STREAMOFF;
62973 - v4l2_event_queue(&uvc->vdev, &v4l2_event);
62974 + if (!uvc->video.ep)
62975 + return -EINVAL;
62977 - uvc->state = UVC_STATE_CONNECTED;
62978 - return 0;
62980 + usb_ep_disable(uvc->video.ep);
62982 - case 1:
62983 - if (uvc->state != UVC_STATE_CONNECTED)
62984 - return 0;
62985 + ret = config_ep_by_speed(f->config->cdev->gadget,
62986 + &uvc->func, uvc->video.ep);
62989 + usb_ep_enable(uvc->video.ep);
62991 - if (!uvc->video.ep)
62994 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
62998 return -EINVAL;
63001 + switch (uvc->state) {
63003 + if (uvc->video.ep &&
63004 + !uvc->video.ep->enabled) {
63007 + * but don't change the 'uvc->state'.
63009 + ret = config_ep_by_speed(cdev->gadget,
63010 + &uvc->func,
63011 + uvc->video.ep);
63014 + ret = usb_ep_enable(uvc->video.ep);
63020 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63022 + uvc->state = UVC_STATE_STREAMING;
63026 - uvcg_info(f, "reset UVC\n");
63027 - usb_ep_disable(uvc->video.ep);
63034 - ret = config_ep_by_speed(f->config->cdev->gadget,
63035 - &(uvc->func), uvc->video.ep);
63036 - if (ret)
63037 - return ret;
63038 - usb_ep_enable(uvc->video.ep);
63039 + if (uvc->video.ep &&
63040 + uvc->video.ep->enabled) {
63041 + ret = usb_ep_disable(uvc->video.ep);
63046 - memset(&v4l2_event, 0, sizeof(v4l2_event));
63047 - v4l2_event.type = UVC_EVENT_STREAMON;
63048 - v4l2_event_queue(&uvc->vdev, &v4l2_event);
63049 - return USB_GADGET_DELAYED_STATUS;
63052 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63053 + uvc->state = UVC_STATE_CONNECTED;
63056 - default:
63057 - return -EINVAL;
63059 + return -EINVAL;
63064 @@ -374,6 +518,30 @@ uvc_function_disable(struct usb_function *f)
63065 usb_ep_disable(uvc->control_ep);
63075 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63076 + uvc->event_suspend = 1;
63087 + v4l2_event_queue(&uvc->vdev, &v4l2_event);
63088 + uvc->event_suspend = 0;
63092 /* --------------------------------------------------------------------------
63095 @@ -467,32 +635,45 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
63098 const struct usb_descriptor_header * const *src;
63109 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63113 uvc_control_desc = uvc->desc.ss_control;
63114 uvc_streaming_cls = uvc->desc.ss_streaming;
63115 - uvc_streaming_std = uvc_ss_streaming;
63116 + if (!opts->streaming_bulk)
63123 uvc_control_desc = uvc->desc.fs_control;
63124 uvc_streaming_cls = uvc->desc.hs_streaming;
63125 - uvc_streaming_std = uvc_hs_streaming;
63126 + if (!opts->streaming_bulk)
63134 uvc_control_desc = uvc->desc.fs_control;
63135 uvc_streaming_cls = uvc->desc.fs_streaming;
63136 - uvc_streaming_std = uvc_fs_streaming;
63137 + if (!opts->streaming_bulk)
63144 @@ -512,12 +693,17 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
63148 + if (!opts->streaming_bulk)
63158 - + uvc_streaming_intf_alt0.bLength;
63159 + + streaming_intf_alt0->bLength;
63163 @@ -567,7 +753,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
63167 - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0);
63172 @@ -592,15 +778,24 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63175 int ret = -EINVAL;
63180 opts = fi_to_f_uvc_opts(f->fi);
63183 - opts->streaming_interval = clamp(opts->streaming_interval, 1U, 16U);
63184 - opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
63185 - opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
63186 + if (!opts->streaming_bulk) {
63187 + opts->streaming_interval = clamp(opts->streaming_interval,
63189 + opts->streaming_maxpacket = clamp(opts->streaming_maxpacket,
63191 + opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
63193 + opts->streaming_maxpacket = clamp(opts->streaming_maxpacket,
63195 + opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
63199 if (opts->streaming_maxburst &&
63200 @@ -627,26 +822,46 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63201 max_packet_size = opts->streaming_maxpacket / 3;
63204 - uvc_fs_streaming_ep.wMaxPacketSize =
63205 - cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
63206 - uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
63207 -
63208 - uvc_hs_streaming_ep.wMaxPacketSize =
63209 - cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11));
63210 -
63211 - /* A high-bandwidth endpoint must specify a bInterval value of 1 */
63212 - if (max_packet_mult > 1)
63213 - uvc_hs_streaming_ep.bInterval = 1;
63214 - else
63215 - uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
63216 -
63217 - uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size);
63218 - uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
63219 - uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
63220 - uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
63221 - uvc_ss_streaming_comp.wBytesPerInterval =
63222 - cpu_to_le16(max_packet_size * max_packet_mult *
63223 - (opts->streaming_maxburst + 1));
63224 + if (!opts->streaming_bulk) {
63226 + cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
63227 + uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
63231 + ((max_packet_mult - 1) << 11));
63233 + /* A high-bandwidth endpoint must specify a bInterval value of 1 */
63237 + uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
63241 + uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
63242 + uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
63243 + uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
63246 + (opts->streaming_maxburst + 1));
63249 + cpu_to_le16(min(opts->streaming_maxpacket, 64U));
63252 + cpu_to_le16(min(opts->streaming_maxpacket, 512U));
63256 + uvc_ss_bulk_streaming_comp.bMaxBurst = opts->streaming_maxburst;
63258 + * As per USB 3.1 spec "Table 9-26. SuperSpeed Endpoint
63266 ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
63267 @@ -656,23 +871,57 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63269 uvc->control_ep = ep;
63271 - if (gadget_is_superspeed(c->cdev->gadget))
63272 - ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep,
63273 - &uvc_ss_streaming_comp);
63274 - else if (gadget_is_dualspeed(cdev->gadget))
63275 - ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep);
63276 - else
63277 - ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep);
63278 + if (gadget_is_superspeed(c->cdev->gadget)) {
63279 + if (!opts->streaming_bulk)
63280 + ep = usb_ep_autoconfig_ss(cdev->gadget,
63284 + ep = usb_ep_autoconfig_ss(cdev->gadget,
63287 + } else if (gadget_is_dualspeed(cdev->gadget)) {
63288 + if (!opts->streaming_bulk) {
63289 + ep = usb_ep_autoconfig(cdev->gadget,
63292 + ep = usb_ep_autoconfig(cdev->gadget,
63301 + cpu_to_le16(min(opts->streaming_maxpacket,
63305 + if (!opts->streaming_bulk)
63306 + ep = usb_ep_autoconfig(cdev->gadget,
63309 + ep = usb_ep_autoconfig(cdev->gadget,
63317 uvc->video.ep = ep;
63318 + address = uvc->video.ep->address;
63320 - uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
63321 - uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
63322 - uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address;
63323 + if (!opts->streaming_bulk) {
63335 @@ -683,8 +932,12 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63339 - uvc_streaming_intf_alt0.iInterface = ret;
63340 - uvc_streaming_intf_alt1.iInterface = ret;
63341 + if (!opts->streaming_bulk) {
63350 @@ -696,8 +949,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63354 - uvc_streaming_intf_alt0.bInterfaceNumber = ret;
63355 - uvc_streaming_intf_alt1.bInterfaceNumber = ret;
63357 + if (!opts->streaming_bulk) {
63364 uvc->streaming_intf = ret;
63365 opts->streaming_interface = ret;
63367 @@ -747,6 +1006,8 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
63371 + if (opts->streaming_bulk)
63372 + uvc->video.max_payload_size = uvc->video.imagesize;
63376 @@ -785,6 +1046,7 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63384 @@ -834,6 +1096,34 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63385 od->bSourceID = 2;
63386 od->iTerminal = 0;
63388 + ed = &opts->uvc_extension;
63389 + ed->bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 1);
63390 + ed->bDescriptorType = USB_DT_CS_INTERFACE;
63391 + ed->bDescriptorSubType = UVC_VC_EXTENSION_UNIT;
63392 + ed->bUnitID = 6;
63393 + ed->guidExtensionCode[0] = 0xa2;
63394 + ed->guidExtensionCode[1] = 0x9e;
63395 + ed->guidExtensionCode[2] = 0x76;
63396 + ed->guidExtensionCode[3] = 0x41;
63397 + ed->guidExtensionCode[4] = 0xde;
63398 + ed->guidExtensionCode[5] = 0x04;
63399 + ed->guidExtensionCode[6] = 0x47;
63400 + ed->guidExtensionCode[7] = 0xe3;
63401 + ed->guidExtensionCode[8] = 0x8b;
63402 + ed->guidExtensionCode[9] = 0x2b;
63403 + ed->guidExtensionCode[10] = 0xf4;
63404 + ed->guidExtensionCode[11] = 0x34;
63405 + ed->guidExtensionCode[12] = 0x1a;
63406 + ed->guidExtensionCode[13] = 0xff;
63407 + ed->guidExtensionCode[14] = 0x00;
63408 + ed->guidExtensionCode[15] = 0x3b;
63409 + ed->bNumControls = 3;
63410 + ed->bNrInPins = 1;
63411 + ed->baSourceID[0] = 2;
63412 + ed->bControlSize = 1;
63413 + ed->bmControls[0] = 7;
63414 + ed->iExtension = 0;
63416 md = &opts->uvc_color_matching;
63417 md->bLength = UVC_DT_COLOR_MATCHING_SIZE;
63418 md->bDescriptorType = USB_DT_CS_INTERFACE;
63419 @@ -848,7 +1138,8 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63423 - ctl_cls[4] = NULL; /* NULL-terminate */
63425 + ctl_cls[5] = NULL; /* NULL-terminate */
63426 opts->fs_control =
63429 @@ -858,12 +1149,15 @@ static struct usb_function_instance *uvc_alloc_inst(void)
63433 - ctl_cls[4] = NULL; /* NULL-terminate */
63435 + ctl_cls[5] = NULL; /* NULL-terminate */
63436 opts->ss_control =
63439 opts->streaming_interval = 1;
63440 opts->streaming_maxpacket = 1024;
63441 + opts->uvc_num_request = UVC_NUM_REQUESTS;
63442 + opts->pm_qos_latency = 0;
63446 @@ -974,6 +1268,8 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
63447 uvc->func.disable = uvc_function_disable;
63448 uvc->func.setup = uvc_function_setup;
63449 uvc->func.free_func = uvc_free;
63450 + uvc->func.suspend = uvc_function_suspend;
63451 + uvc->func.resume = uvc_function_resume;
63452 uvc->func.bind_deactivated = true;
63454 return &uvc->func;
63455 diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h
63457 --- a/drivers/usb/gadget/function/u_uvc.h
63459 @@ -18,15 +18,18 @@
63477 * Control descriptors array pointers for full-/high-speed and
63478 @@ -51,6 +54,7 @@ struct f_uvc_opts {
63486 @@ -60,8 +64,8 @@ struct f_uvc_opts {
63490 - struct uvc_descriptor_header *uvc_fs_control_cls[5];
63491 - struct uvc_descriptor_header *uvc_ss_control_cls[5];
63496 * Streaming descriptors for full-speed, high-speed and super-speed.
63497 @@ -81,6 +85,7 @@ struct f_uvc_opts {
63505 diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
63507 --- a/drivers/usb/gadget/function/uvc.h
63509 @@ -15,6 +15,7 @@
63515 #include <media/v4l2-device.h>
63516 #include <media/v4l2-dev.h>
63517 @@ -69,6 +70,7 @@ extern unsigned int uvc_gadget_trace_param;
63523 /* ------------------------------------------------------------------------
63525 @@ -90,8 +92,8 @@ struct uvc_video {
63529 - struct usb_request *req[UVC_NUM_REQUESTS];
63530 - __u8 *req_buffer[UVC_NUM_REQUESTS];
63536 @@ -120,6 +122,8 @@ struct uvc_device {
63545 @@ -140,6 +144,7 @@ struct uvc_device {
63553 diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
63555 --- a/drivers/usb/gadget/function/uvc_queue.c
63557 @@ -124,6 +124,14 @@ int uvcg_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
63558 queue->queue.mem_ops = &vb2_vmalloc_memops;
63559 queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
63567 + queue->queue.allow_zero_bytesused = 1;
63569 ret = vb2_queue_init(&queue->queue);
63572 diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c
63574 --- a/drivers/usb/gadget/function/uvc_v4l2.c
63576 @@ -41,6 +41,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
63577 req->length = min_t(unsigned int, uvc->event_length, data->length);
63578 req->zero = data->length < uvc->event_length;
63580 + uvc_trace(UVC_TRACE_CONTROL, "%s: req len %d\n", __func__, req->length);
63581 memcpy(req->buf, data->data, req->length);
63583 return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL);
63584 @@ -58,6 +59,8 @@ struct uvc_format {
63593 @@ -201,11 +204,21 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
63597 - * Complete the alternate setting selection setup phase now that
63598 - * userspace is ready to provide video frames.
63600 + * for ISOC endpoints as there are different alt-
63601 + * settings for zero-bandwidth and full-bandwidth
63603 + * as they have a single alt-setting.
63605 - uvc_function_setup_continue(uvc);
63606 - uvc->state = UVC_STATE_STREAMING;
63607 + if (!usb_endpoint_xfer_bulk(video->ep->desc)) {
63614 + uvc->state = UVC_STATE_STREAMING;
63619 @@ -390,6 +403,9 @@ const struct v4l2_file_operations uvc_v4l2_fops = {
63629 diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
63631 --- a/drivers/usb/gadget/function/uvc_video.c
63633 @@ -12,12 +12,14 @@
63639 #include <media/v4l2-dev.h>
63646 /* --------------------------------------------------------------------------
63648 @@ -87,6 +89,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
63649 video->fid ^= UVC_STREAM_FID;
63651 video->payload_size = 0;
63652 + req->zero = 1;
63655 if (video->payload_size == video->max_payload_size ||
63656 @@ -135,7 +138,7 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
63660 - if (usb_endpoint_xfer_bulk(video->ep->desc))
63661 + if (video->ep->desc && usb_endpoint_xfer_bulk(video->ep->desc))
63662 usb_ep_set_halt(video->ep);
63665 @@ -176,8 +179,13 @@ static int
63672 - for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
63674 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63676 + for (i = 0; i < opts->uvc_num_request; ++i) {
63677 if (video->req[i]) {
63678 usb_ep_free_request(video->ep, video->req[i]);
63679 video->req[i] = NULL;
63680 @@ -200,14 +208,24 @@ uvc_video_alloc_requests(struct uvc_video *video)
63683 int ret = -ENOMEM;
63688 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63690 BUG_ON(video->req_size);
63692 - req_size = video->ep->maxpacket
63693 - * max_t(unsigned int, video->ep->maxburst, 1)
63694 - * (video->ep->mult);
63695 + if (!usb_endpoint_xfer_bulk(video->ep->desc)) {
63696 + req_size = video->ep->maxpacket
63697 + * max_t(unsigned int, video->ep->maxburst, 1)
63698 + * (video->ep->mult);
63700 + req_size = video->ep->maxpacket
63701 + * max_t(unsigned int, video->ep->maxburst, 1);
63704 - for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
63705 + for (i = 0; i < opts->uvc_num_request; ++i) {
63706 video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
63707 if (video->req_buffer[i] == NULL)
63709 @@ -301,6 +319,8 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
63716 if (video->ep == NULL) {
63717 uvcg_info(&video->uvc->func,
63718 @@ -308,19 +328,25 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
63719 return -ENODEV;
63723 + opts = fi_to_f_uvc_opts(uvc->func.fi);
63726 cancel_work_sync(&video->pump);
63727 uvcg_queue_cancel(&video->queue, 0);
63729 - for (i = 0; i < UVC_NUM_REQUESTS; ++i)
63730 + for (i = 0; i < opts->uvc_num_request; ++i)
63731 if (video->req[i])
63732 usb_ep_dequeue(video->ep, video->req[i]);
63735 uvcg_queue_enable(&video->queue, 0);
63736 + if (cpu_latency_qos_request_active(&uvc->pm_qos))
63737 + cpu_latency_qos_remove_request(&uvc->pm_qos);
63741 + cpu_latency_qos_add_request(&uvc->pm_qos, opts->pm_qos_latency);
63742 if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
63745 diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
63747 --- a/drivers/usb/gadget/udc/core.c
63749 @@ -755,7 +755,7 @@ int usb_gadget_deactivate(struct usb_gadget *gadget)
63753 - if (gadget->deactivated)
63754 + if (!gadget || gadget->deactivated)
63757 if (gadget->connected) {
63758 diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
63760 --- a/drivers/usb/storage/scsiglue.c
63762 @@ -102,6 +102,10 @@ static int slave_configure(struct scsi_device *sdev)
63763 if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) {
63766 + if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == 0x05e3 &&
63767 + le16_to_cpu(us->pusb_dev->descriptor.idProduct) == 0x0749)
63770 if (us->fflags & US_FL_MAX_SECTORS_MIN)
63772 if (queue_max_hw_sectors(sdev->request_queue) > max_sectors)
63773 diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
63775 --- a/drivers/usb/storage/unusual_devs.h
63777 @@ -927,6 +927,12 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451,
63790 diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
63792 --- a/drivers/usb/storage/unusual_uas.h
63794 @@ -76,6 +76,12 @@ UNUSUAL_DEV(0x0b05, 0x1932, 0x0000, 0x9999,
63804 /* Reported-by: David Webb <djw@noc.ac.uk> */
63807 @@ -118,6 +124,12 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
63817 /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
63820 @@ -139,6 +151,12 @@ UNUSUAL_DEV(0x17ef, 0x3899, 0x0000, 0x9999,
63830 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
63833 diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
63835 --- a/drivers/video/Kconfig
63837 @@ -25,6 +25,10 @@ endmenu
63848 diff --git a/drivers/video/Makefile b/drivers/video/Makefile
63850 --- a/drivers/video/Makefile
63852 @@ -6,6 +6,7 @@ obj-$(CONFIG_VT) += console/
63853 obj-$(CONFIG_FB_STI) += console/
63854 obj-$(CONFIG_LOGO) += logo/
63855 obj-y += backlight/
63856 +obj-y += rockchip/
63858 obj-y += fbdev/
63860 diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
63862 --- a/drivers/video/backlight/pwm_bl.c
63864 @@ -603,6 +603,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
63865 pb->scale = data->max_brightness;
63868 + pwm_adjust_config(pb->pwm);
63870 pb->lth_brightness = data->lth_brightness * (div_u64(state.period,
63871 pb->scale));