mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-23 11:04:44 +08:00
sun4i fixes on clk, division by zero and LVDS.
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJan8AiAAoJEEN0HIUfOBk0M3MP/RX26ihtgnSikYoJU1zdjs1w uX3ejVdgP24mhzN1iqBqKRJxnDNuOVlBn27qmcSFAW4ytUirq8Esx0FG5sQOyYZO kggvydpbrEQfa5jybcTrlS5nr8NXOfWaIQ33hCLzcsDttAnw/dEY0owhWGj4j5cO Nq1b4N85d0XC6XrbjGnqLz924qeS4JArOA9Ee/uBumNf0LsozpeYNKBeRf00KmQG V8ayzXLordcmQTm74Xm2LcSBH62c+tBeGNIiKlWI4U579AWopaWqPonIrAqItKrr rdRKkGBZ2nl3Am5fnSgiHmSdyMJrAhdwAlyZFWx0RkSTUQOUWSp+pRy6qM/Q2yC6 PC7KK6ZIBXKjtXgEJtpx0JKZJIkU0m4aJ4IN6LGSh22U1RgjZLSWuIev1lthHWeY AsUNahpbUUxVI3X/IU3I7K70E5zk5JHmOPBBqD7CvWftJPEQqGwd9fU+wynM5o+9 gjMxszhwnoUsdX22gL0E1X0Xvw/j5WE3KpTPFftu7dg+03ZXB6fSDoK/SDEwpXWX i8qbG7hRu7aZ4Gzp2376BVZq7EhzaPrNNfRPZtG6goXrhN2ZzRxSWceFD/XXVdzX 8QAWEXituDYA/pXQVEzsC73tjv3fstkbU6FyPOuG1Q+Hjqgtp+/dCo1hRkfvz7YV +eP78iV0oUq3EqSh0OzI =tIwH -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
f5732e66a7
@ -93,6 +93,8 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
|
||||
DRM_DEBUG_DRIVER("Disabling the CRTC\n");
|
||||
|
||||
drm_crtc_vblank_off(crtc);
|
||||
|
||||
sun4i_tcon_set_status(scrtc->tcon, encoder, false);
|
||||
|
||||
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");
|
||||
|
||||
sun4i_tcon_set_status(scrtc->tcon, encoder, true);
|
||||
|
||||
drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
||||
|
@ -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)
|
||||
{
|
||||
struct sun4i_dclk *dclk = hw_to_dclk(hw);
|
||||
u32 val = degrees / 120;
|
||||
|
||||
val <<= 28;
|
||||
|
||||
regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG,
|
||||
GENMASK(29, 28),
|
||||
degrees / 120);
|
||||
val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,
|
||||
|
||||
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);
|
||||
if (rounded_rate < rate)
|
||||
return MODE_CLOCK_LOW;
|
||||
|
@ -101,10 +101,12 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
if (enabled) {
|
||||
clk_prepare_enable(clk);
|
||||
else
|
||||
} else {
|
||||
clk_rate_exclusive_put(clk);
|
||||
clk_disable_unprepare(clk);
|
||||
}
|
||||
}
|
||||
|
||||
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
|
||||
@ -873,52 +875,56 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This can only be made optional since we've had DT nodes
|
||||
* without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and print a
|
||||
* warning.
|
||||
*/
|
||||
tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
|
||||
if (IS_ERR(tcon->lvds_rst)) {
|
||||
dev_err(dev, "Couldn't get our reset line\n");
|
||||
return PTR_ERR(tcon->lvds_rst);
|
||||
} else if (tcon->lvds_rst) {
|
||||
has_lvds_rst = true;
|
||||
reset_control_reset(tcon->lvds_rst);
|
||||
} else {
|
||||
has_lvds_rst = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This can only be made optional since we've had DT nodes
|
||||
* without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and print a
|
||||
* warning.
|
||||
*/
|
||||
if (tcon->quirks->has_lvds_alt) {
|
||||
tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
|
||||
if (IS_ERR(tcon->lvds_pll)) {
|
||||
if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
|
||||
has_lvds_alt = false;
|
||||
} else {
|
||||
dev_err(dev, "Couldn't get the LVDS PLL\n");
|
||||
return PTR_ERR(tcon->lvds_pll);
|
||||
}
|
||||
if (tcon->quirks->supports_lvds) {
|
||||
/*
|
||||
* This can only be made optional since we've had DT
|
||||
* nodes without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and
|
||||
* print a warning.
|
||||
*/
|
||||
tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
|
||||
if (IS_ERR(tcon->lvds_rst)) {
|
||||
dev_err(dev, "Couldn't get our reset line\n");
|
||||
return PTR_ERR(tcon->lvds_rst);
|
||||
} else if (tcon->lvds_rst) {
|
||||
has_lvds_rst = true;
|
||||
reset_control_reset(tcon->lvds_rst);
|
||||
} else {
|
||||
has_lvds_alt = true;
|
||||
has_lvds_rst = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_lvds_rst || (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
|
||||
dev_warn(dev,
|
||||
"Missing LVDS properties, Please upgrade your DT\n");
|
||||
dev_warn(dev, "LVDS output disabled\n");
|
||||
can_lvds = false;
|
||||
/*
|
||||
* This can only be made optional since we've had DT
|
||||
* nodes without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and
|
||||
* print a warning.
|
||||
*/
|
||||
if (tcon->quirks->has_lvds_alt) {
|
||||
tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
|
||||
if (IS_ERR(tcon->lvds_pll)) {
|
||||
if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
|
||||
has_lvds_alt = false;
|
||||
} else {
|
||||
dev_err(dev, "Couldn't get the LVDS PLL\n");
|
||||
return PTR_ERR(tcon->lvds_pll);
|
||||
}
|
||||
} else {
|
||||
has_lvds_alt = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_lvds_rst ||
|
||||
(tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
|
||||
dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
|
||||
dev_warn(dev, "LVDS output disabled\n");
|
||||
can_lvds = false;
|
||||
} else {
|
||||
can_lvds = true;
|
||||
}
|
||||
} else {
|
||||
can_lvds = true;
|
||||
can_lvds = false;
|
||||
}
|
||||
|
||||
ret = sun4i_tcon_init_clocks(dev, tcon);
|
||||
@ -1137,7 +1143,7 @@ static const struct sun4i_tcon_quirks sun8i_a33_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 = {
|
||||
|
@ -175,6 +175,7 @@ struct sun4i_tcon_quirks {
|
||||
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 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 */
|
||||
int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
|
||||
|
Loading…
Reference in New Issue
Block a user