mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-17 07:17:02 +07:00
Merge tag 'drm-msm-fixes-2018-04-25' of git://people.freedesktop.org/~robclark/linux into drm-fixes
A few fixes for 4.17.. thanks to Sean for helping pull together some of the display related fixes while I was off in compute-land. * tag 'drm-msm-fixes-2018-04-25' of git://people.freedesktop.org/~robclark/linux: drm/msm: don't deref error pointer in the msm_fbdev_create error path drm/msm/dsi: use correct enum in dsi_get_cmd_fmt drm/msm: Fix possible null dereference on failure of get_pages() drm/msm: Add modifier to mdp_get_format arguments drm/msm: Mark the crtc->state->event consumed drm/msm/dsi: implement auto PHY timing calculator for 10nm PHY drm/msm/dsi: check video mode engine status before waiting drm/msm/dsi: check return value for video done waits
This commit is contained in:
commit
14cdea8945
@ -351,6 +351,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
mdp4_crtc->event = crtc->state->event;
|
||||
crtc->state->event = NULL;
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
||||
blend_setup(crtc);
|
||||
|
@ -708,6 +708,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
mdp5_crtc->event = crtc->state->event;
|
||||
crtc->state->event = NULL;
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
||||
/*
|
||||
|
@ -171,7 +171,8 @@ uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats,
|
||||
return i;
|
||||
}
|
||||
|
||||
const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format)
|
||||
const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format,
|
||||
uint64_t modifier)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(formats); i++) {
|
||||
|
@ -98,7 +98,7 @@ struct mdp_format {
|
||||
#define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv)
|
||||
|
||||
uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
|
||||
const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format);
|
||||
const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier);
|
||||
|
||||
/* MDP capabilities */
|
||||
#define MDP_CAP_SMP BIT(0) /* Shared Memory Pool */
|
||||
|
@ -173,6 +173,7 @@ struct msm_dsi_host {
|
||||
|
||||
bool registered;
|
||||
bool power_on;
|
||||
bool enabled;
|
||||
int irq;
|
||||
};
|
||||
|
||||
@ -775,7 +776,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
|
||||
switch (mipi_fmt) {
|
||||
case MIPI_DSI_FMT_RGB888: return CMD_DST_FORMAT_RGB888;
|
||||
case MIPI_DSI_FMT_RGB666_PACKED:
|
||||
case MIPI_DSI_FMT_RGB666: return VID_DST_FORMAT_RGB666;
|
||||
case MIPI_DSI_FMT_RGB666: return CMD_DST_FORMAT_RGB666;
|
||||
case MIPI_DSI_FMT_RGB565: return CMD_DST_FORMAT_RGB565;
|
||||
default: return CMD_DST_FORMAT_RGB888;
|
||||
}
|
||||
@ -986,13 +987,19 @@ static void dsi_set_tx_power_mode(int mode, struct msm_dsi_host *msm_host)
|
||||
|
||||
static void dsi_wait4video_done(struct msm_dsi_host *msm_host)
|
||||
{
|
||||
u32 ret = 0;
|
||||
struct device *dev = &msm_host->pdev->dev;
|
||||
|
||||
dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 1);
|
||||
|
||||
reinit_completion(&msm_host->video_comp);
|
||||
|
||||
wait_for_completion_timeout(&msm_host->video_comp,
|
||||
ret = wait_for_completion_timeout(&msm_host->video_comp,
|
||||
msecs_to_jiffies(70));
|
||||
|
||||
if (ret <= 0)
|
||||
dev_err(dev, "wait for video done timed out\n");
|
||||
|
||||
dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0);
|
||||
}
|
||||
|
||||
@ -1001,7 +1008,7 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
|
||||
if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
|
||||
return;
|
||||
|
||||
if (msm_host->power_on) {
|
||||
if (msm_host->power_on && msm_host->enabled) {
|
||||
dsi_wait4video_done(msm_host);
|
||||
/* delay 4 ms to skip BLLP */
|
||||
usleep_range(2000, 4000);
|
||||
@ -2203,7 +2210,7 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
|
||||
* pm_runtime_put_autosuspend(&msm_host->pdev->dev);
|
||||
* }
|
||||
*/
|
||||
|
||||
msm_host->enabled = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2211,6 +2218,7 @@ int msm_dsi_host_disable(struct mipi_dsi_host *host)
|
||||
{
|
||||
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
|
||||
|
||||
msm_host->enabled = false;
|
||||
dsi_op_mode_config(msm_host,
|
||||
!!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), false);
|
||||
|
||||
|
@ -265,6 +265,115 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
|
||||
struct msm_dsi_phy_clk_request *clk_req)
|
||||
{
|
||||
const unsigned long bit_rate = clk_req->bitclk_rate;
|
||||
const unsigned long esc_rate = clk_req->escclk_rate;
|
||||
s32 ui, ui_x8, lpx;
|
||||
s32 tmax, tmin;
|
||||
s32 pcnt0 = 50;
|
||||
s32 pcnt1 = 50;
|
||||
s32 pcnt2 = 10;
|
||||
s32 pcnt3 = 30;
|
||||
s32 pcnt4 = 10;
|
||||
s32 pcnt5 = 2;
|
||||
s32 coeff = 1000; /* Precision, should avoid overflow */
|
||||
s32 hb_en, hb_en_ckln;
|
||||
s32 temp;
|
||||
|
||||
if (!bit_rate || !esc_rate)
|
||||
return -EINVAL;
|
||||
|
||||
timing->hs_halfbyte_en = 0;
|
||||
hb_en = 0;
|
||||
timing->hs_halfbyte_en_ckln = 0;
|
||||
hb_en_ckln = 0;
|
||||
|
||||
ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
|
||||
ui_x8 = ui << 3;
|
||||
lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
|
||||
|
||||
temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
|
||||
tmin = max_t(s32, temp, 0);
|
||||
temp = (95 * coeff) / ui_x8;
|
||||
tmax = max_t(s32, temp, 0);
|
||||
timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
|
||||
|
||||
temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
|
||||
tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
|
||||
tmax = (tmin > 255) ? 511 : 255;
|
||||
timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
|
||||
|
||||
tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
|
||||
temp = 105 * coeff + 12 * ui - 20 * coeff;
|
||||
tmax = (temp + 3 * ui) / ui_x8;
|
||||
timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
|
||||
|
||||
temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
|
||||
tmin = max_t(s32, temp, 0);
|
||||
temp = (85 * coeff + 6 * ui) / ui_x8;
|
||||
tmax = max_t(s32, temp, 0);
|
||||
timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
|
||||
|
||||
temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
|
||||
tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
|
||||
tmax = 255;
|
||||
timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
|
||||
|
||||
tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
|
||||
temp = 105 * coeff + 12 * ui - 20 * coeff;
|
||||
tmax = (temp / ui_x8) - 1;
|
||||
timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
|
||||
|
||||
temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
|
||||
timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
|
||||
|
||||
tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
|
||||
tmax = 255;
|
||||
timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
|
||||
|
||||
temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
|
||||
timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
|
||||
|
||||
temp = 60 * coeff + 52 * ui - 43 * ui;
|
||||
tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
|
||||
tmax = 63;
|
||||
timing->shared_timings.clk_post =
|
||||
linear_inter(tmax, tmin, pcnt2, 0, false);
|
||||
|
||||
temp = 8 * ui + (timing->clk_prepare << 3) * ui;
|
||||
temp += (((timing->clk_zero + 3) << 3) + 11) * ui;
|
||||
temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
|
||||
(((timing->hs_rqst_ckln << 3) + 8) * ui);
|
||||
tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
|
||||
tmax = 63;
|
||||
if (tmin > tmax) {
|
||||
temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
|
||||
timing->shared_timings.clk_pre = temp >> 1;
|
||||
timing->shared_timings.clk_pre_inc_by_2 = 1;
|
||||
} else {
|
||||
timing->shared_timings.clk_pre =
|
||||
linear_inter(tmax, tmin, pcnt2, 0, false);
|
||||
timing->shared_timings.clk_pre_inc_by_2 = 0;
|
||||
}
|
||||
|
||||
timing->ta_go = 3;
|
||||
timing->ta_sure = 0;
|
||||
timing->ta_get = 4;
|
||||
|
||||
DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
|
||||
timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
|
||||
timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
|
||||
timing->clk_trail, timing->clk_prepare, timing->hs_exit,
|
||||
timing->hs_zero, timing->hs_prepare, timing->hs_trail,
|
||||
timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
|
||||
timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
|
||||
timing->hs_prep_dly_ckln);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
|
||||
u32 bit_mask)
|
||||
{
|
||||
|
@ -101,6 +101,8 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
|
||||
struct msm_dsi_phy_clk_request *clk_req);
|
||||
int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
|
||||
struct msm_dsi_phy_clk_request *clk_req);
|
||||
int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
|
||||
struct msm_dsi_phy_clk_request *clk_req);
|
||||
void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
|
||||
u32 bit_mask);
|
||||
int msm_dsi_phy_init_common(struct msm_dsi_phy *phy);
|
||||
|
@ -79,34 +79,6 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
|
||||
dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04);
|
||||
}
|
||||
|
||||
static int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
|
||||
struct msm_dsi_phy_clk_request *clk_req)
|
||||
{
|
||||
/*
|
||||
* TODO: These params need to be computed, they're currently hardcoded
|
||||
* for a 1440x2560@60Hz panel with a byteclk of 100.618 Mhz, and a
|
||||
* default escape clock of 19.2 Mhz.
|
||||
*/
|
||||
|
||||
timing->hs_halfbyte_en = 0;
|
||||
timing->clk_zero = 0x1c;
|
||||
timing->clk_prepare = 0x07;
|
||||
timing->clk_trail = 0x07;
|
||||
timing->hs_exit = 0x23;
|
||||
timing->hs_zero = 0x21;
|
||||
timing->hs_prepare = 0x07;
|
||||
timing->hs_trail = 0x07;
|
||||
timing->hs_rqst = 0x05;
|
||||
timing->ta_sure = 0x00;
|
||||
timing->ta_go = 0x03;
|
||||
timing->ta_get = 0x04;
|
||||
|
||||
timing->shared_timings.clk_pre = 0x2d;
|
||||
timing->shared_timings.clk_post = 0x0d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
|
||||
struct msm_dsi_phy_clk_request *clk_req)
|
||||
{
|
||||
|
@ -183,7 +183,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
|
||||
hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
|
||||
vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
|
||||
|
||||
format = kms->funcs->get_format(kms, mode_cmd->pixel_format);
|
||||
format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
|
||||
mode_cmd->modifier[0]);
|
||||
if (!format) {
|
||||
dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
|
||||
(char *)&mode_cmd->pixel_format);
|
||||
|
@ -92,8 +92,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
|
||||
|
||||
if (IS_ERR(fb)) {
|
||||
dev_err(dev->dev, "failed to allocate fb\n");
|
||||
ret = PTR_ERR(fb);
|
||||
goto fail;
|
||||
return PTR_ERR(fb);
|
||||
}
|
||||
|
||||
bo = msm_framebuffer_bo(fb, 0);
|
||||
@ -151,13 +150,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
|
||||
|
||||
fail_unlock:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
fail:
|
||||
|
||||
if (ret) {
|
||||
if (fb)
|
||||
drm_framebuffer_remove(fb);
|
||||
}
|
||||
|
||||
drm_framebuffer_remove(fb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -132,17 +132,19 @@ static void put_pages(struct drm_gem_object *obj)
|
||||
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||
|
||||
if (msm_obj->pages) {
|
||||
/* For non-cached buffers, ensure the new pages are clean
|
||||
* because display controller, GPU, etc. are not coherent:
|
||||
*/
|
||||
if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
|
||||
dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
|
||||
msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
|
||||
if (msm_obj->sgt) {
|
||||
/* For non-cached buffers, ensure the new
|
||||
* pages are clean because display controller,
|
||||
* GPU, etc. are not coherent:
|
||||
*/
|
||||
if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
|
||||
dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
|
||||
msm_obj->sgt->nents,
|
||||
DMA_BIDIRECTIONAL);
|
||||
|
||||
if (msm_obj->sgt)
|
||||
sg_free_table(msm_obj->sgt);
|
||||
|
||||
kfree(msm_obj->sgt);
|
||||
kfree(msm_obj->sgt);
|
||||
}
|
||||
|
||||
if (use_pages(obj))
|
||||
drm_gem_put_pages(obj, msm_obj->pages, true, false);
|
||||
|
@ -48,8 +48,11 @@ struct msm_kms_funcs {
|
||||
/* functions to wait for atomic commit completed on each CRTC */
|
||||
void (*wait_for_crtc_commit_done)(struct msm_kms *kms,
|
||||
struct drm_crtc *crtc);
|
||||
/* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
|
||||
const struct msm_format *(*get_format)(struct msm_kms *kms,
|
||||
const uint32_t format,
|
||||
const uint64_t modifiers);
|
||||
/* misc: */
|
||||
const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format);
|
||||
long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
|
||||
struct drm_encoder *encoder);
|
||||
int (*set_split_display)(struct msm_kms *kms,
|
||||
|
Loading…
Reference in New Issue
Block a user