Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5732e66 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2018-03-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

sun4i fixes on clk, division by zero and LVDS.

* tag 'drm-misc-fixes-2018-03-07' of git://anongit.freedesktop.org/drm/drm-misc:
  drm/sun4i: crtc: Call drm_crtc_vblank_on / drm_crtc_vblank_off
  drm/sun4i: rgb: Fix potential division by zero
  drm/sun4i: tcon: Reduce the scope of the LVDS error a bit
  drm/sun4i: Release exclusive clock lock when disabling TCON
  drm/sun4i: Fix dclk_set_phase
parents aa87d62f fd00c4ee
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -93,6 +93,8 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,


	DRM_DEBUG_DRIVER("Disabling the CRTC\n");
	DRM_DEBUG_DRIVER("Disabling the CRTC\n");


	drm_crtc_vblank_off(crtc);

	sun4i_tcon_set_status(scrtc->tcon, encoder, false);
	sun4i_tcon_set_status(scrtc->tcon, encoder, false);


	if (crtc->state->event && !crtc->state->active) {
	if (crtc->state->event && !crtc->state->active) {
@@ -113,6 +115,8 @@ static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc,
	DRM_DEBUG_DRIVER("Enabling the CRTC\n");
	DRM_DEBUG_DRIVER("Enabling the CRTC\n");


	sun4i_tcon_set_status(scrtc->tcon, encoder, true);
	sun4i_tcon_set_status(scrtc->tcon, encoder, true);

	drm_crtc_vblank_on(crtc);
}
}


static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
+4 −1
Original line number Original line Diff line number Diff line
@@ -132,10 +132,13 @@ static int sun4i_dclk_get_phase(struct clk_hw *hw)
static int sun4i_dclk_set_phase(struct clk_hw *hw, int degrees)
static int sun4i_dclk_set_phase(struct clk_hw *hw, int degrees)
{
{
	struct sun4i_dclk *dclk = hw_to_dclk(hw);
	struct sun4i_dclk *dclk = hw_to_dclk(hw);
	u32 val = degrees / 120;

	val <<= 28;


	regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG,
	regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG,
			   GENMASK(29, 28),
			   GENMASK(29, 28),
			   degrees / 120);
			   val);


	return 0;
	return 0;
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -92,6 +92,8 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,


	DRM_DEBUG_DRIVER("Vertical parameters OK\n");
	DRM_DEBUG_DRIVER("Vertical parameters OK\n");


	tcon->dclk_min_div = 6;
	tcon->dclk_max_div = 127;
	rounded_rate = clk_round_rate(tcon->dclk, rate);
	rounded_rate = clk_round_rate(tcon->dclk, rate);
	if (rounded_rate < rate)
	if (rounded_rate < rate)
		return MODE_CLOCK_LOW;
		return MODE_CLOCK_LOW;
+49 −43
Original line number Original line Diff line number Diff line
@@ -101,11 +101,13 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
		return;
		return;
	}
	}


	if (enabled)
	if (enabled) {
		clk_prepare_enable(clk);
		clk_prepare_enable(clk);
	else
	} else {
		clk_rate_exclusive_put(clk);
		clk_disable_unprepare(clk);
		clk_disable_unprepare(clk);
	}
	}
}


static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
				       const struct drm_encoder *encoder,
				       const struct drm_encoder *encoder,
@@ -873,12 +875,13 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
		return ret;
		return ret;
	}
	}


	if (tcon->quirks->supports_lvds) {
		/*
		/*
	 * This can only be made optional since we've had DT nodes
		 * This can only be made optional since we've had DT
	 * without the LVDS reset properties.
		 * nodes without the LVDS reset properties.
		 *
		 *
	 * If the property is missing, just disable LVDS, and print a
		 * If the property is missing, just disable LVDS, and
	 * warning.
		 * print a warning.
		 */
		 */
		tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
		tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
		if (IS_ERR(tcon->lvds_rst)) {
		if (IS_ERR(tcon->lvds_rst)) {
@@ -892,11 +895,11 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
		}
		}


		/*
		/*
	 * This can only be made optional since we've had DT nodes
		 * This can only be made optional since we've had DT
	 * without the LVDS reset properties.
		 * nodes without the LVDS reset properties.
		 *
		 *
	 * If the property is missing, just disable LVDS, and print a
		 * If the property is missing, just disable LVDS, and
	 * warning.
		 * print a warning.
		 */
		 */
		if (tcon->quirks->has_lvds_alt) {
		if (tcon->quirks->has_lvds_alt) {
			tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
			tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
@@ -912,14 +915,17 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
			}
			}
		}
		}


	if (!has_lvds_rst || (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
		if (!has_lvds_rst ||
		dev_warn(dev,
		    (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
			 "Missing LVDS properties, Please upgrade your DT\n");
			dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
			dev_warn(dev, "LVDS output disabled\n");
			dev_warn(dev, "LVDS output disabled\n");
			can_lvds = false;
			can_lvds = false;
		} else {
		} else {
			can_lvds = true;
			can_lvds = true;
		}
		}
	} else {
		can_lvds = false;
	}


	ret = sun4i_tcon_init_clocks(dev, tcon);
	ret = sun4i_tcon_init_clocks(dev, tcon);
	if (ret) {
	if (ret) {
@@ -1137,7 +1143,7 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
};
};


static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
	/* nothing is supported */
	.supports_lvds		= true,
};
};


static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
+1 −0
Original line number Original line Diff line number Diff line
@@ -175,6 +175,7 @@ struct sun4i_tcon_quirks {
	bool	has_channel_1;	/* a33 does not have channel 1 */
	bool	has_channel_1;	/* a33 does not have channel 1 */
	bool	has_lvds_alt;	/* Does the LVDS clock have a parent other than the TCON clock? */
	bool	has_lvds_alt;	/* Does the LVDS clock have a parent other than the TCON clock? */
	bool	needs_de_be_mux; /* sun6i needs mux to select backend */
	bool	needs_de_be_mux; /* sun6i needs mux to select backend */
	bool	supports_lvds;   /* Does the TCON support an LVDS output? */


	/* callback to handle tcon muxing options */
	/* callback to handle tcon muxing options */
	int	(*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
	int	(*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);