Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/sun4i: tcon: Move SoC specific quirks to a DT matched data structure

We already have some differences between the 2 supported SoCs.
More will be added as we support other SoCs. To avoid bloating
the probe function with even more conditionals, move the quirks
to a separate data structure that's tied to the compatible string.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

authored by

Chen-Yu Tsai and committed by
Maxime Ripard
91ea2f29 b3e0b2db

+25 -19
+18 -15
drivers/gpu/drm/sun4i/sun4i_tcon.c
··· 20 20 #include <linux/component.h> 21 21 #include <linux/ioport.h> 22 22 #include <linux/of_address.h> 23 + #include <linux/of_device.h> 23 24 #include <linux/of_graph.h> 24 25 #include <linux/of_irq.h> 25 26 #include <linux/regmap.h> ··· 63 62 return; 64 63 } 65 64 66 - WARN_ON(!tcon->has_channel_1); 65 + WARN_ON(!tcon->quirks->has_channel_1); 67 66 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 68 67 SUN4I_TCON1_CTL_TCON_ENABLE, 0); 69 68 clk_disable_unprepare(tcon->sclk1); ··· 81 80 return; 82 81 } 83 82 84 - WARN_ON(!tcon->has_channel_1); 83 + WARN_ON(!tcon->quirks->has_channel_1); 85 84 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 86 85 SUN4I_TCON1_CTL_TCON_ENABLE, 87 86 SUN4I_TCON1_CTL_TCON_ENABLE); ··· 203 202 u8 clk_delay; 204 203 u32 val; 205 204 206 - WARN_ON(!tcon->has_channel_1); 205 + WARN_ON(!tcon->quirks->has_channel_1); 207 206 208 207 /* Adjust clock delay */ 209 208 clk_delay = sun4i_tcon_get_clk_delay(mode, 1); ··· 267 266 /* 268 267 * FIXME: Undocumented bits 269 268 */ 270 - if (tcon->has_mux) 269 + if (tcon->quirks->has_unknown_mux) 271 270 regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, 1); 272 271 } 273 272 EXPORT_SYMBOL(sun4i_tcon1_mode_set); ··· 328 327 return PTR_ERR(tcon->sclk0); 329 328 } 330 329 331 - if (tcon->has_channel_1) { 330 + if (tcon->quirks->has_channel_1) { 332 331 tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); 333 332 if (IS_ERR(tcon->sclk1)) { 334 333 dev_err(dev, "Couldn't get the TCON channel 1 clock\n"); ··· 488 487 drv->tcon = tcon; 489 488 tcon->drm = drm; 490 489 tcon->dev = dev; 491 - 492 - if (of_device_is_compatible(dev->of_node, "allwinner,sun5i-a13-tcon")) { 493 - tcon->has_mux = true; 494 - tcon->has_channel_1 = true; 495 - } else { 496 - tcon->has_mux = false; 497 - tcon->has_channel_1 = false; 498 - } 490 + tcon->quirks = of_device_get_match_data(dev); 499 491 500 492 tcon->lcd_rst = devm_reset_control_get(dev, "lcd"); 501 493 if (IS_ERR(tcon->lcd_rst)) { ··· 582 588 return 0; 583 589 } 584 590 591 + static const struct sun4i_tcon_quirks sun5i_a13_quirks = { 592 + .has_unknown_mux = true, 593 + .has_channel_1 = true, 594 + }; 595 + 596 + static const struct sun4i_tcon_quirks sun8i_a33_quirks = { 597 + /* nothing is supported */ 598 + }; 599 + 585 600 static const struct of_device_id sun4i_tcon_of_table[] = { 586 - { .compatible = "allwinner,sun5i-a13-tcon" }, 587 - { .compatible = "allwinner,sun8i-a33-tcon" }, 601 + { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, 602 + { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, 588 603 { } 589 604 }; 590 605 MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
+7 -4
drivers/gpu/drm/sun4i/sun4i_tcon.h
··· 142 142 143 143 #define SUN4I_TCON_MAX_CHANNELS 2 144 144 145 + struct sun4i_tcon_quirks { 146 + bool has_unknown_mux; /* sun5i has undocumented mux */ 147 + bool has_channel_1; /* a33 does not have channel 1 */ 148 + }; 149 + 145 150 struct sun4i_tcon { 146 151 struct device *dev; 147 152 struct drm_device *drm; ··· 165 160 /* Reset control */ 166 161 struct reset_control *lcd_rst; 167 162 168 - /* Platform adjustments */ 169 - bool has_mux; 170 - 171 163 struct drm_panel *panel; 172 164 173 - bool has_channel_1; 165 + /* Platform adjustments */ 166 + const struct sun4i_tcon_quirks *quirks; 174 167 }; 175 168 176 169 struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node);