> Date: Fri, 12 Jul 2019 14:27:15 +1000
> From: Jonathan Gray <[email protected]>
>
> Use SMBIOS data for panel orientation. Uses BIOS dates when other
> strings are generic.
>
> There are orientation quirks in drm_panel_orientation_quirks.c for:
> Acer One 10 (S1003)
> Asus T100HA
> GPD MicroPC (generic strings, also match on bios date)
> GPD Pocket 2 (generic strings, also match on bios date)
> GPD Win (same note on DMI match as GPD Pocket)
> I.T.Works TW891
> Lenovo Ideapad Miix 320
> VIOS LTH17
>
> This codepath is also called from
>
> i915/vlv_dsi.c with the call to
> drm_connector_init_panel_orientation_property().
Still works on my Asus T100HA.
ok kettenis@
> Index: arch/amd64/amd64/bios.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 bios.c
> --- arch/amd64/amd64/bios.c 23 Oct 2018 17:51:32 -0000 1.37
> +++ arch/amd64/amd64/bios.c 12 Jul 2019 01:57:08 -0000
> @@ -67,6 +67,8 @@ const char *smbios_uninfo[] = {
> "SYS-"
> };
>
> +char smbios_bios_date[64];
> +
> int
> bios_match(struct device *parent, void *match , void *aux)
> {
> @@ -141,8 +143,11 @@ bios_attach(struct device *parent, struc
> printf(" version \"%s\"",
> fixstring(scratch));
> if ((smbios_get_string(&bios, sb->release,
> - scratch, sizeof(scratch))) != NULL)
> + scratch, sizeof(scratch))) != NULL) {
> + strlcpy(smbios_bios_date, fixstring(scratch),
> + sizeof(smbios_bios_date));
> printf(" date %s", fixstring(scratch));
> + }
> }
>
> smbios_info(sc->sc_dev.dv_xname);
> Index: arch/i386/i386/bios.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/i386/i386/bios.c,v
> retrieving revision 1.120
> diff -u -p -r1.120 bios.c
> --- arch/i386/i386/bios.c 23 Oct 2018 17:51:32 -0000 1.120
> +++ arch/i386/i386/bios.c 12 Jul 2019 03:45:03 -0000
> @@ -140,6 +140,8 @@ const char *smbios_uninfo[] = {
> };
>
>
> +char smbios_bios_date[64];
> +
> int
> biosprobe(struct device *parent, void *match, void *aux)
> {
> @@ -305,8 +307,12 @@ biosattach(struct device *parent, struct
> printf(" version \"%s\"",
> fixstring(scratch));
> if ((smbios_get_string(&bios, sb->release,
> - scratch, sizeof(scratch))) != NULL)
> + scratch, sizeof(scratch))) != NULL) {
> + strlcpy(smbios_bios_date,
> + fixstring(scratch),
> + sizeof(smbios_bios_date));
> printf(" date %s", fixstring(scratch));
> + }
> }
> smbios_info(sc->sc_dev.dv_xname);
>
> Index: dev/pci/drm/drm_linux.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/drm_linux.c,v
> retrieving revision 1.43
> diff -u -p -r1.43 drm_linux.c
> --- dev/pci/drm/drm_linux.c 10 Jul 2019 16:43:19 -0000 1.43
> +++ dev/pci/drm/drm_linux.c 12 Jul 2019 03:46:54 -0000
> @@ -394,6 +394,34 @@ dmi_found(const struct dmi_system_id *ds
> return true;
> }
>
> +const struct dmi_system_id *
> +dmi_first_match(const struct dmi_system_id *sysid)
> +{
> + const struct dmi_system_id *dsi;
> +
> + for (dsi = sysid; dsi->matches[0].slot != 0 ; dsi++) {
> + if (dmi_found(dsi))
> + return dsi;
> + }
> +
> + return NULL;
> +}
> +
> +#ifdef CONFIG_DMI
> +extern char smbios_bios_date[];
> +#endif
> +
> +const char *
> +dmi_get_system_info(int slot)
> +{
> + WARN_ON(slot != DMI_BIOS_DATE);
> +#ifdef CONFIG_DMI
> + if (slot == DMI_BIOS_DATE)
> + return smbios_bios_date;
> +#endif
> + return NULL;
> +}
> +
> int
> dmi_check_system(const struct dmi_system_id *sysid)
> {
> Index: dev/pci/drm/i915/i915_drv.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.c,v
> retrieving revision 1.118
> diff -u -p -r1.118 i915_drv.c
> --- dev/pci/drm/i915/i915_drv.c 8 May 2019 15:55:56 -0000 1.118
> +++ dev/pci/drm/i915/i915_drv.c 12 Jul 2019 03:50:53 -0000
> @@ -45,6 +45,7 @@
> #include <drm/drm_crtc_helper.h>
> #include <drm/drm_atomic_helper.h>
> #include <drm/i915_drm.h>
> +#include <drm/drm_utils.h>
>
> #include "i915_drv.h"
> #include "i915_trace.h"
> @@ -3598,6 +3599,7 @@ inteldrm_attachhook(struct device *self)
> struct wsemuldisplaydev_attach_args aa;
> const struct drm_pcidev *id = dev_priv->id;
> struct drm_device *dev = &dev_priv->drm;
> + int orientation_quirk;
>
> if (i915_driver_load(dev_priv, id))
> goto fail;
> @@ -3613,24 +3615,14 @@ inteldrm_attachhook(struct device *self)
> inteldrm_init_backlight(dev_priv);
>
> ri->ri_flg = RI_CENTER | RI_WRONLY | RI_VCONS | RI_CLEAR;
> - if (ri->ri_width < ri->ri_height) {
> - pcireg_t subsys;
>
> -#define PCI_PRODUCT_ASUSTEK_T100HA 0x1bdd
> + orientation_quirk = drm_get_panel_orientation_quirk(ri->ri_width,
> + ri->ri_height);
> + if (orientation_quirk == DRM_MODE_PANEL_ORIENTATION_LEFT_UP)
> + ri->ri_flg |= RI_ROTATE_CCW;
> + else if (orientation_quirk == DRM_MODE_PANEL_ORIENTATION_RIGHT_UP)
> + ri->ri_flg |= RI_ROTATE_CW;
>
> - /*
> - * Asus T100HA needs to be rotated counter-clockwise.
> - * Everybody else seems to mount their panels the
> - * other way around.
> - */
> - subsys = pci_conf_read(dev_priv->pc, dev_priv->tag,
> - PCI_SUBSYS_ID_REG);
> - if (PCI_VENDOR(subsys) == PCI_VENDOR_ASUSTEK &&
> - PCI_PRODUCT(subsys) == PCI_PRODUCT_ASUSTEK_T100HA)
> - ri->ri_flg |= RI_ROTATE_CCW;
> - else
> - ri->ri_flg |= RI_ROTATE_CW;
> - }
> ri->ri_hw = dev_priv;
> rasops_init(ri, 160, 160);
>
> Index: dev/pci/drm/include/linux/dmi.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/dmi.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 dmi.h
> --- dev/pci/drm/include/linux/dmi.h 14 Apr 2019 10:14:53 -0000 1.1
> +++ dev/pci/drm/include/linux/dmi.h 11 Jul 2019 04:11:08 -0000
> @@ -8,5 +8,7 @@
>
> int dmi_check_system(const struct dmi_system_id *);
> bool dmi_match(int, const char *);
> +const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *);
> +const char *dmi_get_system_info(int);
>
> #endif
> Index: dev/pci/drm/include/linux/kconfig.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/kconfig.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 kconfig.h
> --- dev/pci/drm/include/linux/kconfig.h 21 May 2019 22:40:14 -0000
> 1.2
> +++ dev/pci/drm/include/linux/kconfig.h 12 Jul 2019 03:47:24 -0000
> @@ -36,4 +36,8 @@
> #define CONFIG_AGP 1
> #endif
>
> +#if defined(__amd64__) || defined(__i386__)
> +#define CONFIG_DMI 1
> +#endif
> +
> #endif
> Index: dev/pci/drm/include/linux/mod_devicetable.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/mod_devicetable.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 mod_devicetable.h
> --- dev/pci/drm/include/linux/mod_devicetable.h 14 Apr 2019 10:14:53
> -0000 1.1
> +++ dev/pci/drm/include/linux/mod_devicetable.h 12 Jul 2019 01:43:29
> -0000
> @@ -32,9 +32,10 @@ struct dmi_strmatch {
> };
>
> struct dmi_system_id {
> - int (*callback)(const struct dmi_system_id *);
> - const char *ident;
> - struct dmi_strmatch matches[4];
> + int (*callback)(const struct dmi_system_id *);
> + const char *ident;
> + struct dmi_strmatch matches[4];
> + void *driver_data;
> };
> #define DMI_MATCH(a, b) {(a), (b)}
> #define DMI_EXACT_MATCH(a, b) {(a), (b)}
>
>