Commit 744ed8cb authored by Daniel Vetter's avatar Daniel Vetter

Merge tag 'drm-misc-fixes-2019-06-13' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

Sean writes:

meson: A few G12A fixes across the driver (Neil)
quirks: A couple quirks for GPD devices (Hans)
gem_shmem: Use writecombine when vmapping non-dmabuf BOs (Boris)
panfrost: A couple tweaks to requiring devfreq (Neil & Ezequiel)
edid: Ensure we return the override mode when ddc probe fails (Jani)

Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Boris Brezillon <boris.brezillon@collabora.com>
Cc: Ezequiel Garcia <ezequiel@collabora.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20190613143946.GA24233@art_vandelay
parents febe8030 48eaeb76
...@@ -1570,6 +1570,50 @@ static void connector_bad_edid(struct drm_connector *connector, ...@@ -1570,6 +1570,50 @@ static void connector_bad_edid(struct drm_connector *connector,
} }
} }
/* Get override or firmware EDID */
static struct edid *drm_get_override_edid(struct drm_connector *connector)
{
struct edid *override = NULL;
if (connector->override_edid)
override = drm_edid_duplicate(connector->edid_blob_ptr->data);
if (!override)
override = drm_load_edid_firmware(connector);
return IS_ERR(override) ? NULL : override;
}
/**
* drm_add_override_edid_modes - add modes from override/firmware EDID
* @connector: connector we're probing
*
* Add modes from the override/firmware EDID, if available. Only to be used from
* drm_helper_probe_single_connector_modes() as a fallback for when DDC probe
* failed during drm_get_edid() and caused the override/firmware EDID to be
* skipped.
*
* Return: The number of modes added or 0 if we couldn't find any.
*/
int drm_add_override_edid_modes(struct drm_connector *connector)
{
struct edid *override;
int num_modes = 0;
override = drm_get_override_edid(connector);
if (override) {
drm_connector_update_edid_property(connector, override);
num_modes = drm_add_edid_modes(connector, override);
kfree(override);
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] adding %d modes via fallback override/firmware EDID\n",
connector->base.id, connector->name, num_modes);
}
return num_modes;
}
EXPORT_SYMBOL(drm_add_override_edid_modes);
/** /**
* drm_do_get_edid - get EDID data using a custom EDID block read function * drm_do_get_edid - get EDID data using a custom EDID block read function
* @connector: connector we're probing * @connector: connector we're probing
...@@ -1597,15 +1641,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, ...@@ -1597,15 +1641,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
{ {
int i, j = 0, valid_extensions = 0; int i, j = 0, valid_extensions = 0;
u8 *edid, *new; u8 *edid, *new;
struct edid *override = NULL; struct edid *override;
if (connector->override_edid)
override = drm_edid_duplicate(connector->edid_blob_ptr->data);
if (!override)
override = drm_load_edid_firmware(connector);
if (!IS_ERR_OR_NULL(override)) override = drm_get_override_edid(connector);
if (override)
return override; return override;
if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
......
...@@ -255,7 +255,8 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem) ...@@ -255,7 +255,8 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem)
if (obj->import_attach) if (obj->import_attach)
shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf);
else else
shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, VM_MAP, PAGE_KERNEL); shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT,
VM_MAP, pgprot_writecombine(PAGE_KERNEL));
if (!shmem->vaddr) { if (!shmem->vaddr) {
DRM_DEBUG_KMS("Failed to vmap pages\n"); DRM_DEBUG_KMS("Failed to vmap pages\n");
......
...@@ -42,6 +42,14 @@ static const struct drm_dmi_panel_orientation_data asus_t100ha = { ...@@ -42,6 +42,14 @@ static const struct drm_dmi_panel_orientation_data asus_t100ha = {
.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
}; };
static const struct drm_dmi_panel_orientation_data gpd_micropc = {
.width = 720,
.height = 1280,
.bios_dates = (const char * const []){ "04/26/2019",
NULL },
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
};
static const struct drm_dmi_panel_orientation_data gpd_pocket = { static const struct drm_dmi_panel_orientation_data gpd_pocket = {
.width = 1200, .width = 1200,
.height = 1920, .height = 1920,
...@@ -50,6 +58,14 @@ static const struct drm_dmi_panel_orientation_data gpd_pocket = { ...@@ -50,6 +58,14 @@ static const struct drm_dmi_panel_orientation_data gpd_pocket = {
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
}; };
static const struct drm_dmi_panel_orientation_data gpd_pocket2 = {
.width = 1200,
.height = 1920,
.bios_dates = (const char * const []){ "06/28/2018", "08/28/2018",
"12/07/2018", NULL },
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
};
static const struct drm_dmi_panel_orientation_data gpd_win = { static const struct drm_dmi_panel_orientation_data gpd_win = {
.width = 720, .width = 720,
.height = 1280, .height = 1280,
...@@ -99,6 +115,14 @@ static const struct dmi_system_id orientation_data[] = { ...@@ -99,6 +115,14 @@ static const struct dmi_system_id orientation_data[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
}, },
.driver_data = (void *)&asus_t100ha, .driver_data = (void *)&asus_t100ha,
}, { /* GPD MicroPC (generic strings, also match on bios date) */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
},
.driver_data = (void *)&gpd_micropc,
}, { /* }, { /*
* GPD Pocket, note that the the DMI data is less generic then * GPD Pocket, note that the the DMI data is less generic then
* it seems, devices with a board-vendor of "AMI Corporation" * it seems, devices with a board-vendor of "AMI Corporation"
...@@ -112,6 +136,14 @@ static const struct dmi_system_id orientation_data[] = { ...@@ -112,6 +136,14 @@ static const struct dmi_system_id orientation_data[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
}, },
.driver_data = (void *)&gpd_pocket, .driver_data = (void *)&gpd_pocket,
}, { /* GPD Pocket 2 (generic strings, also match on bios date) */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
},
.driver_data = (void *)&gpd_pocket2,
}, { /* GPD Win (same note on DMI match as GPD Pocket) */ }, { /* GPD Win (same note on DMI match as GPD Pocket) */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
......
...@@ -479,6 +479,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, ...@@ -479,6 +479,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
count = (*connector_funcs->get_modes)(connector); count = (*connector_funcs->get_modes)(connector);
/*
* Fallback for when DDC probe failed in drm_get_edid() and thus skipped
* override/firmware EDID.
*/
if (count == 0 && connector->status == connector_status_connected)
count = drm_add_override_edid_modes(connector);
if (count == 0 && connector->status == connector_status_connected) if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768); count = drm_add_modes_noedid(connector, 1024, 768);
count += drm_helper_probe_add_cmdline_mode(connector); count += drm_helper_probe_add_cmdline_mode(connector);
......
...@@ -107,8 +107,6 @@ static void meson_g12a_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -107,8 +107,6 @@ static void meson_g12a_crtc_atomic_enable(struct drm_crtc *crtc,
priv->io_base + _REG(VPP_OUT_H_V_SIZE)); priv->io_base + _REG(VPP_OUT_H_V_SIZE));
drm_crtc_vblank_on(crtc); drm_crtc_vblank_on(crtc);
priv->viu.osd1_enabled = true;
} }
static void meson_crtc_atomic_enable(struct drm_crtc *crtc, static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
...@@ -137,8 +135,6 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -137,8 +135,6 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
priv->io_base + _REG(VPP_MISC)); priv->io_base + _REG(VPP_MISC));
drm_crtc_vblank_on(crtc); drm_crtc_vblank_on(crtc);
priv->viu.osd1_enabled = true;
} }
static void meson_g12a_crtc_atomic_disable(struct drm_crtc *crtc, static void meson_g12a_crtc_atomic_disable(struct drm_crtc *crtc,
...@@ -256,6 +252,8 @@ static void meson_g12a_crtc_enable_osd1(struct meson_drm *priv) ...@@ -256,6 +252,8 @@ static void meson_g12a_crtc_enable_osd1(struct meson_drm *priv)
writel_relaxed(priv->viu.osb_blend1_size, writel_relaxed(priv->viu.osb_blend1_size,
priv->io_base + priv->io_base +
_REG(VIU_OSD_BLEND_BLEND1_SIZE)); _REG(VIU_OSD_BLEND_BLEND1_SIZE));
writel_bits_relaxed(3 << 8, 3 << 8,
priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
} }
static void meson_crtc_enable_vd1(struct meson_drm *priv) static void meson_crtc_enable_vd1(struct meson_drm *priv)
......
...@@ -305,6 +305,8 @@ static void meson_plane_atomic_update(struct drm_plane *plane, ...@@ -305,6 +305,8 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
meson_plane->enabled = true; meson_plane->enabled = true;
} }
priv->viu.osd1_enabled = true;
spin_unlock_irqrestore(&priv->drm->event_lock, flags); spin_unlock_irqrestore(&priv->drm->event_lock, flags);
} }
...@@ -316,14 +318,14 @@ static void meson_plane_atomic_disable(struct drm_plane *plane, ...@@ -316,14 +318,14 @@ static void meson_plane_atomic_disable(struct drm_plane *plane,
/* Disable OSD1 */ /* Disable OSD1 */
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
writel_bits_relaxed(BIT(0) | BIT(21), 0, writel_bits_relaxed(3 << 8, 0,
priv->io_base + _REG(VIU_OSD1_CTRL_STAT)); priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
else else
writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0, writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
priv->io_base + _REG(VPP_MISC)); priv->io_base + _REG(VPP_MISC));
meson_plane->enabled = false; meson_plane->enabled = false;
priv->viu.osd1_enabled = false;
} }
static const struct drm_plane_helper_funcs meson_plane_helper_funcs = { static const struct drm_plane_helper_funcs meson_plane_helper_funcs = {
......
...@@ -503,8 +503,17 @@ void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m, ...@@ -503,8 +503,17 @@ void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
/* G12A HDMI PLL Needs specific parameters for 5.4GHz */ /* G12A HDMI PLL Needs specific parameters for 5.4GHz */
if (m >= 0xf7) { if (m >= 0xf7) {
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0xea68dc00); if (frac < 0x10000) {
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x65771290); regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
0x6a685c00);
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
0x11551293);
} else {
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
0xea68dc00);
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
0x65771290);
}
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000); regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x55540000); regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x55540000);
} else { } else {
......
...@@ -405,8 +405,7 @@ void meson_viu_init(struct meson_drm *priv) ...@@ -405,8 +405,7 @@ void meson_viu_init(struct meson_drm *priv)
0 << 16 | 0 << 16 |
1, 1,
priv->io_base + _REG(VIU_OSD_BLEND_CTRL)); priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
writel_relaxed(3 << 8 | writel_relaxed(1 << 20,
1 << 20,
priv->io_base + _REG(OSD1_BLEND_SRC_CTRL)); priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
writel_relaxed(1 << 20, writel_relaxed(1 << 20,
priv->io_base + _REG(OSD2_BLEND_SRC_CTRL)); priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
......
...@@ -10,6 +10,7 @@ config DRM_PANFROST ...@@ -10,6 +10,7 @@ config DRM_PANFROST
select IOMMU_IO_PGTABLE_LPAE select IOMMU_IO_PGTABLE_LPAE
select DRM_GEM_SHMEM_HELPER select DRM_GEM_SHMEM_HELPER
select PM_DEVFREQ select PM_DEVFREQ
select DEVFREQ_GOV_SIMPLE_ONDEMAND
help help
DRM driver for ARM Mali Midgard (T6xx, T7xx, T8xx) and DRM driver for ARM Mali Midgard (T6xx, T7xx, T8xx) and
Bifrost (G3x, G5x, G7x) GPUs. Bifrost (G3x, G5x, G7x) GPUs.
...@@ -140,7 +140,9 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) ...@@ -140,7 +140,9 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
return 0; return 0;
ret = dev_pm_opp_of_add_table(&pfdev->pdev->dev); ret = dev_pm_opp_of_add_table(&pfdev->pdev->dev);
if (ret) if (ret == -ENODEV) /* Optional, continue without devfreq */
return 0;
else if (ret)
return ret; return ret;
panfrost_devfreq_reset(pfdev); panfrost_devfreq_reset(pfdev);
...@@ -170,6 +172,9 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev) ...@@ -170,6 +172,9 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev)
{ {
int i; int i;
if (!pfdev->devfreq.devfreq)
return;
panfrost_devfreq_reset(pfdev); panfrost_devfreq_reset(pfdev);
for (i = 0; i < NUM_JOB_SLOTS; i++) for (i = 0; i < NUM_JOB_SLOTS; i++)
pfdev->devfreq.slot[i].busy = false; pfdev->devfreq.slot[i].busy = false;
...@@ -179,6 +184,9 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev) ...@@ -179,6 +184,9 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev)
void panfrost_devfreq_suspend(struct panfrost_device *pfdev) void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
{ {
if (!pfdev->devfreq.devfreq)
return;
devfreq_suspend_device(pfdev->devfreq.devfreq); devfreq_suspend_device(pfdev->devfreq.devfreq);
} }
...@@ -188,6 +196,9 @@ static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev, i ...@@ -188,6 +196,9 @@ static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev, i
ktime_t now; ktime_t now;
ktime_t last; ktime_t last;
if (!pfdev->devfreq.devfreq)
return;
now = ktime_get(); now = ktime_get();
last = pfdev->devfreq.slot[slot].time_last_update; last = pfdev->devfreq.slot[slot].time_last_update;
......
...@@ -471,6 +471,7 @@ struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, ...@@ -471,6 +471,7 @@ struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
struct i2c_adapter *adapter); struct i2c_adapter *adapter);
struct edid *drm_edid_duplicate(const struct edid *edid); struct edid *drm_edid_duplicate(const struct edid *edid);
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
int drm_add_override_edid_modes(struct drm_connector *connector);
u8 drm_match_cea_mode(const struct drm_display_mode *to_match); u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code); enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment