summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2017-07-02 20:58:55 +0000
committerkettenis <kettenis@openbsd.org>2017-07-02 20:58:55 +0000
commit1a8d1b186933499f19f7744e5c90f4d72bf9fdcd (patch)
treee3b33c7784764c90c27bc52be0771e13197725df
parentre-enable PAT (diff)
downloadwireguard-openbsd-1a8d1b186933499f19f7744e5c90f4d72bf9fdcd.tar.xz
wireguard-openbsd-1a8d1b186933499f19f7744e5c90f4d72bf9fdcd.zip
Enable MIPI/DSI support for inteldrm(4). Makes the display on my ASUS
Transformer Book T100HA work (with some ugly error/warning messages).
-rw-r--r--sys/dev/pci/drm/drm_linux.h41
-rw-r--r--sys/dev/pci/drm/drm_mipi_dsi.c944
-rw-r--r--sys/dev/pci/drm/drm_mipi_dsi.h2
-rw-r--r--sys/dev/pci/drm/drm_panel.c9
-rw-r--r--sys/dev/pci/drm/drm_panel.h2
-rw-r--r--sys/dev/pci/drm/files.drm11
-rw-r--r--sys/dev/pci/drm/i915/intel_bios.c8
-rw-r--r--sys/dev/pci/drm/i915/intel_display.c2
-rw-r--r--sys/dev/pci/drm/i915/intel_dsi.c16
-rw-r--r--sys/dev/pci/drm/i915/intel_dsi.h6
-rw-r--r--sys/dev/pci/drm/i915/intel_dsi_panel_vbt.c12
-rw-r--r--sys/dev/pci/drm/i915/intel_dsi_pll.c2
12 files changed, 1020 insertions, 35 deletions
diff --git a/sys/dev/pci/drm/drm_linux.h b/sys/dev/pci/drm/drm_linux.h
index 2c289e38d88..82910492e11 100644
--- a/sys/dev/pci/drm/drm_linux.h
+++ b/sys/dev/pci/drm/drm_linux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_linux.h,v 1.51 2017/07/01 16:14:10 kettenis Exp $ */
+/* $OpenBSD: drm_linux.h,v 1.52 2017/07/02 20:58:55 kettenis Exp $ */
/*
* Copyright (c) 2013, 2014, 2015 Mark Kettenis
*
@@ -266,6 +266,8 @@ bitmap_weight(void *p, u_int n)
#define IS_BUILTIN(x) 1
+struct device_node;
+
struct device_driver {
struct device *dev;
};
@@ -505,6 +507,7 @@ PTR_ERR_OR_ZERO(const void *ptr)
typedef struct rwlock rwlock_t;
typedef struct mutex spinlock_t;
#define DEFINE_SPINLOCK(x) struct mutex x
+#define DEFINE_MUTEX(x) struct rwlock x
static inline void
spin_lock_irqsave(struct mutex *mtxp, __unused unsigned long flags)
@@ -1897,6 +1900,14 @@ acpi_status acpi_get_table_with_size(const char *, int, struct acpi_table_header
#define acpi_video_register()
#define acpi_video_unregister()
+#define MIPI_DSI_V_SYNC_START 0x01
+#define MIPI_DSI_V_SYNC_END 0x11
+#define MIPI_DSI_H_SYNC_START 0x21
+#define MIPI_DSI_H_SYNC_END 0x31
+#define MIPI_DSI_COLOR_MODE_OFF 0x02
+#define MIPI_DSI_COLOR_MODE_ON 0x12
+#define MIPI_DSI_SHUTDOWN_PERIPHERAL 0x22
+#define MIPI_DSI_TURN_ON_PERIPHERAL 0x32
#define MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM 0x03
#define MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM 0x13
#define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23
@@ -1906,8 +1917,36 @@ acpi_status acpi_get_table_with_size(const char *, int, struct acpi_table_header
#define MIPI_DSI_DCS_SHORT_WRITE 0x05
#define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15
#define MIPI_DSI_DCS_READ 0x06
+#define MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE 0x37
+#define MIPI_DSI_END_OF_TRANSMISSION 0x08
+#define MIPI_DSI_NULL_PACKET 0x09
+#define MIPI_DSI_BLANKING_PACKET 0x19
#define MIPI_DSI_GENERIC_LONG_WRITE 0x29
#define MIPI_DSI_DCS_LONG_WRITE 0x39
+#define MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 0x0c
+#define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 0x1c
+#define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 0x2c
+#define MIPI_DSI_PACKED_PIXEL_STREAM_30 0x0d
+#define MIPI_DSI_PACKED_PIXEL_STREAM_36 0x1d
+#define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 0x3d
+#define MIPI_DSI_PACKED_PIXEL_STREAM_16 0x0e
+#define MIPI_DSI_PACKED_PIXEL_STREAM_18 0x1e
+#define MIPI_DSI_PIXEL_STREAM_3BYTE_18 0x2e
+#define MIPI_DSI_PACKED_PIXEL_STREAM_24 0x3e
+
+#define MIPI_DCS_NOP 0x00
+#define MIPI_DCS_SOFT_RESET 0x01
+#define MIPI_DCS_GET_POWER_MODE 0x0a
+#define MIPI_DCS_GET_PIXEL_FORMAT 0x0c
+#define MIPI_DCS_ENTER_SLEEP_MODE 0x10
+#define MIPI_DCS_EXIT_SLEEP_MODE 0x11
+#define MIPI_DCS_SET_DISPLAY_OFF 0x28
+#define MIPI_DCS_SET_DISPLAY_ON 0x29
+#define MIPI_DCS_SET_COLUMN_ADDRESS 0x2a
+#define MIPI_DCS_SET_PAGE_ADDRESS 0x2b
+#define MIPI_DCS_SET_TEAR_OFF 0x34
+#define MIPI_DCS_SET_TEAR_ON 0x35
+#define MIPI_DCS_SET_PIXEL_FORMAT 0x3a
struct pwm_device;
diff --git a/sys/dev/pci/drm/drm_mipi_dsi.c b/sys/dev/pci/drm/drm_mipi_dsi.c
new file mode 100644
index 00000000000..b256b123825
--- /dev/null
+++ b/sys/dev/pci/drm/drm_mipi_dsi.c
@@ -0,0 +1,944 @@
+/*
+ * MIPI DSI Bus
+ *
+ * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
+ * Andrzej Hajda <a.hajda@samsung.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dev/pci/drm/drm_linux.h>
+#include <dev/pci/drm/drm_mipi_dsi.h>
+
+#ifdef __linux__
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include <video/mipi_display.h>
+#endif
+
+/**
+ * DOC: dsi helpers
+ *
+ * These functions contain some common logic and helpers to deal with MIPI DSI
+ * peripherals.
+ *
+ * Helpers are provided for a number of standard MIPI DSI command as well as a
+ * subset of the MIPI DCS command set.
+ */
+
+#ifdef notyet
+
+static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
+{
+ return of_driver_match_device(dev, drv);
+}
+
+static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
+ .runtime_suspend = pm_generic_runtime_suspend,
+ .runtime_resume = pm_generic_runtime_resume,
+ .suspend = pm_generic_suspend,
+ .resume = pm_generic_resume,
+ .freeze = pm_generic_freeze,
+ .thaw = pm_generic_thaw,
+ .poweroff = pm_generic_poweroff,
+ .restore = pm_generic_restore,
+};
+
+static struct bus_type mipi_dsi_bus_type = {
+ .name = "mipi-dsi",
+ .match = mipi_dsi_device_match,
+ .pm = &mipi_dsi_device_pm_ops,
+};
+
+static int of_device_match(struct device *dev, void *data)
+{
+ return dev->of_node == data;
+}
+
+/**
+ * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
+ * device tree node
+ * @np: device tree node
+ *
+ * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no
+ * such device exists (or has not been registered yet).
+ */
+struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&mipi_dsi_bus_type, NULL, np, of_device_match);
+
+ return dev ? to_mipi_dsi_device(dev) : NULL;
+}
+EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
+
+static void mipi_dsi_dev_release(struct device *dev)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+
+ of_node_put(dev->of_node);
+ kfree(dsi);
+}
+
+static const struct device_type mipi_dsi_device_type = {
+ .release = mipi_dsi_dev_release,
+};
+
+static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
+{
+ struct mipi_dsi_device *dsi;
+
+ dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return ERR_PTR(-ENOMEM);
+
+ dsi->host = host;
+ dsi->dev.bus = &mipi_dsi_bus_type;
+ dsi->dev.parent = host->dev;
+ dsi->dev.type = &mipi_dsi_device_type;
+
+ device_initialize(&dsi->dev);
+
+ return dsi;
+}
+
+static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
+{
+ struct mipi_dsi_host *host = dsi->host;
+
+ dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), dsi->channel);
+
+ return device_add(&dsi->dev);
+}
+
+static struct mipi_dsi_device *
+of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
+{
+ struct mipi_dsi_device *dsi;
+ struct device *dev = host->dev;
+ int ret;
+ u32 reg;
+
+ ret = of_property_read_u32(node, "reg", &reg);
+ if (ret) {
+ dev_err(dev, "device node %s has no valid reg property: %d\n",
+ node->full_name, ret);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (reg > 3) {
+ dev_err(dev, "device node %s has invalid reg property: %u\n",
+ node->full_name, reg);
+ return ERR_PTR(-EINVAL);
+ }
+
+ dsi = mipi_dsi_device_alloc(host);
+ if (IS_ERR(dsi)) {
+ dev_err(dev, "failed to allocate DSI device %s: %ld\n",
+ node->full_name, PTR_ERR(dsi));
+ return dsi;
+ }
+
+ dsi->dev.of_node = of_node_get(node);
+ dsi->channel = reg;
+
+ ret = mipi_dsi_device_add(dsi);
+ if (ret) {
+ dev_err(dev, "failed to add DSI device %s: %d\n",
+ node->full_name, ret);
+ kfree(dsi);
+ return ERR_PTR(ret);
+ }
+
+ return dsi;
+}
+
+int mipi_dsi_host_register(struct mipi_dsi_host *host)
+{
+ struct device_node *node;
+
+ for_each_available_child_of_node(host->dev->of_node, node) {
+ /* skip nodes without reg property */
+ if (!of_find_property(node, "reg", NULL))
+ continue;
+ of_mipi_dsi_device_add(host, node);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_host_register);
+
+static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+
+ device_unregister(&dsi->dev);
+
+ return 0;
+}
+
+void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
+{
+ device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
+}
+EXPORT_SYMBOL(mipi_dsi_host_unregister);
+
+#endif
+
+/**
+ * mipi_dsi_attach - attach a DSI device to its DSI host
+ * @dsi: DSI peripheral
+ */
+int mipi_dsi_attach(struct mipi_dsi_device *dsi)
+{
+ const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+
+ if (!ops || !ops->attach)
+ return -ENOSYS;
+
+ return ops->attach(dsi->host, dsi);
+}
+EXPORT_SYMBOL(mipi_dsi_attach);
+
+/**
+ * mipi_dsi_detach - detach a DSI device from its DSI host
+ * @dsi: DSI peripheral
+ */
+int mipi_dsi_detach(struct mipi_dsi_device *dsi)
+{
+ const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+
+ if (!ops || !ops->detach)
+ return -ENOSYS;
+
+ return ops->detach(dsi->host, dsi);
+}
+EXPORT_SYMBOL(mipi_dsi_detach);
+
+static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
+ struct mipi_dsi_msg *msg)
+{
+ const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+
+ if (!ops || !ops->transfer)
+ return -ENOSYS;
+
+ if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
+ msg->flags |= MIPI_DSI_MSG_USE_LPM;
+
+ return ops->transfer(dsi->host, msg);
+}
+
+/**
+ * mipi_dsi_packet_format_is_short - check if a packet is of the short format
+ * @type: MIPI DSI data type of the packet
+ *
+ * Return: true if the packet for the given data type is a short packet, false
+ * otherwise.
+ */
+bool mipi_dsi_packet_format_is_short(u8 type)
+{
+ switch (type) {
+ case MIPI_DSI_V_SYNC_START:
+ case MIPI_DSI_V_SYNC_END:
+ case MIPI_DSI_H_SYNC_START:
+ case MIPI_DSI_H_SYNC_END:
+ case MIPI_DSI_END_OF_TRANSMISSION:
+ case MIPI_DSI_COLOR_MODE_OFF:
+ case MIPI_DSI_COLOR_MODE_ON:
+ case MIPI_DSI_SHUTDOWN_PERIPHERAL:
+ case MIPI_DSI_TURN_ON_PERIPHERAL:
+ case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
+ case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
+ case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
+ case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
+ case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
+ case MIPI_DSI_DCS_SHORT_WRITE:
+ case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+ case MIPI_DSI_DCS_READ:
+ case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(mipi_dsi_packet_format_is_short);
+
+/**
+ * mipi_dsi_packet_format_is_long - check if a packet is of the long format
+ * @type: MIPI DSI data type of the packet
+ *
+ * Return: true if the packet for the given data type is a long packet, false
+ * otherwise.
+ */
+bool mipi_dsi_packet_format_is_long(u8 type)
+{
+ switch (type) {
+ case MIPI_DSI_NULL_PACKET:
+ case MIPI_DSI_BLANKING_PACKET:
+ case MIPI_DSI_GENERIC_LONG_WRITE:
+ case MIPI_DSI_DCS_LONG_WRITE:
+ case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_30:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_36:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_16:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_18:
+ case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
+ case MIPI_DSI_PACKED_PIXEL_STREAM_24:
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
+
+/**
+ * mipi_dsi_create_packet - create a packet from a message according to the
+ * DSI protocol
+ * @packet: pointer to a DSI packet structure
+ * @msg: message to translate into a packet
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
+ const struct mipi_dsi_msg *msg)
+{
+ if (!packet || !msg)
+ return -EINVAL;
+
+ /* do some minimum sanity checking */
+ if (!mipi_dsi_packet_format_is_short(msg->type) &&
+ !mipi_dsi_packet_format_is_long(msg->type))
+ return -EINVAL;
+
+ if (msg->channel > 3)
+ return -EINVAL;
+
+ memset(packet, 0, sizeof(*packet));
+ packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
+
+ /* TODO: compute ECC if hardware support is not available */
+
+ /*
+ * Long write packets contain the word count in header bytes 1 and 2.
+ * The payload follows the header and is word count bytes long.
+ *
+ * Short write packets encode up to two parameters in header bytes 1
+ * and 2.
+ */
+ if (mipi_dsi_packet_format_is_long(msg->type)) {
+ packet->header[1] = (msg->tx_len >> 0) & 0xff;
+ packet->header[2] = (msg->tx_len >> 8) & 0xff;
+
+ packet->payload_length = msg->tx_len;
+ packet->payload = msg->tx_buf;
+ } else {
+ const u8 *tx = msg->tx_buf;
+
+ packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
+ packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
+ }
+
+ packet->size = sizeof(packet->header) + packet->payload_length;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_create_packet);
+
+/*
+ * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the
+ * the payload in a long packet transmitted from the peripheral back to the
+ * host processor
+ * @dsi: DSI peripheral device
+ * @value: the maximum size of the payload
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
+ u16 value)
+{
+ u8 tx[2] = { value & 0xff, value >> 8 };
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
+ .tx_len = sizeof(tx),
+ .tx_buf = tx,
+ };
+
+ return mipi_dsi_device_transfer(dsi, &msg);
+}
+EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
+
+/**
+ * mipi_dsi_generic_write() - transmit data using a generic write packet
+ * @dsi: DSI peripheral device
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * This function will automatically choose the right data type depending on
+ * the payload length.
+ *
+ * Return: The number of bytes transmitted on success or a negative error code
+ * on failure.
+ */
+ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
+ size_t size)
+{
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .tx_buf = payload,
+ .tx_len = size
+ };
+
+ switch (size) {
+ case 0:
+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
+ break;
+
+ case 1:
+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
+ break;
+
+ case 2:
+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
+ break;
+
+ default:
+ msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
+ break;
+ }
+
+ return mipi_dsi_device_transfer(dsi, &msg);
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write);
+
+/**
+ * mipi_dsi_generic_read() - receive data using a generic read packet
+ * @dsi: DSI peripheral device
+ * @params: buffer containing the request parameters
+ * @num_params: number of request parameters
+ * @data: buffer in which to return the received data
+ * @size: size of receive buffer
+ *
+ * This function will automatically choose the right data type depending on
+ * the number of parameters passed in.
+ *
+ * Return: The number of bytes successfully read or a negative error code on
+ * failure.
+ */
+ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
+ size_t num_params, void *data, size_t size)
+{
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .tx_len = num_params,
+ .tx_buf = params,
+ .rx_len = size,
+ .rx_buf = data
+ };
+
+ switch (num_params) {
+ case 0:
+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
+ break;
+
+ case 1:
+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
+ break;
+
+ case 2:
+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return mipi_dsi_device_transfer(dsi, &msg);
+}
+EXPORT_SYMBOL(mipi_dsi_generic_read);
+
+/**
+ * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
+ * @dsi: DSI peripheral device
+ * @data: buffer containing data to be transmitted
+ * @len: size of transmission buffer
+ *
+ * This function will automatically choose the right data type depending on
+ * the command payload length.
+ *
+ * Return: The number of bytes successfully transmitted or a negative error
+ * code on failure.
+ */
+ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
+ const void *data, size_t len)
+{
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .tx_buf = data,
+ .tx_len = len
+ };
+
+ switch (len) {
+ case 0:
+ return -EINVAL;
+
+ case 1:
+ msg.type = MIPI_DSI_DCS_SHORT_WRITE;
+ break;
+
+ case 2:
+ msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
+ break;
+
+ default:
+ msg.type = MIPI_DSI_DCS_LONG_WRITE;
+ break;
+ }
+
+ return mipi_dsi_device_transfer(dsi, &msg);
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
+
+/**
+ * mipi_dsi_dcs_write() - send DCS write command
+ * @dsi: DSI peripheral device
+ * @cmd: DCS command
+ * @data: buffer containing the command payload
+ * @len: command payload length
+ *
+ * This function will automatically choose the right data type depending on
+ * the command payload length.
+ *
+ * Return: The number of bytes successfully transmitted or a negative error
+ * code on failure.
+ */
+ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
+ const void *data, size_t len)
+{
+ ssize_t err;
+ size_t size;
+ u8 *tx;
+
+ if (len > 0) {
+ size = 1 + len;
+
+ tx = kmalloc(size, GFP_KERNEL);
+ if (!tx)
+ return -ENOMEM;
+
+ /* concatenate the DCS command byte and the payload */
+ tx[0] = cmd;
+ memcpy(&tx[1], data, len);
+ } else {
+ tx = &cmd;
+ size = 1;
+ }
+
+ err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
+
+ if (len > 0)
+ kfree(tx);
+
+ return err;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_write);
+
+/**
+ * mipi_dsi_dcs_read() - send DCS read request command
+ * @dsi: DSI peripheral device
+ * @cmd: DCS command
+ * @data: buffer in which to receive data
+ * @len: size of receive buffer
+ *
+ * Return: The number of bytes read or a negative error code on failure.
+ */
+ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
+ size_t len)
+{
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .type = MIPI_DSI_DCS_READ,
+ .tx_buf = &cmd,
+ .tx_len = 1,
+ .rx_buf = data,
+ .rx_len = len
+ };
+
+ return mipi_dsi_device_transfer(dsi, &msg);
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_read);
+
+/**
+ * mipi_dsi_dcs_nop() - send DCS nop packet
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_nop);
+
+/**
+ * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset);
+
+/**
+ * mipi_dsi_dcs_get_power_mode() - query the display module's current power
+ * mode
+ * @dsi: DSI peripheral device
+ * @mode: return location for the current power mode
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
+ sizeof(*mode));
+ if (err <= 0) {
+ if (err == 0)
+ err = -ENODATA;
+
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode);
+
+/**
+ * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
+ * data used by the interface
+ * @dsi: DSI peripheral device
+ * @format: return location for the pixel format
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
+ sizeof(*format));
+ if (err <= 0) {
+ if (err == 0)
+ err = -ENODATA;
+
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
+
+/**
+ * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
+ * display module except interface communication
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
+
+/**
+ * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
+ * module
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
+
+/**
+ * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
+ * display device
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
+
+/**
+ * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
+ * display device
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure
+ */
+int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
+
+/**
+ * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
+ * memory accessed by the host processor
+ * @dsi: DSI peripheral device
+ * @start: first column of frame memory
+ * @end: last column of frame memory
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
+ u16 end)
+{
+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
+ sizeof(payload));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
+
+/**
+ * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
+ * memory accessed by the host processor
+ * @dsi: DSI peripheral device
+ * @start: first page of frame memory
+ * @end: last page of frame memory
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
+ u16 end)
+{
+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
+ sizeof(payload));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
+
+/**
+ * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
+ * output signal on the TE signal line
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure
+ */
+int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
+
+/**
+ * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
+ * output signal on the TE signal line.
+ * @dsi: DSI peripheral device
+ * @mode: the Tearing Effect Output Line mode
+ *
+ * Return: 0 on success or a negative error code on failure
+ */
+int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
+ enum mipi_dsi_dcs_tear_mode mode)
+{
+ u8 value = mode;
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
+ sizeof(value));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
+
+/**
+ * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
+ * data used by the interface
+ * @dsi: DSI peripheral device
+ * @format: pixel format
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
+{
+ ssize_t err;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
+ sizeof(format));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
+
+#ifdef notyet
+
+static int mipi_dsi_drv_probe(struct device *dev)
+{
+ struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+
+ return drv->probe(dsi);
+}
+
+static int mipi_dsi_drv_remove(struct device *dev)
+{
+ struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+
+ return drv->remove(dsi);
+}
+
+static void mipi_dsi_drv_shutdown(struct device *dev)
+{
+ struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+
+ drv->shutdown(dsi);
+}
+
+/**
+ * mipi_dsi_driver_register_full() - register a driver for DSI devices
+ * @drv: DSI driver structure
+ * @owner: owner module
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv,
+ struct module *owner)
+{
+ drv->driver.bus = &mipi_dsi_bus_type;
+ drv->driver.owner = owner;
+
+ if (drv->probe)
+ drv->driver.probe = mipi_dsi_drv_probe;
+ if (drv->remove)
+ drv->driver.remove = mipi_dsi_drv_remove;
+ if (drv->shutdown)
+ drv->driver.shutdown = mipi_dsi_drv_shutdown;
+
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(mipi_dsi_driver_register_full);
+
+/**
+ * mipi_dsi_driver_unregister() - unregister a driver for DSI devices
+ * @drv: DSI driver structure
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(mipi_dsi_driver_unregister);
+
+static int __init mipi_dsi_bus_init(void)
+{
+ return bus_register(&mipi_dsi_bus_type);
+}
+postcore_initcall(mipi_dsi_bus_init);
+
+MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
+MODULE_DESCRIPTION("MIPI DSI Bus");
+MODULE_LICENSE("GPL and additional rights");
+
+#endif
diff --git a/sys/dev/pci/drm/drm_mipi_dsi.h b/sys/dev/pci/drm/drm_mipi_dsi.h
index f1d8d0dbb4f..dc0ff9f5687 100644
--- a/sys/dev/pci/drm/drm_mipi_dsi.h
+++ b/sys/dev/pci/drm/drm_mipi_dsi.h
@@ -12,7 +12,9 @@
#ifndef __DRM_MIPI_DSI_H__
#define __DRM_MIPI_DSI_H__
+#ifdef __linux__
#include <linux/device.h>
+#endif
struct mipi_dsi_host;
struct mipi_dsi_device;
diff --git a/sys/dev/pci/drm/drm_panel.c b/sys/dev/pci/drm/drm_panel.c
index 2ef988e037b..8eac0f2e92f 100644
--- a/sys/dev/pci/drm/drm_panel.c
+++ b/sys/dev/pci/drm/drm_panel.c
@@ -21,14 +21,17 @@
* DEALINGS IN THE SOFTWARE.
*/
+#ifdef __linux__
#include <linux/err.h>
#include <linux/module.h>
+#endif
-#include <drm/drm_crtc.h>
-#include <drm/drm_panel.h>
+#include <dev/pci/drm/drmP.h>
+#include <dev/pci/drm/drm_crtc.h>
+#include <dev/pci/drm/drm_panel.h>
static DEFINE_MUTEX(panel_lock);
-static LIST_HEAD(panel_list);
+static DRM_LIST_HEAD(panel_list);
void drm_panel_init(struct drm_panel *panel)
{
diff --git a/sys/dev/pci/drm/drm_panel.h b/sys/dev/pci/drm/drm_panel.h
index 13ff44b2889..110023fb4b4 100644
--- a/sys/dev/pci/drm/drm_panel.h
+++ b/sys/dev/pci/drm/drm_panel.h
@@ -24,7 +24,7 @@
#ifndef __DRM_PANEL_H__
#define __DRM_PANEL_H__
-#include <linux/list.h>
+#include <dev/pci/drm/drm_linux_list.h>
struct drm_connector;
struct drm_device;
diff --git a/sys/dev/pci/drm/files.drm b/sys/dev/pci/drm/files.drm
index 7e198bb063c..0e3acacb8ae 100644
--- a/sys/dev/pci/drm/files.drm
+++ b/sys/dev/pci/drm/files.drm
@@ -1,5 +1,5 @@
# $NetBSD: files.drm,v 1.2 2007/03/28 11:29:37 jmcneill Exp $
-# $OpenBSD: files.drm,v 1.36 2017/07/01 16:14:10 kettenis Exp $
+# $OpenBSD: files.drm,v 1.37 2017/07/02 20:58:55 kettenis Exp $
# direct rendering modules
define drmbase {[console = -1]}
@@ -29,8 +29,9 @@ file dev/pci/drm/drm_gem.c drm
file dev/pci/drm/drm_vma_manager.c drm
file dev/pci/drm/drm_linux.c drm
file dev/pci/drm/drm_cache.c drm & inteldrm
-#file dev/pci/drm/drm_panel.c drm
+file dev/pci/drm/drm_panel.c drm & inteldrm
file dev/pci/drm/drm_dp_mst_topology.c drm
+file dev/pci/drm/drm_mipi_dsi.c drm & inteldrm
file dev/pci/drm/linux_hdmi.c drm
file dev/pci/drm/linux_list_sort.c drm
@@ -79,9 +80,9 @@ file dev/pci/drm/i915/intel_ddi.c inteldrm
file dev/pci/drm/i915/intel_display.c inteldrm
file dev/pci/drm/i915/intel_dp.c inteldrm
file dev/pci/drm/i915/intel_dp_mst.c inteldrm
-#file dev/pci/drm/i915/intel_dsi.c inteldrm
-#file dev/pci/drm/i915/intel_dsi_panel_vbt.c inteldrm
-#file dev/pci/drm/i915/intel_dsi_pll.c inteldrm
+file dev/pci/drm/i915/intel_dsi.c inteldrm
+file dev/pci/drm/i915/intel_dsi_panel_vbt.c inteldrm
+file dev/pci/drm/i915/intel_dsi_pll.c inteldrm
file dev/pci/drm/i915/intel_dvo.c inteldrm
file dev/pci/drm/i915/intel_fbc.c inteldrm
file dev/pci/drm/i915/intel_fbdev.c inteldrm
diff --git a/sys/dev/pci/drm/i915/intel_bios.c b/sys/dev/pci/drm/i915/intel_bios.c
index 22bd406aa5f..ed4807fdad4 100644
--- a/sys/dev/pci/drm/i915/intel_bios.c
+++ b/sys/dev/pci/drm/i915/intel_bios.c
@@ -678,8 +678,6 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time;
}
-#ifdef notyet
-
static u8 *goto_next_sequence(u8 *data, int *size)
{
u16 len;
@@ -904,8 +902,6 @@ err:
memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence));
}
-#endif
-
static u8 translate_iboost(u8 val)
{
static const u8 mapping[] = { 1, 3, 7 }; /* See VBT spec */
@@ -1155,7 +1151,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
continue;
}
-#ifdef notyet
if (p_child->common.dvo_port >= DVO_PORT_MIPIA
&& p_child->common.dvo_port <= DVO_PORT_MIPID
&&p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT) {
@@ -1163,7 +1158,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
dev_priv->vbt.has_mipi = 1;
dev_priv->vbt.dsi.port = p_child->common.dvo_port;
}
-#endif
child_dev_ptr = dev_priv->vbt.child_dev + count;
count++;
@@ -1370,9 +1364,7 @@ intel_parse_bios(struct drm_device *dev)
parse_driver_features(dev_priv, bdb);
parse_edp(dev_priv, bdb);
parse_psr(dev_priv, bdb);
-#ifdef notyet
parse_mipi(dev_priv, bdb);
-#endif
parse_ddi_ports(dev_priv, bdb);
#ifdef __linux__
diff --git a/sys/dev/pci/drm/i915/intel_display.c b/sys/dev/pci/drm/i915/intel_display.c
index f48131e27f7..a77cd1f2186 100644
--- a/sys/dev/pci/drm/i915/intel_display.c
+++ b/sys/dev/pci/drm/i915/intel_display.c
@@ -14218,9 +14218,7 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_hdmi_init(dev, CHV_HDMID, PORT_D);
}
-#ifdef notyet
intel_dsi_init(dev);
-#endif
} else if (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) {
bool found = false;
diff --git a/sys/dev/pci/drm/i915/intel_dsi.c b/sys/dev/pci/drm/i915/intel_dsi.c
index 49335f836d9..3d06538e4e9 100644
--- a/sys/dev/pci/drm/i915/intel_dsi.c
+++ b/sys/dev/pci/drm/i915/intel_dsi.c
@@ -23,15 +23,17 @@
* Author: Jani Nikula <jani.nikula@intel.com>
*/
-#include <drm/drmP.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-#include <drm/i915_drm.h>
-#include <drm/drm_panel.h>
-#include <drm/drm_mipi_dsi.h>
+#include <dev/pci/drm/drmP.h>
+#include <dev/pci/drm/drm_atomic_helper.h>
+#include <dev/pci/drm/drm_crtc.h>
+#include <dev/pci/drm/drm_edid.h>
+#include <dev/pci/drm/i915_drm.h>
+#include <dev/pci/drm/drm_panel.h>
+#include <dev/pci/drm/drm_mipi_dsi.h>
+#ifdef __linux__
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
+#endif
#include "i915_drv.h"
#include "intel_drv.h"
#include "intel_dsi.h"
diff --git a/sys/dev/pci/drm/i915/intel_dsi.h b/sys/dev/pci/drm/i915/intel_dsi.h
index e6cb2523994..7ebbda2e87c 100644
--- a/sys/dev/pci/drm/i915/intel_dsi.h
+++ b/sys/dev/pci/drm/i915/intel_dsi.h
@@ -24,9 +24,9 @@
#ifndef _INTEL_DSI_H
#define _INTEL_DSI_H
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_mipi_dsi.h>
+#include <dev/pci/drm/drmP.h>
+#include <dev/pci/drm/drm_crtc.h>
+#include <dev/pci/drm/drm_mipi_dsi.h>
#include "intel_drv.h"
/* Dual Link support */
diff --git a/sys/dev/pci/drm/i915/intel_dsi_panel_vbt.c b/sys/dev/pci/drm/i915/intel_dsi_panel_vbt.c
index a8912aecc31..066a74de58d 100644
--- a/sys/dev/pci/drm/i915/intel_dsi_panel_vbt.c
+++ b/sys/dev/pci/drm/i915/intel_dsi_panel_vbt.c
@@ -24,15 +24,17 @@
*
*/
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-#include <drm/i915_drm.h>
-#include <drm/drm_panel.h>
+#include <dev/pci/drm/drmP.h>
+#include <dev/pci/drm/drm_crtc.h>
+#include <dev/pci/drm/drm_edid.h>
+#include <dev/pci/drm/i915_drm.h>
+#include <dev/pci/drm/drm_panel.h>
+#ifdef __linux__
#include <linux/slab.h>
#include <video/mipi_display.h>
#include <asm/intel-mid.h>
#include <video/mipi_display.h>
+#endif
#include "i915_drv.h"
#include "intel_drv.h"
#include "intel_dsi.h"
diff --git a/sys/dev/pci/drm/i915/intel_dsi_pll.c b/sys/dev/pci/drm/i915/intel_dsi_pll.c
index cb3cf398621..6e48f72932d 100644
--- a/sys/dev/pci/drm/i915/intel_dsi_pll.c
+++ b/sys/dev/pci/drm/i915/intel_dsi_pll.c
@@ -25,7 +25,9 @@
* Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
*/
+#ifdef __linux__
#include <linux/kernel.h>
+#endif
#include "intel_drv.h"
#include "i915_drv.h"
#include "intel_dsi.h"