drm/sun4i: Create minimal multipliers and dividers
authorMaxime Ripard <maxime.ripard@free-electrons.com>
Thu, 21 Dec 2017 11:02:32 +0000 (12:02 +0100)
committerMaxime Ripard <maxime.ripard@free-electrons.com>
Thu, 4 Jan 2018 19:08:42 +0000 (20:08 +0100)
The various outputs the TCON can provide have different constraints on the
dotclock divider. Let's make them configurable by the various mode_set
functions.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Link: https://patchwork.freedesktop.org/patch/msgid/92ff5881c8f8674056d34458b2f264cd48d4e136.1513854122.git-series.maxime.ripard@free-electrons.com
drivers/gpu/drm/sun4i/sun4i_dotclock.c
drivers/gpu/drm/sun4i/sun4i_tcon.c
drivers/gpu/drm/sun4i/sun4i_tcon.h

index d401156490f36c890f49f23d1eab1b3f7691d108..023f39bda633de70825243b3a28335e2686091ed 100644 (file)
@@ -17,8 +17,9 @@
 #include "sun4i_dotclock.h"
 
 struct sun4i_dclk {
-       struct clk_hw   hw;
-       struct regmap   *regmap;
+       struct clk_hw           hw;
+       struct regmap           *regmap;
+       struct sun4i_tcon       *tcon;
 };
 
 static inline struct sun4i_dclk *hw_to_dclk(struct clk_hw *hw)
@@ -73,11 +74,13 @@ static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw,
 static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
                                  unsigned long *parent_rate)
 {
+       struct sun4i_dclk *dclk = hw_to_dclk(hw);
+       struct sun4i_tcon *tcon = dclk->tcon;
        unsigned long best_parent = 0;
        u8 best_div = 1;
        int i;
 
-       for (i = 6; i <= 127; i++) {
+       for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
                unsigned long ideal = rate * i;
                unsigned long rounded;
 
@@ -167,6 +170,7 @@ int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon)
        dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL);
        if (!dclk)
                return -ENOMEM;
+       dclk->tcon = tcon;
 
        init.name = clk_name;
        init.ops = &sun4i_dclk_ops;
index a1ed462c24307b8b79eea334efdab6a5a17027a2..41d325c0420fa234c546034ac40c5484afbf9feb 100644 (file)
@@ -177,6 +177,8 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
        u8 clk_delay;
        u32 val = 0;
 
+       tcon->dclk_min_div = 6;
+       tcon->dclk_max_div = 127;
        sun4i_tcon0_mode_set_common(tcon, mode);
 
        /* Adjust clock delay */
index 839266a3850590badb9cdfbb375c9d02ec03a24d..bd3ad7684870d30e2b6a94f84334d96f44cddbdd 100644 (file)
@@ -169,6 +169,8 @@ struct sun4i_tcon {
 
        /* Pixel clock */
        struct clk                      *dclk;
+       u8                              dclk_max_div;
+       u8                              dclk_min_div;
 
        /* Reset control */
        struct reset_control            *lcd_rst;