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>
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEfxcpfMSgdnQMs+QqlvcN/ahKBwoFAl0CXtkACgkQlvcN/ahK
 BwpkGwf8CTfNtC5/09JdDx/AIiHyuBF87M0/u+G+PHlSNwpVGz4ot1kLDQ7KU04u
 2UttAR7TNfrl/c5dBSGhEnidpD7UTsU1zPSfizwkbnwcFpmOop8V16eVUtzvKvhk
 krwLsLbeYUAGopDF7LzY1XA3R0k9irMC+d7hJzZvlPb0g33hZBfeCKJDyFkcVV4t
 Aqvumg9gTVk2whIqpa+ICnWSp9wmaMIHSySpvfr61orXzrPPyCKb5yiXbiYrwhOA
 0JEEGN6hORBuox7x00/s7M/8UogwPa6xpOVfbtaLIs5Wapfd/5bgnh+WK3jU6Urm
 NIzwX/0k9OwCMYMTJgF+oV7ANetQOg==
 =BuMw
 -----END PGP SIGNATURE-----

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: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20190613143946.GA24233@art_vandelay
This commit is contained in:
Daniel Vetter 2019-06-13 22:44:21 +02:00
commit 744ed8cb8a
11 changed files with 121 additions and 21 deletions

View File

@ -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,
{ {
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_get_override_edid(connector);
override = drm_edid_duplicate(connector->edid_blob_ptr->data); if (override)
if (!override)
override = drm_load_edid_firmware(connector);
if (!IS_ERR_OR_NULL(override))
return override; return override;
if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)

View File

@ -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");

View File

@ -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 = {
.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[] = {
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[] = {
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"),

View File

@ -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);

View File

@ -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,
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)
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)

View File

@ -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,
/* 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 = {

View File

@ -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 {

View File

@ -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));

View File

@ -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.

View File

@ -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)
{ {
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)
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
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;

View File

@ -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);