* [MIPI SEQ PARSING v2 PATCH 01/11] drm/i915: Adding the parsing logic for the i2c element
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-17 9:18 ` Jani Nikula
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 02/11] drm/i915: Updating asle structure with new fields Deepak M
` (9 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
From: vkorjani <vikas.korjani@intel.com>
New sequence element for i2c is been added in the
mipi sequence block of the VBT. This patch parses
and executes the i2c sequence.
v2: Add i2c_put_adapter call(Jani), rebase
Signed-off-by: vkorjani <vikas.korjani@intel.com>
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/intel_bios.c | 6 +++
drivers/gpu/drm/i915/intel_bios.h | 1 +
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 61 ++++++++++++++++++++++++++++
3 files changed, 68 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index c8acc29..0bf0942 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -714,6 +714,12 @@ static u8 *goto_next_sequence(u8 *data, int *size)
data += 3;
break;
+ case MIPI_SEQ_ELEM_I2C:
+ /* skip by this element payload size */
+ data += 7;
+ len = *data;
+ data += len + 1;
+ break;
default:
DRM_ERROR("Unknown element\n");
return NULL;
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 1b7417e..21a7f3f 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -956,6 +956,7 @@ enum mipi_seq_element {
MIPI_SEQ_ELEM_SEND_PKT,
MIPI_SEQ_ELEM_DELAY,
MIPI_SEQ_ELEM_GPIO,
+ MIPI_SEQ_ELEM_I2C,
MIPI_SEQ_ELEM_STATUS,
MIPI_SEQ_ELEM_MAX
};
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index a5e99ac..9989f61 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -31,6 +31,7 @@
#include <drm/drm_panel.h>
#include <linux/slab.h>
#include <video/mipi_display.h>
+#include <linux/i2c.h>
#include <asm/intel-mid.h>
#include <video/mipi_display.h>
#include "i915_drv.h"
@@ -104,6 +105,65 @@ static struct gpio_table gtable[] = {
{ GPIO_NC_11_PCONF0, GPIO_NC_11_PAD, 0}
};
+static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
+{
+ struct i2c_adapter *adapter;
+ int ret;
+ u8 reg_offset, payload_size, retries = 5;
+ struct i2c_msg msg;
+ u8 *transmit_buffer = NULL;
+ u8 flag = *data++;
+ u8 index = *data++;
+ u8 bus_number = *data++;
+ u16 slave_add = *(u16 *)(data);
+
+ data = data + 2;
+ reg_offset = *data++;
+ payload_size = *data++;
+
+ adapter = i2c_get_adapter(bus_number);
+
+ if (!adapter) {
+ DRM_ERROR("i2c_get_adapter(%u) failed, index:%u flag: %u\n",
+ (bus_number + 1), index, flag);
+ goto out;
+ }
+
+ transmit_buffer = kmalloc(1 + payload_size, GFP_TEMPORARY);
+
+ if (!transmit_buffer)
+ goto out;
+
+ transmit_buffer[0] = reg_offset;
+ memcpy(&transmit_buffer[1], data, (size_t)payload_size);
+
+ msg.addr = slave_add;
+ msg.flags = 0;
+ msg.len = payload_size + 1;
+ msg.buf = &transmit_buffer[0];
+
+ do {
+ ret = i2c_transfer(adapter, &msg, 1);
+ if (ret == 1)
+ break;
+ else if (ret == -EAGAIN)
+ usleep_range(1000, 2500);
+ else {
+ DRM_ERROR("i2c transfer failed, error code:%d", ret);
+ break;
+ }
+ } while (retries--);
+
+ if (retries == 0)
+ DRM_ERROR("i2c transfer failed, error code:%d", ret);
+out:
+ kfree(transmit_buffer);
+ i2c_put_adapter(adapter);
+
+ data = data + payload_size;
+ return data;
+}
+
static inline enum port intel_dsi_seq_port_to_port(u8 port)
{
return port ? PORT_C : PORT_A;
@@ -236,6 +296,7 @@ static const fn_mipi_elem_exec exec_elem[] = {
mipi_exec_send_packet,
mipi_exec_delay,
mipi_exec_gpio,
+ mipi_exec_i2c,
NULL, /* status read; later */
};
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 01/11] drm/i915: Adding the parsing logic for the i2c element
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 01/11] drm/i915: Adding the parsing logic for the i2c element Deepak M
@ 2015-09-17 9:18 ` Jani Nikula
2015-09-22 6:46 ` Deepak, M
0 siblings, 1 reply; 25+ messages in thread
From: Jani Nikula @ 2015-09-17 9:18 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
> From: vkorjani <vikas.korjani@intel.com>
>
> New sequence element for i2c is been added in the
> mipi sequence block of the VBT. This patch parses
> and executes the i2c sequence.
>
> v2: Add i2c_put_adapter call(Jani), rebase
>
> Signed-off-by: vkorjani <vikas.korjani@intel.com>
> Signed-off-by: Deepak M <m.deepak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_bios.c | 6 +++
> drivers/gpu/drm/i915/intel_bios.h | 1 +
> drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 61 ++++++++++++++++++++++++++++
> 3 files changed, 68 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index c8acc29..0bf0942 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -714,6 +714,12 @@ static u8 *goto_next_sequence(u8 *data, int *size)
>
> data += 3;
> break;
> + case MIPI_SEQ_ELEM_I2C:
> + /* skip by this element payload size */
> + data += 7;
> + len = *data;
> + data += len + 1;
> + break;
> default:
> DRM_ERROR("Unknown element\n");
> return NULL;
> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
> index 1b7417e..21a7f3f 100644
> --- a/drivers/gpu/drm/i915/intel_bios.h
> +++ b/drivers/gpu/drm/i915/intel_bios.h
> @@ -956,6 +956,7 @@ enum mipi_seq_element {
> MIPI_SEQ_ELEM_SEND_PKT,
> MIPI_SEQ_ELEM_DELAY,
> MIPI_SEQ_ELEM_GPIO,
> + MIPI_SEQ_ELEM_I2C,
> MIPI_SEQ_ELEM_STATUS,
Side note, MIPI_SEQ_ELEM_STATUS doesn't seem to be in spec.
> MIPI_SEQ_ELEM_MAX
> };
> diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> index a5e99ac..9989f61 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> @@ -31,6 +31,7 @@
> #include <drm/drm_panel.h>
> #include <linux/slab.h>
> #include <video/mipi_display.h>
> +#include <linux/i2c.h>
> #include <asm/intel-mid.h>
> #include <video/mipi_display.h>
> #include "i915_drv.h"
> @@ -104,6 +105,65 @@ static struct gpio_table gtable[] = {
> { GPIO_NC_11_PCONF0, GPIO_NC_11_PAD, 0}
> };
>
> +static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
> +{
> + struct i2c_adapter *adapter;
> + int ret;
> + u8 reg_offset, payload_size, retries = 5;
> + struct i2c_msg msg;
> + u8 *transmit_buffer = NULL;
> + u8 flag = *data++;
> + u8 index = *data++;
> + u8 bus_number = *data++;
> + u16 slave_add = *(u16 *)(data);
> +
> + data = data + 2;
> + reg_offset = *data++;
> + payload_size = *data++;
> +
> + adapter = i2c_get_adapter(bus_number);
> +
> + if (!adapter) {
> + DRM_ERROR("i2c_get_adapter(%u) failed, index:%u flag: %u\n",
> + (bus_number + 1), index, flag);
Why do you log bus_number + 1 instead of what was actually tried?
I don't see why the flag/index are useful for in the message, as they're
not relevant to the i2c_get_adapter failing.
> + goto out;
> + }
> +
> + transmit_buffer = kmalloc(1 + payload_size, GFP_TEMPORARY);
> +
> + if (!transmit_buffer)
> + goto out;
> +
> + transmit_buffer[0] = reg_offset;
> + memcpy(&transmit_buffer[1], data, (size_t)payload_size);
Why do you need the cast?
> +
> + msg.addr = slave_add;
> + msg.flags = 0;
> + msg.len = payload_size + 1;
> + msg.buf = &transmit_buffer[0];
> +
> + do {
> + ret = i2c_transfer(adapter, &msg, 1);
> + if (ret == 1)
> + break;
> + else if (ret == -EAGAIN)
> + usleep_range(1000, 2500);
> + else {
> + DRM_ERROR("i2c transfer failed, error code:%d", ret);
\n missing.
> + break;
> + }
> + } while (retries--);
> +
> + if (retries == 0)
Due to the way you post-decrement retries, you may end up here even if
the transfer succeeds on the last try.
You may also end up printing two error messages, if i2c_transfer fails
on the last try.
> + DRM_ERROR("i2c transfer failed, error code:%d", ret);
\n missing.
> +out:
> + kfree(transmit_buffer);
> + i2c_put_adapter(adapter);
> +
> + data = data + payload_size;
> + return data;
> +}
> +
> static inline enum port intel_dsi_seq_port_to_port(u8 port)
> {
> return port ? PORT_C : PORT_A;
> @@ -236,6 +296,7 @@ static const fn_mipi_elem_exec exec_elem[] = {
> mipi_exec_send_packet,
> mipi_exec_delay,
> mipi_exec_gpio,
> + mipi_exec_i2c,
> NULL, /* status read; later */
> };
>
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 01/11] drm/i915: Adding the parsing logic for the i2c element
2015-09-17 9:18 ` Jani Nikula
@ 2015-09-22 6:46 ` Deepak, M
0 siblings, 0 replies; 25+ messages in thread
From: Deepak, M @ 2015-09-22 6:46 UTC (permalink / raw)
To: Jani Nikula, intel-gfx@lists.freedesktop.org
>-----Original Message-----
>From: Jani Nikula [mailto:jani.nikula@linux.intel.com]
>Sent: Thursday, September 17, 2015 2:48 PM
>To: Deepak, M; intel-gfx@lists.freedesktop.org
>Cc: Deepak, M
>Subject: Re: [Intel-gfx] [MIPI SEQ PARSING v2 PATCH 01/11] drm/i915: Adding
>the parsing logic for the i2c element
>
>On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
>> From: vkorjani <vikas.korjani@intel.com>
>>
>> New sequence element for i2c is been added in the mipi sequence block
>> of the VBT. This patch parses and executes the i2c sequence.
>>
>> v2: Add i2c_put_adapter call(Jani), rebase
>>
>> Signed-off-by: vkorjani <vikas.korjani@intel.com>
>> Signed-off-by: Deepak M <m.deepak@intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_bios.c | 6 +++
>> drivers/gpu/drm/i915/intel_bios.h | 1 +
>> drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 61
>++++++++++++++++++++++++++++
>> 3 files changed, 68 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_bios.c
>> b/drivers/gpu/drm/i915/intel_bios.c
>> index c8acc29..0bf0942 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.c
>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>> @@ -714,6 +714,12 @@ static u8 *goto_next_sequence(u8 *data, int
>> *size)
>>
>> data += 3;
>> break;
>> + case MIPI_SEQ_ELEM_I2C:
>> + /* skip by this element payload size */
>> + data += 7;
>> + len = *data;
>> + data += len + 1;
>> + break;
>> default:
>> DRM_ERROR("Unknown element\n");
>> return NULL;
>> diff --git a/drivers/gpu/drm/i915/intel_bios.h
>> b/drivers/gpu/drm/i915/intel_bios.h
>> index 1b7417e..21a7f3f 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.h
>> +++ b/drivers/gpu/drm/i915/intel_bios.h
>> @@ -956,6 +956,7 @@ enum mipi_seq_element {
>> MIPI_SEQ_ELEM_SEND_PKT,
>> MIPI_SEQ_ELEM_DELAY,
>> MIPI_SEQ_ELEM_GPIO,
>> + MIPI_SEQ_ELEM_I2C,
>> MIPI_SEQ_ELEM_STATUS,
>
>Side note, MIPI_SEQ_ELEM_STATUS doesn't seem to be in spec.
>
>
>> MIPI_SEQ_ELEM_MAX
>> };
>> diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> index a5e99ac..9989f61 100644
>> --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> @@ -31,6 +31,7 @@
>> #include <drm/drm_panel.h>
>> #include <linux/slab.h>
>> #include <video/mipi_display.h>
>> +#include <linux/i2c.h>
>> #include <asm/intel-mid.h>
>> #include <video/mipi_display.h>
>> #include "i915_drv.h"
>> @@ -104,6 +105,65 @@ static struct gpio_table gtable[] = {
>> { GPIO_NC_11_PCONF0, GPIO_NC_11_PAD, 0} };
>>
>> +static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8
>> +*data) {
>> + struct i2c_adapter *adapter;
>> + int ret;
>> + u8 reg_offset, payload_size, retries = 5;
>> + struct i2c_msg msg;
>> + u8 *transmit_buffer = NULL;
>> + u8 flag = *data++;
>> + u8 index = *data++;
>> + u8 bus_number = *data++;
>> + u16 slave_add = *(u16 *)(data);
>> +
>> + data = data + 2;
>> + reg_offset = *data++;
>> + payload_size = *data++;
>> +
>> + adapter = i2c_get_adapter(bus_number);
>> +
>> + if (!adapter) {
>> + DRM_ERROR("i2c_get_adapter(%u) failed, index:%u flag:
>%u\n",
>> + (bus_number + 1), index, flag);
>
>Why do you log bus_number + 1 instead of what was actually tried?
[Deepak M] Will fix this.
>
>I don't see why the flag/index are useful for in the message, as they're not
>relevant to the i2c_get_adapter failing.
>
[Deepak M] Flag field is reserved and then the index is used for windows, for Linux these two can be skipped. Will not try to declare flag and index variable.
>> + goto out;
>> + }
>> +
>> + transmit_buffer = kmalloc(1 + payload_size, GFP_TEMPORARY);
>> +
>> + if (!transmit_buffer)
>> + goto out;
>> +
>> + transmit_buffer[0] = reg_offset;
>> + memcpy(&transmit_buffer[1], data, (size_t)payload_size);
>
>Why do you need the cast?
>
>> +
>> + msg.addr = slave_add;
>> + msg.flags = 0;
>> + msg.len = payload_size + 1;
>> + msg.buf = &transmit_buffer[0];
>> +
>> + do {
>> + ret = i2c_transfer(adapter, &msg, 1);
>> + if (ret == 1)
>> + break;
>> + else if (ret == -EAGAIN)
>> + usleep_range(1000, 2500);
>> + else {
>> + DRM_ERROR("i2c transfer failed, error code:%d", ret);
>
>\n missing.
>
>> + break;
>> + }
>> + } while (retries--);
>> +
>> + if (retries == 0)
>
>Due to the way you post-decrement retries, you may end up here even if the
>transfer succeeds on the last try.
>
>You may also end up printing two error messages, if i2c_transfer fails on the
>last try.
[Deepak M] okay, Will handle this.
>
>> + DRM_ERROR("i2c transfer failed, error code:%d", ret);
>
>\n missing.
>
>> +out:
>> + kfree(transmit_buffer);
>> + i2c_put_adapter(adapter);
>> +
>> + data = data + payload_size;
>> + return data;
>> +}
>> +
>> static inline enum port intel_dsi_seq_port_to_port(u8 port) {
>> return port ? PORT_C : PORT_A;
>> @@ -236,6 +296,7 @@ static const fn_mipi_elem_exec exec_elem[] = {
>> mipi_exec_send_packet,
>> mipi_exec_delay,
>> mipi_exec_gpio,
>> + mipi_exec_i2c,
>> NULL, /* status read; later */
>> };
>>
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>--
>Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread
* [MIPI SEQ PARSING v2 PATCH 02/11] drm/i915: Updating asle structure with new fields
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 01/11] drm/i915: Adding the parsing logic for the i2c element Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB Deepak M
` (8 subsequent siblings)
10 siblings, 0 replies; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/intel_opregion.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index cb1c657..f46231f 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -120,7 +120,9 @@ struct opregion_asle {
u64 fdss;
u32 fdsp;
u32 stat;
- u8 rsvd[70];
+ u64 rvda; /* Physical address of raw vbt data */
+ u32 rvds; /* Size of raw vbt data */
+ u8 rsvd[58];
} __packed;
/* Driver readiness indicator */
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 01/11] drm/i915: Adding the parsing logic for the i2c element Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 02/11] drm/i915: Updating asle structure with new fields Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-16 13:24 ` Jani Nikula
2015-09-17 12:10 ` Jani Nikula
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion Deepak M
` (7 subsequent siblings)
10 siblings, 2 replies; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
Currently the iomap for VBT works only if the size of the
VBT is less than 6KB, but if the size of the VBT exceeds
6KB than the physical address and the size of the VBT to
be iomapped is specified in the mailbox3 and is iomapped
accordingly.
v2: - Moving the validate_vbt to opregion file (Jani)
- Fix the i915_opregion() in debugfs (Jani)
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 24 ++-
drivers/gpu/drm/i915/i915_drv.h | 4 +
drivers/gpu/drm/i915/intel_bios.c | 49 +-----
drivers/gpu/drm/i915/intel_opregion.c | 279 +++++++++------------------------
drivers/gpu/drm/i915/intel_opregion.h | 230 +++++++++++++++++++++++++++
5 files changed, 329 insertions(+), 257 deletions(-)
create mode 100644 drivers/gpu/drm/i915/intel_opregion.h
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 41629fa..5534aa2 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -26,6 +26,8 @@
*
*/
+#include <linux/acpi.h>
+#include <acpi/video.h>
#include <linux/seq_file.h>
#include <linux/circ_buf.h>
#include <linux/ctype.h>
@@ -39,6 +41,7 @@
#include "intel_ringbuffer.h"
#include <drm/i915_drm.h>
#include "i915_drv.h"
+#include "intel_opregion.h"
enum {
ACTIVE_LIST,
@@ -1832,7 +1835,7 @@ static int i915_opregion(struct seq_file *m, void *unused)
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion;
- void *data = kmalloc(OPREGION_SIZE, GFP_KERNEL);
+ void *data = kmalloc(OPREGION_VBT_OFFSET, GFP_KERNEL);
int ret;
if (data == NULL)
@@ -1843,12 +1846,25 @@ static int i915_opregion(struct seq_file *m, void *unused)
goto out;
if (opregion->header) {
- memcpy_fromio(data, opregion->header, OPREGION_SIZE);
- seq_write(m, data, OPREGION_SIZE);
+ memcpy_fromio(data, opregion->header, OPREGION_VBT_OFFSET);
+ seq_write(m, data, OPREGION_VBT_OFFSET);
+ kfree(data);
+ if (opregion->asle->rvda) {
+ data = kmalloc(opregion->asle->rvds, GFP_KERNEL);
+ memcpy_fromio(data,
+ (const void __iomem *) opregion->asle->rvda,
+ opregion->asle->rvds);
+ seq_write(m, data, opregion->asle->rvds);
+ } else {
+ data = kmalloc(OPREGION_SIZE - OPREGION_VBT_OFFSET,
+ GFP_KERNEL);
+ memcpy_fromio(data, opregion->vbt,
+ OPREGION_SIZE - OPREGION_VBT_OFFSET);
+ seq_write(m, data, OPREGION_SIZE - OPREGION_VBT_OFFSET);
+ }
}
mutex_unlock(&dev->struct_mutex);
-
out:
kfree(data);
return 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1287007..507d57a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1780,6 +1780,7 @@ struct drm_i915_private {
struct i915_hotplug hotplug;
struct i915_fbc fbc;
struct i915_drrs drrs;
+ const struct bdb_header *bdb_start;
struct intel_opregion opregion;
struct intel_vbt_data vbt;
@@ -3306,6 +3307,9 @@ intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
}
#endif
+const struct bdb_header *validate_vbt(const void __iomem *_vbt,
+ size_t size, const char *source);
+
/* intel_acpi.c */
#ifdef CONFIG_ACPI
extern void intel_register_dsm_handler(void);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 0bf0942..1932a86 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1227,49 +1227,6 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
{ }
};
-static const struct bdb_header *validate_vbt(const void __iomem *_base,
- size_t size,
- const void __iomem *_vbt,
- const char *source)
-{
- /*
- * This is the one place where we explicitly discard the address space
- * (__iomem) of the BIOS/VBT. (And this will cause a sparse complaint.)
- * From now on everything is based on 'base', and treated as regular
- * memory.
- */
- const void *base = (const void *) _base;
- size_t offset = _vbt - _base;
- const struct vbt_header *vbt = base + offset;
- const struct bdb_header *bdb;
-
- if (offset + sizeof(struct vbt_header) > size) {
- DRM_DEBUG_DRIVER("VBT header incomplete\n");
- return NULL;
- }
-
- if (memcmp(vbt->signature, "$VBT", 4)) {
- DRM_DEBUG_DRIVER("VBT invalid signature\n");
- return NULL;
- }
-
- offset += vbt->bdb_offset;
- if (offset + sizeof(struct bdb_header) > size) {
- DRM_DEBUG_DRIVER("BDB header incomplete\n");
- return NULL;
- }
-
- bdb = base + offset;
- if (offset + bdb->bdb_size > size) {
- DRM_DEBUG_DRIVER("BDB incomplete\n");
- return NULL;
- }
-
- DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
- source, vbt->signature);
- return bdb;
-}
-
static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
{
const struct bdb_header *bdb = NULL;
@@ -1278,7 +1235,7 @@ static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
/* Scour memory looking for the VBT signature. */
for (i = 0; i + 4 < size; i++) {
if (ioread32(bios + i) == *((const u32 *) "$VBT")) {
- bdb = validate_vbt(bios, size, bios + i, "PCI ROM");
+ bdb = validate_vbt(bios + i, size - i, "PCI ROM");
break;
}
}
@@ -1308,10 +1265,8 @@ intel_parse_bios(struct drm_device *dev)
init_vbt_defaults(dev_priv);
- /* XXX Should this validation be moved to intel_opregion.c? */
if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt)
- bdb = validate_vbt(dev_priv->opregion.header, OPREGION_SIZE,
- dev_priv->opregion.vbt, "OpRegion");
+ bdb = dev_priv->bdb_start;
if (bdb == NULL) {
size_t size;
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index f46231f..3a43db9 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -32,210 +32,7 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "intel_drv.h"
-
-#define PCI_ASLE 0xe4
-#define PCI_ASLS 0xfc
-#define PCI_SWSCI 0xe8
-#define PCI_SWSCI_SCISEL (1 << 15)
-#define PCI_SWSCI_GSSCIE (1 << 0)
-
-#define OPREGION_HEADER_OFFSET 0
-#define OPREGION_ACPI_OFFSET 0x100
-#define ACPI_CLID 0x01ac /* current lid state indicator */
-#define ACPI_CDCK 0x01b0 /* current docking state indicator */
-#define OPREGION_SWSCI_OFFSET 0x200
-#define OPREGION_ASLE_OFFSET 0x300
-#define OPREGION_VBT_OFFSET 0x400
-
-#define OPREGION_SIGNATURE "IntelGraphicsMem"
-#define MBOX_ACPI (1<<0)
-#define MBOX_SWSCI (1<<1)
-#define MBOX_ASLE (1<<2)
-#define MBOX_ASLE_EXT (1<<4)
-
-struct opregion_header {
- u8 signature[16];
- u32 size;
- u32 opregion_ver;
- u8 bios_ver[32];
- u8 vbios_ver[16];
- u8 driver_ver[16];
- u32 mboxes;
- u32 driver_model;
- u32 pcon;
- u8 dver[32];
- u8 rsvd[124];
-} __packed;
-
-/* OpRegion mailbox #1: public ACPI methods */
-struct opregion_acpi {
- u32 drdy; /* driver readiness */
- u32 csts; /* notification status */
- u32 cevt; /* current event */
- u8 rsvd1[20];
- u32 didl[8]; /* supported display devices ID list */
- u32 cpdl[8]; /* currently presented display list */
- u32 cadl[8]; /* currently active display list */
- u32 nadl[8]; /* next active devices list */
- u32 aslp; /* ASL sleep time-out */
- u32 tidx; /* toggle table index */
- u32 chpd; /* current hotplug enable indicator */
- u32 clid; /* current lid state*/
- u32 cdck; /* current docking state */
- u32 sxsw; /* Sx state resume */
- u32 evts; /* ASL supported events */
- u32 cnot; /* current OS notification */
- u32 nrdy; /* driver status */
- u32 did2[7]; /* extended supported display devices ID list */
- u32 cpd2[7]; /* extended attached display devices list */
- u8 rsvd2[4];
-} __packed;
-
-/* OpRegion mailbox #2: SWSCI */
-struct opregion_swsci {
- u32 scic; /* SWSCI command|status|data */
- u32 parm; /* command parameters */
- u32 dslp; /* driver sleep time-out */
- u8 rsvd[244];
-} __packed;
-
-/* OpRegion mailbox #3: ASLE */
-struct opregion_asle {
- u32 ardy; /* driver readiness */
- u32 aslc; /* ASLE interrupt command */
- u32 tche; /* technology enabled indicator */
- u32 alsi; /* current ALS illuminance reading */
- u32 bclp; /* backlight brightness to set */
- u32 pfit; /* panel fitting state */
- u32 cblv; /* current brightness level */
- u16 bclm[20]; /* backlight level duty cycle mapping table */
- u32 cpfm; /* current panel fitting mode */
- u32 epfm; /* enabled panel fitting modes */
- u8 plut[74]; /* panel LUT and identifier */
- u32 pfmb; /* PWM freq and min brightness */
- u32 cddv; /* color correction default values */
- u32 pcft; /* power conservation features */
- u32 srot; /* supported rotation angles */
- u32 iuer; /* IUER events */
- u64 fdss;
- u32 fdsp;
- u32 stat;
- u64 rvda; /* Physical address of raw vbt data */
- u32 rvds; /* Size of raw vbt data */
- u8 rsvd[58];
-} __packed;
-
-/* Driver readiness indicator */
-#define ASLE_ARDY_READY (1 << 0)
-#define ASLE_ARDY_NOT_READY (0 << 0)
-
-/* ASLE Interrupt Command (ASLC) bits */
-#define ASLC_SET_ALS_ILLUM (1 << 0)
-#define ASLC_SET_BACKLIGHT (1 << 1)
-#define ASLC_SET_PFIT (1 << 2)
-#define ASLC_SET_PWM_FREQ (1 << 3)
-#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
-#define ASLC_BUTTON_ARRAY (1 << 5)
-#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
-#define ASLC_DOCKING_INDICATOR (1 << 7)
-#define ASLC_ISCT_STATE_CHANGE (1 << 8)
-#define ASLC_REQ_MSK 0x1ff
-/* response bits */
-#define ASLC_ALS_ILLUM_FAILED (1 << 10)
-#define ASLC_BACKLIGHT_FAILED (1 << 12)
-#define ASLC_PFIT_FAILED (1 << 14)
-#define ASLC_PWM_FREQ_FAILED (1 << 16)
-#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
-#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
-#define ASLC_CONVERTIBLE_FAILED (1 << 22)
-#define ASLC_DOCKING_FAILED (1 << 24)
-#define ASLC_ISCT_STATE_FAILED (1 << 26)
-
-/* Technology enabled indicator */
-#define ASLE_TCHE_ALS_EN (1 << 0)
-#define ASLE_TCHE_BLC_EN (1 << 1)
-#define ASLE_TCHE_PFIT_EN (1 << 2)
-#define ASLE_TCHE_PFMB_EN (1 << 3)
-
-/* ASLE backlight brightness to set */
-#define ASLE_BCLP_VALID (1<<31)
-#define ASLE_BCLP_MSK (~(1<<31))
-
-/* ASLE panel fitting request */
-#define ASLE_PFIT_VALID (1<<31)
-#define ASLE_PFIT_CENTER (1<<0)
-#define ASLE_PFIT_STRETCH_TEXT (1<<1)
-#define ASLE_PFIT_STRETCH_GFX (1<<2)
-
-/* PWM frequency and minimum brightness */
-#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
-#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
-#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
-#define ASLE_PFMB_PWM_VALID (1<<31)
-
-#define ASLE_CBLV_VALID (1<<31)
-
-/* IUER */
-#define ASLE_IUER_DOCKING (1 << 7)
-#define ASLE_IUER_CONVERTIBLE (1 << 6)
-#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
-#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
-#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
-#define ASLE_IUER_WINDOWS_BTN (1 << 1)
-#define ASLE_IUER_POWER_BTN (1 << 0)
-
-/* Software System Control Interrupt (SWSCI) */
-#define SWSCI_SCIC_INDICATOR (1 << 0)
-#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
-#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
-#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
-#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
-#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
-#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
-#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
-#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
-#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
-
-#define SWSCI_FUNCTION_CODE(main, sub) \
- ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
- (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
-
-/* SWSCI: Get BIOS Data (GBDA) */
-#define SWSCI_GBDA 4
-#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
-#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
-#define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
-#define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
-#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
-#define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
-#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
-
-/* SWSCI: System BIOS Callbacks (SBCB) */
-#define SWSCI_SBCB 6
-#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
-#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
-#define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
-#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
-#define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
-#define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
-#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
-#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
-#define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
-#define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
-#define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
-#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
-#define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
-#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
-#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
-#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
-
-#define ACPI_OTHER_OUTPUT (0<<8)
-#define ACPI_VGA_OUTPUT (1<<8)
-#define ACPI_TV_OUTPUT (2<<8)
-#define ACPI_DIGITAL_OUTPUT (3<<8)
-#define ACPI_LVDS_OUTPUT (4<<8)
-
-#define MAX_DSLP 1500
+#include "intel_opregion.h"
#ifdef CONFIG_ACPI
static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
@@ -892,13 +689,55 @@ static void swsci_setup(struct drm_device *dev)
static inline void swsci_setup(struct drm_device *dev) {}
#endif /* CONFIG_ACPI */
+const struct bdb_header *validate_vbt(const void __iomem *_vbt,
+ size_t size,
+ const char *source)
+{
+ /*
+ * This is the one place where we explicitly discard the address space
+ * (__iomem) of the BIOS/VBT. (And this will cause a sparse complaint.)
+ */
+ const struct vbt_header *vbt = (const struct vbt_header *)_vbt;
+ const struct bdb_header *bdb;
+ size_t offset;
+
+ if (sizeof(struct vbt_header) > size) {
+ DRM_DEBUG_DRIVER("VBT header incomplete\n");
+ return NULL;
+ }
+
+ if (memcmp(vbt->signature, "$VBT", 4)) {
+ DRM_DEBUG_DRIVER("VBT invalid signature\n");
+ return NULL;
+ }
+
+ offset = vbt->bdb_offset;
+ if (offset + sizeof(struct bdb_header) > size) {
+ DRM_DEBUG_DRIVER("BDB header incomplete\n");
+ return NULL;
+ }
+
+ bdb = (const void *)_vbt + offset;
+ if (offset + bdb->bdb_size > size) {
+ DRM_DEBUG_DRIVER("BDB incomplete\n");
+ return NULL;
+ }
+
+ DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
+ source, vbt->signature);
+ return bdb;
+}
+
int intel_opregion_setup(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion;
void __iomem *base;
+ void __iomem *vbt_base;
u32 asls, mboxes;
char buf[sizeof(OPREGION_SIGNATURE)];
+ const struct bdb_header *bdb = NULL;
+ size_t size;
int err = 0;
BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
@@ -917,7 +756,7 @@ int intel_opregion_setup(struct drm_device *dev)
INIT_WORK(&opregion->asle_work, asle_work);
#endif
- base = acpi_os_ioremap(asls, OPREGION_SIZE);
+ base = acpi_os_ioremap(asls, OPREGION_VBT_OFFSET);
if (!base)
return -ENOMEM;
@@ -929,7 +768,33 @@ int intel_opregion_setup(struct drm_device *dev)
goto err_out;
}
opregion->header = base;
- opregion->vbt = base + OPREGION_VBT_OFFSET;
+ /* Assigning the alse to the mailbox 3 of the opregion */
+ opregion->asle = base + OPREGION_ASLE_OFFSET;
+
+ /*
+ * Non-zero value in rvda field is an indication to driver that a
+ * valid Raw VBT is stored in that address and driver should not refer
+ * to mailbox4 for getting VBT.
+ */
+ if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda) {
+ size = opregion->asle->rvds;
+ vbt_base = acpi_os_ioremap(opregion->asle->rvda,
+ size);
+ } else {
+ size = OPREGION_SIZE - OPREGION_VBT_OFFSET;
+ vbt_base = acpi_os_ioremap(asls + OPREGION_VBT_OFFSET,
+ size);
+ }
+
+ bdb = validate_vbt(vbt_base, size, "OpRegion");
+
+ if (bdb == NULL) {
+ err = -EINVAL;
+ goto err_vbt;
+ }
+
+ dev_priv->bdb_start = bdb;
+ opregion->vbt = vbt_base;
opregion->lid_state = base + ACPI_CLID;
@@ -953,6 +818,8 @@ int intel_opregion_setup(struct drm_device *dev)
return 0;
+err_vbt:
+ iounmap(vbt_base);
err_out:
iounmap(base);
return err;
diff --git a/drivers/gpu/drm/i915/intel_opregion.h b/drivers/gpu/drm/i915/intel_opregion.h
new file mode 100644
index 0000000..bcb45ec
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_opregion.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2008 Intel Corporation <hong.liu@intel.com>
+ * Copyright 2008 Red Hat <mjg@redhat.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 INTEL 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.
+ *
+ */
+
+#define PCI_ASLE 0xe4
+#define PCI_ASLS 0xfc
+#define PCI_SWSCI 0xe8
+#define PCI_SWSCI_SCISEL (1 << 15)
+#define PCI_SWSCI_GSSCIE (1 << 0)
+
+#define OPREGION_HEADER_OFFSET 0
+#define OPREGION_ACPI_OFFSET 0x100
+#define ACPI_CLID 0x01ac /* current lid state indicator */
+#define ACPI_CDCK 0x01b0 /* current docking state indicator */
+#define OPREGION_SWSCI_OFFSET 0x200
+#define OPREGION_ASLE_OFFSET 0x300
+#define OPREGION_VBT_OFFSET 0x400
+
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+#define MBOX_ACPI (1<<0)
+#define MBOX_SWSCI (1<<1)
+#define MBOX_ASLE (1<<2)
+#define MBOX_ASLE_EXT (1<<4)
+
+struct opregion_header {
+ u8 signature[16];
+ u32 size;
+ u32 opregion_ver;
+ u8 bios_ver[32];
+ u8 vbios_ver[16];
+ u8 driver_ver[16];
+ u32 mboxes;
+ u32 driver_model;
+ u32 pcon;
+ u8 dver[32];
+ u8 rsvd[124];
+} __packed;
+
+/* OpRegion mailbox #1: public ACPI methods */
+struct opregion_acpi {
+ u32 drdy; /* driver readiness */
+ u32 csts; /* notification status */
+ u32 cevt; /* current event */
+ u8 rsvd1[20];
+ u32 didl[8]; /* supported display devices ID list */
+ u32 cpdl[8]; /* currently presented display list */
+ u32 cadl[8]; /* currently active display list */
+ u32 nadl[8]; /* next active devices list */
+ u32 aslp; /* ASL sleep time-out */
+ u32 tidx; /* toggle table index */
+ u32 chpd; /* current hotplug enable indicator */
+ u32 clid; /* current lid state*/
+ u32 cdck; /* current docking state */
+ u32 sxsw; /* Sx state resume */
+ u32 evts; /* ASL supported events */
+ u32 cnot; /* current OS notification */
+ u32 nrdy; /* driver status */
+ u32 did2[7]; /* extended supported display devices ID list */
+ u32 cpd2[7]; /* extended attached display devices list */
+ u8 rsvd2[4];
+} __packed;
+
+/* OpRegion mailbox #2: SWSCI */
+struct opregion_swsci {
+ u32 scic; /* SWSCI command|status|data */
+ u32 parm; /* command parameters */
+ u32 dslp; /* driver sleep time-out */
+ u8 rsvd[244];
+} __packed;
+
+/* OpRegion mailbox #3: ASLE */
+struct opregion_asle {
+ u32 ardy; /* driver readiness */
+ u32 aslc; /* ASLE interrupt command */
+ u32 tche; /* technology enabled indicator */
+ u32 alsi; /* current ALS illuminance reading */
+ u32 bclp; /* backlight brightness to set */
+ u32 pfit; /* panel fitting state */
+ u32 cblv; /* current brightness level */
+ u16 bclm[20]; /* backlight level duty cycle mapping table */
+ u32 cpfm; /* current panel fitting mode */
+ u32 epfm; /* enabled panel fitting modes */
+ u8 plut[74]; /* panel LUT and identifier */
+ u32 pfmb; /* PWM freq and min brightness */
+ u32 cddv; /* color correction default values */
+ u32 pcft; /* power conservation features */
+ u32 srot; /* supported rotation angles */
+ u32 iuer; /* IUER events */
+ u64 fdss;
+ u32 fdsp;
+ u32 stat;
+ u64 rvda; /* Physical address of raw vbt data */
+ u32 rvds; /* Size of raw vbt data */
+ u8 rsvd[58];
+} __packed;
+
+/* Driver readiness indicator */
+#define ASLE_ARDY_READY (1 << 0)
+#define ASLE_ARDY_NOT_READY (0 << 0)
+
+/* ASLE Interrupt Command (ASLC) bits */
+#define ASLC_SET_ALS_ILLUM (1 << 0)
+#define ASLC_SET_BACKLIGHT (1 << 1)
+#define ASLC_SET_PFIT (1 << 2)
+#define ASLC_SET_PWM_FREQ (1 << 3)
+#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
+#define ASLC_BUTTON_ARRAY (1 << 5)
+#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
+#define ASLC_DOCKING_INDICATOR (1 << 7)
+#define ASLC_ISCT_STATE_CHANGE (1 << 8)
+#define ASLC_REQ_MSK 0x1ff
+/* response bits */
+#define ASLC_ALS_ILLUM_FAILED (1 << 10)
+#define ASLC_BACKLIGHT_FAILED (1 << 12)
+#define ASLC_PFIT_FAILED (1 << 14)
+#define ASLC_PWM_FREQ_FAILED (1 << 16)
+#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
+#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
+#define ASLC_CONVERTIBLE_FAILED (1 << 22)
+#define ASLC_DOCKING_FAILED (1 << 24)
+#define ASLC_ISCT_STATE_FAILED (1 << 26)
+
+/* Technology enabled indicator */
+#define ASLE_TCHE_ALS_EN (1 << 0)
+#define ASLE_TCHE_BLC_EN (1 << 1)
+#define ASLE_TCHE_PFIT_EN (1 << 2)
+#define ASLE_TCHE_PFMB_EN (1 << 3)
+
+/* ASLE backlight brightness to set */
+#define ASLE_BCLP_VALID (1<<31)
+#define ASLE_BCLP_MSK (~(1<<31))
+
+/* ASLE panel fitting request */
+#define ASLE_PFIT_VALID (1<<31)
+#define ASLE_PFIT_CENTER (1<<0)
+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
+#define ASLE_PFIT_STRETCH_GFX (1<<2)
+
+/* PWM frequency and minimum brightness */
+#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
+#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
+#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
+#define ASLE_PFMB_PWM_VALID (1<<31)
+
+#define ASLE_CBLV_VALID (1<<31)
+
+/* IUER */
+#define ASLE_IUER_DOCKING (1 << 7)
+#define ASLE_IUER_CONVERTIBLE (1 << 6)
+#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
+#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
+#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
+#define ASLE_IUER_WINDOWS_BTN (1 << 1)
+#define ASLE_IUER_POWER_BTN (1 << 0)
+
+/* Software System Control Interrupt (SWSCI) */
+#define SWSCI_SCIC_INDICATOR (1 << 0)
+#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
+#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
+#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
+#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
+#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
+#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
+#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
+#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
+#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
+
+#define SWSCI_FUNCTION_CODE(main, sub) \
+ ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
+ (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
+
+/* SWSCI: Get BIOS Data (GBDA) */
+#define SWSCI_GBDA 4
+#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
+#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
+#define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
+#define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
+#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
+#define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
+#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
+
+/* SWSCI: System BIOS Callbacks (SBCB) */
+#define SWSCI_SBCB 6
+#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
+#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
+#define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
+#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
+#define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
+#define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
+#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
+#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
+#define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
+#define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
+#define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
+#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
+#define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
+#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
+#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
+#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
+
+#define ACPI_OTHER_OUTPUT (0<<8)
+#define ACPI_VGA_OUTPUT (1<<8)
+#define ACPI_TV_OUTPUT (2<<8)
+#define ACPI_DIGITAL_OUTPUT (3<<8)
+#define ACPI_LVDS_OUTPUT (4<<8)
+
+#define MAX_DSLP 1500
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB Deepak M
@ 2015-09-16 13:24 ` Jani Nikula
2015-09-17 12:10 ` Jani Nikula
1 sibling, 0 replies; 25+ messages in thread
From: Jani Nikula @ 2015-09-16 13:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
> Currently the iomap for VBT works only if the size of the
> VBT is less than 6KB, but if the size of the VBT exceeds
> 6KB than the physical address and the size of the VBT to
> be iomapped is specified in the mailbox3 and is iomapped
> accordingly.
>
> v2: - Moving the validate_vbt to opregion file (Jani)
> - Fix the i915_opregion() in debugfs (Jani)
>
> Signed-off-by: Deepak M <m.deepak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 24 ++-
> drivers/gpu/drm/i915/i915_drv.h | 4 +
> drivers/gpu/drm/i915/intel_bios.c | 49 +-----
> drivers/gpu/drm/i915/intel_opregion.c | 279 +++++++++------------------------
> drivers/gpu/drm/i915/intel_opregion.h | 230 +++++++++++++++++++++++++++
Why are you adding this file? I think it's better to have all of this in
the .c file so that nobody will have any ideas about accessing the data
outside of intel_opregion.c.
BR,
Jani.
> 5 files changed, 329 insertions(+), 257 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/intel_opregion.h
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 41629fa..5534aa2 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -26,6 +26,8 @@
> *
> */
>
> +#include <linux/acpi.h>
> +#include <acpi/video.h>
> #include <linux/seq_file.h>
> #include <linux/circ_buf.h>
> #include <linux/ctype.h>
> @@ -39,6 +41,7 @@
> #include "intel_ringbuffer.h"
> #include <drm/i915_drm.h>
> #include "i915_drv.h"
> +#include "intel_opregion.h"
>
> enum {
> ACTIVE_LIST,
> @@ -1832,7 +1835,7 @@ static int i915_opregion(struct seq_file *m, void *unused)
> struct drm_device *dev = node->minor->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_opregion *opregion = &dev_priv->opregion;
> - void *data = kmalloc(OPREGION_SIZE, GFP_KERNEL);
> + void *data = kmalloc(OPREGION_VBT_OFFSET, GFP_KERNEL);
> int ret;
>
> if (data == NULL)
> @@ -1843,12 +1846,25 @@ static int i915_opregion(struct seq_file *m, void *unused)
> goto out;
>
> if (opregion->header) {
> - memcpy_fromio(data, opregion->header, OPREGION_SIZE);
> - seq_write(m, data, OPREGION_SIZE);
> + memcpy_fromio(data, opregion->header, OPREGION_VBT_OFFSET);
> + seq_write(m, data, OPREGION_VBT_OFFSET);
> + kfree(data);
> + if (opregion->asle->rvda) {
> + data = kmalloc(opregion->asle->rvds, GFP_KERNEL);
> + memcpy_fromio(data,
> + (const void __iomem *) opregion->asle->rvda,
> + opregion->asle->rvds);
> + seq_write(m, data, opregion->asle->rvds);
> + } else {
> + data = kmalloc(OPREGION_SIZE - OPREGION_VBT_OFFSET,
> + GFP_KERNEL);
> + memcpy_fromio(data, opregion->vbt,
> + OPREGION_SIZE - OPREGION_VBT_OFFSET);
> + seq_write(m, data, OPREGION_SIZE - OPREGION_VBT_OFFSET);
> + }
> }
>
> mutex_unlock(&dev->struct_mutex);
> -
> out:
> kfree(data);
> return 0;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1287007..507d57a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1780,6 +1780,7 @@ struct drm_i915_private {
> struct i915_hotplug hotplug;
> struct i915_fbc fbc;
> struct i915_drrs drrs;
> + const struct bdb_header *bdb_start;
> struct intel_opregion opregion;
> struct intel_vbt_data vbt;
>
> @@ -3306,6 +3307,9 @@ intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
> }
> #endif
>
> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
> + size_t size, const char *source);
> +
> /* intel_acpi.c */
> #ifdef CONFIG_ACPI
> extern void intel_register_dsm_handler(void);
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index 0bf0942..1932a86 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -1227,49 +1227,6 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
> { }
> };
>
> -static const struct bdb_header *validate_vbt(const void __iomem *_base,
> - size_t size,
> - const void __iomem *_vbt,
> - const char *source)
> -{
> - /*
> - * This is the one place where we explicitly discard the address space
> - * (__iomem) of the BIOS/VBT. (And this will cause a sparse complaint.)
> - * From now on everything is based on 'base', and treated as regular
> - * memory.
> - */
> - const void *base = (const void *) _base;
> - size_t offset = _vbt - _base;
> - const struct vbt_header *vbt = base + offset;
> - const struct bdb_header *bdb;
> -
> - if (offset + sizeof(struct vbt_header) > size) {
> - DRM_DEBUG_DRIVER("VBT header incomplete\n");
> - return NULL;
> - }
> -
> - if (memcmp(vbt->signature, "$VBT", 4)) {
> - DRM_DEBUG_DRIVER("VBT invalid signature\n");
> - return NULL;
> - }
> -
> - offset += vbt->bdb_offset;
> - if (offset + sizeof(struct bdb_header) > size) {
> - DRM_DEBUG_DRIVER("BDB header incomplete\n");
> - return NULL;
> - }
> -
> - bdb = base + offset;
> - if (offset + bdb->bdb_size > size) {
> - DRM_DEBUG_DRIVER("BDB incomplete\n");
> - return NULL;
> - }
> -
> - DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
> - source, vbt->signature);
> - return bdb;
> -}
> -
> static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
> {
> const struct bdb_header *bdb = NULL;
> @@ -1278,7 +1235,7 @@ static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
> /* Scour memory looking for the VBT signature. */
> for (i = 0; i + 4 < size; i++) {
> if (ioread32(bios + i) == *((const u32 *) "$VBT")) {
> - bdb = validate_vbt(bios, size, bios + i, "PCI ROM");
> + bdb = validate_vbt(bios + i, size - i, "PCI ROM");
> break;
> }
> }
> @@ -1308,10 +1265,8 @@ intel_parse_bios(struct drm_device *dev)
>
> init_vbt_defaults(dev_priv);
>
> - /* XXX Should this validation be moved to intel_opregion.c? */
> if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt)
> - bdb = validate_vbt(dev_priv->opregion.header, OPREGION_SIZE,
> - dev_priv->opregion.vbt, "OpRegion");
> + bdb = dev_priv->bdb_start;
>
> if (bdb == NULL) {
> size_t size;
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index f46231f..3a43db9 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -32,210 +32,7 @@
> #include <drm/i915_drm.h>
> #include "i915_drv.h"
> #include "intel_drv.h"
> -
> -#define PCI_ASLE 0xe4
> -#define PCI_ASLS 0xfc
> -#define PCI_SWSCI 0xe8
> -#define PCI_SWSCI_SCISEL (1 << 15)
> -#define PCI_SWSCI_GSSCIE (1 << 0)
> -
> -#define OPREGION_HEADER_OFFSET 0
> -#define OPREGION_ACPI_OFFSET 0x100
> -#define ACPI_CLID 0x01ac /* current lid state indicator */
> -#define ACPI_CDCK 0x01b0 /* current docking state indicator */
> -#define OPREGION_SWSCI_OFFSET 0x200
> -#define OPREGION_ASLE_OFFSET 0x300
> -#define OPREGION_VBT_OFFSET 0x400
> -
> -#define OPREGION_SIGNATURE "IntelGraphicsMem"
> -#define MBOX_ACPI (1<<0)
> -#define MBOX_SWSCI (1<<1)
> -#define MBOX_ASLE (1<<2)
> -#define MBOX_ASLE_EXT (1<<4)
> -
> -struct opregion_header {
> - u8 signature[16];
> - u32 size;
> - u32 opregion_ver;
> - u8 bios_ver[32];
> - u8 vbios_ver[16];
> - u8 driver_ver[16];
> - u32 mboxes;
> - u32 driver_model;
> - u32 pcon;
> - u8 dver[32];
> - u8 rsvd[124];
> -} __packed;
> -
> -/* OpRegion mailbox #1: public ACPI methods */
> -struct opregion_acpi {
> - u32 drdy; /* driver readiness */
> - u32 csts; /* notification status */
> - u32 cevt; /* current event */
> - u8 rsvd1[20];
> - u32 didl[8]; /* supported display devices ID list */
> - u32 cpdl[8]; /* currently presented display list */
> - u32 cadl[8]; /* currently active display list */
> - u32 nadl[8]; /* next active devices list */
> - u32 aslp; /* ASL sleep time-out */
> - u32 tidx; /* toggle table index */
> - u32 chpd; /* current hotplug enable indicator */
> - u32 clid; /* current lid state*/
> - u32 cdck; /* current docking state */
> - u32 sxsw; /* Sx state resume */
> - u32 evts; /* ASL supported events */
> - u32 cnot; /* current OS notification */
> - u32 nrdy; /* driver status */
> - u32 did2[7]; /* extended supported display devices ID list */
> - u32 cpd2[7]; /* extended attached display devices list */
> - u8 rsvd2[4];
> -} __packed;
> -
> -/* OpRegion mailbox #2: SWSCI */
> -struct opregion_swsci {
> - u32 scic; /* SWSCI command|status|data */
> - u32 parm; /* command parameters */
> - u32 dslp; /* driver sleep time-out */
> - u8 rsvd[244];
> -} __packed;
> -
> -/* OpRegion mailbox #3: ASLE */
> -struct opregion_asle {
> - u32 ardy; /* driver readiness */
> - u32 aslc; /* ASLE interrupt command */
> - u32 tche; /* technology enabled indicator */
> - u32 alsi; /* current ALS illuminance reading */
> - u32 bclp; /* backlight brightness to set */
> - u32 pfit; /* panel fitting state */
> - u32 cblv; /* current brightness level */
> - u16 bclm[20]; /* backlight level duty cycle mapping table */
> - u32 cpfm; /* current panel fitting mode */
> - u32 epfm; /* enabled panel fitting modes */
> - u8 plut[74]; /* panel LUT and identifier */
> - u32 pfmb; /* PWM freq and min brightness */
> - u32 cddv; /* color correction default values */
> - u32 pcft; /* power conservation features */
> - u32 srot; /* supported rotation angles */
> - u32 iuer; /* IUER events */
> - u64 fdss;
> - u32 fdsp;
> - u32 stat;
> - u64 rvda; /* Physical address of raw vbt data */
> - u32 rvds; /* Size of raw vbt data */
> - u8 rsvd[58];
> -} __packed;
> -
> -/* Driver readiness indicator */
> -#define ASLE_ARDY_READY (1 << 0)
> -#define ASLE_ARDY_NOT_READY (0 << 0)
> -
> -/* ASLE Interrupt Command (ASLC) bits */
> -#define ASLC_SET_ALS_ILLUM (1 << 0)
> -#define ASLC_SET_BACKLIGHT (1 << 1)
> -#define ASLC_SET_PFIT (1 << 2)
> -#define ASLC_SET_PWM_FREQ (1 << 3)
> -#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
> -#define ASLC_BUTTON_ARRAY (1 << 5)
> -#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
> -#define ASLC_DOCKING_INDICATOR (1 << 7)
> -#define ASLC_ISCT_STATE_CHANGE (1 << 8)
> -#define ASLC_REQ_MSK 0x1ff
> -/* response bits */
> -#define ASLC_ALS_ILLUM_FAILED (1 << 10)
> -#define ASLC_BACKLIGHT_FAILED (1 << 12)
> -#define ASLC_PFIT_FAILED (1 << 14)
> -#define ASLC_PWM_FREQ_FAILED (1 << 16)
> -#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
> -#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
> -#define ASLC_CONVERTIBLE_FAILED (1 << 22)
> -#define ASLC_DOCKING_FAILED (1 << 24)
> -#define ASLC_ISCT_STATE_FAILED (1 << 26)
> -
> -/* Technology enabled indicator */
> -#define ASLE_TCHE_ALS_EN (1 << 0)
> -#define ASLE_TCHE_BLC_EN (1 << 1)
> -#define ASLE_TCHE_PFIT_EN (1 << 2)
> -#define ASLE_TCHE_PFMB_EN (1 << 3)
> -
> -/* ASLE backlight brightness to set */
> -#define ASLE_BCLP_VALID (1<<31)
> -#define ASLE_BCLP_MSK (~(1<<31))
> -
> -/* ASLE panel fitting request */
> -#define ASLE_PFIT_VALID (1<<31)
> -#define ASLE_PFIT_CENTER (1<<0)
> -#define ASLE_PFIT_STRETCH_TEXT (1<<1)
> -#define ASLE_PFIT_STRETCH_GFX (1<<2)
> -
> -/* PWM frequency and minimum brightness */
> -#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
> -#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
> -#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
> -#define ASLE_PFMB_PWM_VALID (1<<31)
> -
> -#define ASLE_CBLV_VALID (1<<31)
> -
> -/* IUER */
> -#define ASLE_IUER_DOCKING (1 << 7)
> -#define ASLE_IUER_CONVERTIBLE (1 << 6)
> -#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
> -#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
> -#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
> -#define ASLE_IUER_WINDOWS_BTN (1 << 1)
> -#define ASLE_IUER_POWER_BTN (1 << 0)
> -
> -/* Software System Control Interrupt (SWSCI) */
> -#define SWSCI_SCIC_INDICATOR (1 << 0)
> -#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
> -#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
> -#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
> -#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
> -#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
> -#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
> -#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
> -#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
> -#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
> -
> -#define SWSCI_FUNCTION_CODE(main, sub) \
> - ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
> - (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
> -
> -/* SWSCI: Get BIOS Data (GBDA) */
> -#define SWSCI_GBDA 4
> -#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
> -#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
> -#define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
> -#define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
> -#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
> -#define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
> -#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
> -
> -/* SWSCI: System BIOS Callbacks (SBCB) */
> -#define SWSCI_SBCB 6
> -#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
> -#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
> -#define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
> -#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
> -#define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
> -#define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
> -#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
> -#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
> -#define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
> -#define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
> -#define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
> -#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
> -#define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
> -#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
> -#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
> -#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
> -
> -#define ACPI_OTHER_OUTPUT (0<<8)
> -#define ACPI_VGA_OUTPUT (1<<8)
> -#define ACPI_TV_OUTPUT (2<<8)
> -#define ACPI_DIGITAL_OUTPUT (3<<8)
> -#define ACPI_LVDS_OUTPUT (4<<8)
> -
> -#define MAX_DSLP 1500
> +#include "intel_opregion.h"
>
> #ifdef CONFIG_ACPI
> static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
> @@ -892,13 +689,55 @@ static void swsci_setup(struct drm_device *dev)
> static inline void swsci_setup(struct drm_device *dev) {}
> #endif /* CONFIG_ACPI */
>
> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
> + size_t size,
> + const char *source)
> +{
> + /*
> + * This is the one place where we explicitly discard the address space
> + * (__iomem) of the BIOS/VBT. (And this will cause a sparse complaint.)
> + */
> + const struct vbt_header *vbt = (const struct vbt_header *)_vbt;
> + const struct bdb_header *bdb;
> + size_t offset;
> +
> + if (sizeof(struct vbt_header) > size) {
> + DRM_DEBUG_DRIVER("VBT header incomplete\n");
> + return NULL;
> + }
> +
> + if (memcmp(vbt->signature, "$VBT", 4)) {
> + DRM_DEBUG_DRIVER("VBT invalid signature\n");
> + return NULL;
> + }
> +
> + offset = vbt->bdb_offset;
> + if (offset + sizeof(struct bdb_header) > size) {
> + DRM_DEBUG_DRIVER("BDB header incomplete\n");
> + return NULL;
> + }
> +
> + bdb = (const void *)_vbt + offset;
> + if (offset + bdb->bdb_size > size) {
> + DRM_DEBUG_DRIVER("BDB incomplete\n");
> + return NULL;
> + }
> +
> + DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
> + source, vbt->signature);
> + return bdb;
> +}
> +
> int intel_opregion_setup(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_opregion *opregion = &dev_priv->opregion;
> void __iomem *base;
> + void __iomem *vbt_base;
> u32 asls, mboxes;
> char buf[sizeof(OPREGION_SIGNATURE)];
> + const struct bdb_header *bdb = NULL;
> + size_t size;
> int err = 0;
>
> BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
> @@ -917,7 +756,7 @@ int intel_opregion_setup(struct drm_device *dev)
> INIT_WORK(&opregion->asle_work, asle_work);
> #endif
>
> - base = acpi_os_ioremap(asls, OPREGION_SIZE);
> + base = acpi_os_ioremap(asls, OPREGION_VBT_OFFSET);
> if (!base)
> return -ENOMEM;
>
> @@ -929,7 +768,33 @@ int intel_opregion_setup(struct drm_device *dev)
> goto err_out;
> }
> opregion->header = base;
> - opregion->vbt = base + OPREGION_VBT_OFFSET;
> + /* Assigning the alse to the mailbox 3 of the opregion */
> + opregion->asle = base + OPREGION_ASLE_OFFSET;
> +
> + /*
> + * Non-zero value in rvda field is an indication to driver that a
> + * valid Raw VBT is stored in that address and driver should not refer
> + * to mailbox4 for getting VBT.
> + */
> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda) {
> + size = opregion->asle->rvds;
> + vbt_base = acpi_os_ioremap(opregion->asle->rvda,
> + size);
> + } else {
> + size = OPREGION_SIZE - OPREGION_VBT_OFFSET;
> + vbt_base = acpi_os_ioremap(asls + OPREGION_VBT_OFFSET,
> + size);
> + }
> +
> + bdb = validate_vbt(vbt_base, size, "OpRegion");
> +
> + if (bdb == NULL) {
> + err = -EINVAL;
> + goto err_vbt;
> + }
> +
> + dev_priv->bdb_start = bdb;
> + opregion->vbt = vbt_base;
>
> opregion->lid_state = base + ACPI_CLID;
>
> @@ -953,6 +818,8 @@ int intel_opregion_setup(struct drm_device *dev)
>
> return 0;
>
> +err_vbt:
> + iounmap(vbt_base);
> err_out:
> iounmap(base);
> return err;
> diff --git a/drivers/gpu/drm/i915/intel_opregion.h b/drivers/gpu/drm/i915/intel_opregion.h
> new file mode 100644
> index 0000000..bcb45ec
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_opregion.h
> @@ -0,0 +1,230 @@
> +/*
> + * Copyright 2008 Intel Corporation <hong.liu@intel.com>
> + * Copyright 2008 Red Hat <mjg@redhat.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 INTEL 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.
> + *
> + */
> +
> +#define PCI_ASLE 0xe4
> +#define PCI_ASLS 0xfc
> +#define PCI_SWSCI 0xe8
> +#define PCI_SWSCI_SCISEL (1 << 15)
> +#define PCI_SWSCI_GSSCIE (1 << 0)
> +
> +#define OPREGION_HEADER_OFFSET 0
> +#define OPREGION_ACPI_OFFSET 0x100
> +#define ACPI_CLID 0x01ac /* current lid state indicator */
> +#define ACPI_CDCK 0x01b0 /* current docking state indicator */
> +#define OPREGION_SWSCI_OFFSET 0x200
> +#define OPREGION_ASLE_OFFSET 0x300
> +#define OPREGION_VBT_OFFSET 0x400
> +
> +#define OPREGION_SIGNATURE "IntelGraphicsMem"
> +#define MBOX_ACPI (1<<0)
> +#define MBOX_SWSCI (1<<1)
> +#define MBOX_ASLE (1<<2)
> +#define MBOX_ASLE_EXT (1<<4)
> +
> +struct opregion_header {
> + u8 signature[16];
> + u32 size;
> + u32 opregion_ver;
> + u8 bios_ver[32];
> + u8 vbios_ver[16];
> + u8 driver_ver[16];
> + u32 mboxes;
> + u32 driver_model;
> + u32 pcon;
> + u8 dver[32];
> + u8 rsvd[124];
> +} __packed;
> +
> +/* OpRegion mailbox #1: public ACPI methods */
> +struct opregion_acpi {
> + u32 drdy; /* driver readiness */
> + u32 csts; /* notification status */
> + u32 cevt; /* current event */
> + u8 rsvd1[20];
> + u32 didl[8]; /* supported display devices ID list */
> + u32 cpdl[8]; /* currently presented display list */
> + u32 cadl[8]; /* currently active display list */
> + u32 nadl[8]; /* next active devices list */
> + u32 aslp; /* ASL sleep time-out */
> + u32 tidx; /* toggle table index */
> + u32 chpd; /* current hotplug enable indicator */
> + u32 clid; /* current lid state*/
> + u32 cdck; /* current docking state */
> + u32 sxsw; /* Sx state resume */
> + u32 evts; /* ASL supported events */
> + u32 cnot; /* current OS notification */
> + u32 nrdy; /* driver status */
> + u32 did2[7]; /* extended supported display devices ID list */
> + u32 cpd2[7]; /* extended attached display devices list */
> + u8 rsvd2[4];
> +} __packed;
> +
> +/* OpRegion mailbox #2: SWSCI */
> +struct opregion_swsci {
> + u32 scic; /* SWSCI command|status|data */
> + u32 parm; /* command parameters */
> + u32 dslp; /* driver sleep time-out */
> + u8 rsvd[244];
> +} __packed;
> +
> +/* OpRegion mailbox #3: ASLE */
> +struct opregion_asle {
> + u32 ardy; /* driver readiness */
> + u32 aslc; /* ASLE interrupt command */
> + u32 tche; /* technology enabled indicator */
> + u32 alsi; /* current ALS illuminance reading */
> + u32 bclp; /* backlight brightness to set */
> + u32 pfit; /* panel fitting state */
> + u32 cblv; /* current brightness level */
> + u16 bclm[20]; /* backlight level duty cycle mapping table */
> + u32 cpfm; /* current panel fitting mode */
> + u32 epfm; /* enabled panel fitting modes */
> + u8 plut[74]; /* panel LUT and identifier */
> + u32 pfmb; /* PWM freq and min brightness */
> + u32 cddv; /* color correction default values */
> + u32 pcft; /* power conservation features */
> + u32 srot; /* supported rotation angles */
> + u32 iuer; /* IUER events */
> + u64 fdss;
> + u32 fdsp;
> + u32 stat;
> + u64 rvda; /* Physical address of raw vbt data */
> + u32 rvds; /* Size of raw vbt data */
> + u8 rsvd[58];
> +} __packed;
> +
> +/* Driver readiness indicator */
> +#define ASLE_ARDY_READY (1 << 0)
> +#define ASLE_ARDY_NOT_READY (0 << 0)
> +
> +/* ASLE Interrupt Command (ASLC) bits */
> +#define ASLC_SET_ALS_ILLUM (1 << 0)
> +#define ASLC_SET_BACKLIGHT (1 << 1)
> +#define ASLC_SET_PFIT (1 << 2)
> +#define ASLC_SET_PWM_FREQ (1 << 3)
> +#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
> +#define ASLC_BUTTON_ARRAY (1 << 5)
> +#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
> +#define ASLC_DOCKING_INDICATOR (1 << 7)
> +#define ASLC_ISCT_STATE_CHANGE (1 << 8)
> +#define ASLC_REQ_MSK 0x1ff
> +/* response bits */
> +#define ASLC_ALS_ILLUM_FAILED (1 << 10)
> +#define ASLC_BACKLIGHT_FAILED (1 << 12)
> +#define ASLC_PFIT_FAILED (1 << 14)
> +#define ASLC_PWM_FREQ_FAILED (1 << 16)
> +#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
> +#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
> +#define ASLC_CONVERTIBLE_FAILED (1 << 22)
> +#define ASLC_DOCKING_FAILED (1 << 24)
> +#define ASLC_ISCT_STATE_FAILED (1 << 26)
> +
> +/* Technology enabled indicator */
> +#define ASLE_TCHE_ALS_EN (1 << 0)
> +#define ASLE_TCHE_BLC_EN (1 << 1)
> +#define ASLE_TCHE_PFIT_EN (1 << 2)
> +#define ASLE_TCHE_PFMB_EN (1 << 3)
> +
> +/* ASLE backlight brightness to set */
> +#define ASLE_BCLP_VALID (1<<31)
> +#define ASLE_BCLP_MSK (~(1<<31))
> +
> +/* ASLE panel fitting request */
> +#define ASLE_PFIT_VALID (1<<31)
> +#define ASLE_PFIT_CENTER (1<<0)
> +#define ASLE_PFIT_STRETCH_TEXT (1<<1)
> +#define ASLE_PFIT_STRETCH_GFX (1<<2)
> +
> +/* PWM frequency and minimum brightness */
> +#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
> +#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
> +#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
> +#define ASLE_PFMB_PWM_VALID (1<<31)
> +
> +#define ASLE_CBLV_VALID (1<<31)
> +
> +/* IUER */
> +#define ASLE_IUER_DOCKING (1 << 7)
> +#define ASLE_IUER_CONVERTIBLE (1 << 6)
> +#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
> +#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
> +#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
> +#define ASLE_IUER_WINDOWS_BTN (1 << 1)
> +#define ASLE_IUER_POWER_BTN (1 << 0)
> +
> +/* Software System Control Interrupt (SWSCI) */
> +#define SWSCI_SCIC_INDICATOR (1 << 0)
> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
> +#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
> +#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
> +#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
> +#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
> +
> +#define SWSCI_FUNCTION_CODE(main, sub) \
> + ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
> + (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
> +
> +/* SWSCI: Get BIOS Data (GBDA) */
> +#define SWSCI_GBDA 4
> +#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
> +#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
> +#define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
> +#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
> +#define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
> +#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
> +
> +/* SWSCI: System BIOS Callbacks (SBCB) */
> +#define SWSCI_SBCB 6
> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
> +#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
> +#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
> +#define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
> +#define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
> +#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
> +#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
> +#define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
> +#define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
> +#define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
> +#define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
> +#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
> +#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
> +#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
> +
> +#define ACPI_OTHER_OUTPUT (0<<8)
> +#define ACPI_VGA_OUTPUT (1<<8)
> +#define ACPI_TV_OUTPUT (2<<8)
> +#define ACPI_DIGITAL_OUTPUT (3<<8)
> +#define ACPI_LVDS_OUTPUT (4<<8)
> +
> +#define MAX_DSLP 1500
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB Deepak M
2015-09-16 13:24 ` Jani Nikula
@ 2015-09-17 12:10 ` Jani Nikula
2015-09-22 6:37 ` Deepak, M
1 sibling, 1 reply; 25+ messages in thread
From: Jani Nikula @ 2015-09-17 12:10 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
> Currently the iomap for VBT works only if the size of the
> VBT is less than 6KB, but if the size of the VBT exceeds
> 6KB than the physical address and the size of the VBT to
> be iomapped is specified in the mailbox3 and is iomapped
> accordingly.
>
> v2: - Moving the validate_vbt to opregion file (Jani)
> - Fix the i915_opregion() in debugfs (Jani)
>
> Signed-off-by: Deepak M <m.deepak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 24 ++-
> drivers/gpu/drm/i915/i915_drv.h | 4 +
> drivers/gpu/drm/i915/intel_bios.c | 49 +-----
> drivers/gpu/drm/i915/intel_opregion.c | 279 +++++++++------------------------
> drivers/gpu/drm/i915/intel_opregion.h | 230 +++++++++++++++++++++++++++
> 5 files changed, 329 insertions(+), 257 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/intel_opregion.h
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 41629fa..5534aa2 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -26,6 +26,8 @@
> *
> */
>
> +#include <linux/acpi.h>
> +#include <acpi/video.h>
> #include <linux/seq_file.h>
> #include <linux/circ_buf.h>
> #include <linux/ctype.h>
> @@ -39,6 +41,7 @@
> #include "intel_ringbuffer.h"
> #include <drm/i915_drm.h>
> #include "i915_drv.h"
> +#include "intel_opregion.h"
>
> enum {
> ACTIVE_LIST,
> @@ -1832,7 +1835,7 @@ static int i915_opregion(struct seq_file *m, void *unused)
> struct drm_device *dev = node->minor->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_opregion *opregion = &dev_priv->opregion;
> - void *data = kmalloc(OPREGION_SIZE, GFP_KERNEL);
> + void *data = kmalloc(OPREGION_VBT_OFFSET, GFP_KERNEL);
> int ret;
>
> if (data == NULL)
> @@ -1843,12 +1846,25 @@ static int i915_opregion(struct seq_file *m, void *unused)
> goto out;
>
> if (opregion->header) {
> - memcpy_fromio(data, opregion->header, OPREGION_SIZE);
> - seq_write(m, data, OPREGION_SIZE);
> + memcpy_fromio(data, opregion->header, OPREGION_VBT_OFFSET);
> + seq_write(m, data, OPREGION_VBT_OFFSET);
> + kfree(data);
> + if (opregion->asle->rvda) {
> + data = kmalloc(opregion->asle->rvds, GFP_KERNEL);
> + memcpy_fromio(data,
> + (const void __iomem *) opregion->asle->rvda,
> + opregion->asle->rvds);
> + seq_write(m, data, opregion->asle->rvds);
> + } else {
> + data = kmalloc(OPREGION_SIZE - OPREGION_VBT_OFFSET,
> + GFP_KERNEL);
> + memcpy_fromio(data, opregion->vbt,
> + OPREGION_SIZE - OPREGION_VBT_OFFSET);
> + seq_write(m, data, OPREGION_SIZE - OPREGION_VBT_OFFSET);
> + }
If rvda != 0, this debugfs file no longer represents the opregion
contents. Mailboxes #4 and #5 are dropped from the output. BTW, what is
mailbox #4 expected to contain when rvda != 0? (I still don't have
access to the latest opregion spec version, so can't check what it
actually says.)
I am beginning to think we should leave "i915_opregion" debugfs file
intact, and add a new "i915_vbt" file that contains either mailbox #4 or
the data in rvda. This might be a cleaner approach.
See my comments below, and you'll see how this would be feasible.
> }
>
> mutex_unlock(&dev->struct_mutex);
> -
> out:
> kfree(data);
> return 0;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1287007..507d57a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1780,6 +1780,7 @@ struct drm_i915_private {
> struct i915_hotplug hotplug;
> struct i915_fbc fbc;
> struct i915_drrs drrs;
> + const struct bdb_header *bdb_start;
What is wrong with using dev_priv->opregion.vbt for this?
> struct intel_opregion opregion;
> struct intel_vbt_data vbt;
>
> @@ -3306,6 +3307,9 @@ intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
> }
> #endif
>
> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
> + size_t size, const char *source);
> +
> /* intel_acpi.c */
> #ifdef CONFIG_ACPI
> extern void intel_register_dsm_handler(void);
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index 0bf0942..1932a86 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -1227,49 +1227,6 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
> { }
> };
>
> -static const struct bdb_header *validate_vbt(const void __iomem *_base,
> - size_t size,
> - const void __iomem *_vbt,
> - const char *source)
> -{
> - /*
> - * This is the one place where we explicitly discard the address space
> - * (__iomem) of the BIOS/VBT. (And this will cause a sparse complaint.)
> - * From now on everything is based on 'base', and treated as regular
> - * memory.
> - */
> - const void *base = (const void *) _base;
> - size_t offset = _vbt - _base;
> - const struct vbt_header *vbt = base + offset;
> - const struct bdb_header *bdb;
> -
> - if (offset + sizeof(struct vbt_header) > size) {
> - DRM_DEBUG_DRIVER("VBT header incomplete\n");
> - return NULL;
> - }
> -
> - if (memcmp(vbt->signature, "$VBT", 4)) {
> - DRM_DEBUG_DRIVER("VBT invalid signature\n");
> - return NULL;
> - }
> -
> - offset += vbt->bdb_offset;
> - if (offset + sizeof(struct bdb_header) > size) {
> - DRM_DEBUG_DRIVER("BDB header incomplete\n");
> - return NULL;
> - }
> -
> - bdb = base + offset;
> - if (offset + bdb->bdb_size > size) {
> - DRM_DEBUG_DRIVER("BDB incomplete\n");
> - return NULL;
> - }
> -
> - DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
> - source, vbt->signature);
> - return bdb;
> -}
> -
Moving of this function should be a separate prep patch.
> static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
> {
> const struct bdb_header *bdb = NULL;
> @@ -1278,7 +1235,7 @@ static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
> /* Scour memory looking for the VBT signature. */
> for (i = 0; i + 4 < size; i++) {
> if (ioread32(bios + i) == *((const u32 *) "$VBT")) {
> - bdb = validate_vbt(bios, size, bios + i, "PCI ROM");
> + bdb = validate_vbt(bios + i, size - i, "PCI ROM");
> break;
> }
> }
> @@ -1308,10 +1265,8 @@ intel_parse_bios(struct drm_device *dev)
>
> init_vbt_defaults(dev_priv);
>
> - /* XXX Should this validation be moved to intel_opregion.c? */
> if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt)
> - bdb = validate_vbt(dev_priv->opregion.header, OPREGION_SIZE,
> - dev_priv->opregion.vbt, "OpRegion");
> + bdb = dev_priv->bdb_start;
This should be dev_priv->opregion.vbt.
>
> if (bdb == NULL) {
> size_t size;
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index f46231f..3a43db9 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -32,210 +32,7 @@
> #include <drm/i915_drm.h>
> #include "i915_drv.h"
> #include "intel_drv.h"
> -
> -#define PCI_ASLE 0xe4
> -#define PCI_ASLS 0xfc
> -#define PCI_SWSCI 0xe8
> -#define PCI_SWSCI_SCISEL (1 << 15)
> -#define PCI_SWSCI_GSSCIE (1 << 0)
> -
> -#define OPREGION_HEADER_OFFSET 0
> -#define OPREGION_ACPI_OFFSET 0x100
> -#define ACPI_CLID 0x01ac /* current lid state indicator */
> -#define ACPI_CDCK 0x01b0 /* current docking state indicator */
> -#define OPREGION_SWSCI_OFFSET 0x200
> -#define OPREGION_ASLE_OFFSET 0x300
> -#define OPREGION_VBT_OFFSET 0x400
> -
> -#define OPREGION_SIGNATURE "IntelGraphicsMem"
> -#define MBOX_ACPI (1<<0)
> -#define MBOX_SWSCI (1<<1)
> -#define MBOX_ASLE (1<<2)
> -#define MBOX_ASLE_EXT (1<<4)
> -
> -struct opregion_header {
> - u8 signature[16];
> - u32 size;
> - u32 opregion_ver;
> - u8 bios_ver[32];
> - u8 vbios_ver[16];
> - u8 driver_ver[16];
> - u32 mboxes;
> - u32 driver_model;
> - u32 pcon;
> - u8 dver[32];
> - u8 rsvd[124];
> -} __packed;
> -
> -/* OpRegion mailbox #1: public ACPI methods */
> -struct opregion_acpi {
> - u32 drdy; /* driver readiness */
> - u32 csts; /* notification status */
> - u32 cevt; /* current event */
> - u8 rsvd1[20];
> - u32 didl[8]; /* supported display devices ID list */
> - u32 cpdl[8]; /* currently presented display list */
> - u32 cadl[8]; /* currently active display list */
> - u32 nadl[8]; /* next active devices list */
> - u32 aslp; /* ASL sleep time-out */
> - u32 tidx; /* toggle table index */
> - u32 chpd; /* current hotplug enable indicator */
> - u32 clid; /* current lid state*/
> - u32 cdck; /* current docking state */
> - u32 sxsw; /* Sx state resume */
> - u32 evts; /* ASL supported events */
> - u32 cnot; /* current OS notification */
> - u32 nrdy; /* driver status */
> - u32 did2[7]; /* extended supported display devices ID list */
> - u32 cpd2[7]; /* extended attached display devices list */
> - u8 rsvd2[4];
> -} __packed;
> -
> -/* OpRegion mailbox #2: SWSCI */
> -struct opregion_swsci {
> - u32 scic; /* SWSCI command|status|data */
> - u32 parm; /* command parameters */
> - u32 dslp; /* driver sleep time-out */
> - u8 rsvd[244];
> -} __packed;
> -
> -/* OpRegion mailbox #3: ASLE */
> -struct opregion_asle {
> - u32 ardy; /* driver readiness */
> - u32 aslc; /* ASLE interrupt command */
> - u32 tche; /* technology enabled indicator */
> - u32 alsi; /* current ALS illuminance reading */
> - u32 bclp; /* backlight brightness to set */
> - u32 pfit; /* panel fitting state */
> - u32 cblv; /* current brightness level */
> - u16 bclm[20]; /* backlight level duty cycle mapping table */
> - u32 cpfm; /* current panel fitting mode */
> - u32 epfm; /* enabled panel fitting modes */
> - u8 plut[74]; /* panel LUT and identifier */
> - u32 pfmb; /* PWM freq and min brightness */
> - u32 cddv; /* color correction default values */
> - u32 pcft; /* power conservation features */
> - u32 srot; /* supported rotation angles */
> - u32 iuer; /* IUER events */
> - u64 fdss;
> - u32 fdsp;
> - u32 stat;
> - u64 rvda; /* Physical address of raw vbt data */
> - u32 rvds; /* Size of raw vbt data */
> - u8 rsvd[58];
> -} __packed;
> -
> -/* Driver readiness indicator */
> -#define ASLE_ARDY_READY (1 << 0)
> -#define ASLE_ARDY_NOT_READY (0 << 0)
> -
> -/* ASLE Interrupt Command (ASLC) bits */
> -#define ASLC_SET_ALS_ILLUM (1 << 0)
> -#define ASLC_SET_BACKLIGHT (1 << 1)
> -#define ASLC_SET_PFIT (1 << 2)
> -#define ASLC_SET_PWM_FREQ (1 << 3)
> -#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
> -#define ASLC_BUTTON_ARRAY (1 << 5)
> -#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
> -#define ASLC_DOCKING_INDICATOR (1 << 7)
> -#define ASLC_ISCT_STATE_CHANGE (1 << 8)
> -#define ASLC_REQ_MSK 0x1ff
> -/* response bits */
> -#define ASLC_ALS_ILLUM_FAILED (1 << 10)
> -#define ASLC_BACKLIGHT_FAILED (1 << 12)
> -#define ASLC_PFIT_FAILED (1 << 14)
> -#define ASLC_PWM_FREQ_FAILED (1 << 16)
> -#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
> -#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
> -#define ASLC_CONVERTIBLE_FAILED (1 << 22)
> -#define ASLC_DOCKING_FAILED (1 << 24)
> -#define ASLC_ISCT_STATE_FAILED (1 << 26)
> -
> -/* Technology enabled indicator */
> -#define ASLE_TCHE_ALS_EN (1 << 0)
> -#define ASLE_TCHE_BLC_EN (1 << 1)
> -#define ASLE_TCHE_PFIT_EN (1 << 2)
> -#define ASLE_TCHE_PFMB_EN (1 << 3)
> -
> -/* ASLE backlight brightness to set */
> -#define ASLE_BCLP_VALID (1<<31)
> -#define ASLE_BCLP_MSK (~(1<<31))
> -
> -/* ASLE panel fitting request */
> -#define ASLE_PFIT_VALID (1<<31)
> -#define ASLE_PFIT_CENTER (1<<0)
> -#define ASLE_PFIT_STRETCH_TEXT (1<<1)
> -#define ASLE_PFIT_STRETCH_GFX (1<<2)
> -
> -/* PWM frequency and minimum brightness */
> -#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
> -#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
> -#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
> -#define ASLE_PFMB_PWM_VALID (1<<31)
> -
> -#define ASLE_CBLV_VALID (1<<31)
> -
> -/* IUER */
> -#define ASLE_IUER_DOCKING (1 << 7)
> -#define ASLE_IUER_CONVERTIBLE (1 << 6)
> -#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
> -#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
> -#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
> -#define ASLE_IUER_WINDOWS_BTN (1 << 1)
> -#define ASLE_IUER_POWER_BTN (1 << 0)
> -
> -/* Software System Control Interrupt (SWSCI) */
> -#define SWSCI_SCIC_INDICATOR (1 << 0)
> -#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
> -#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
> -#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
> -#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
> -#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
> -#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
> -#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
> -#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
> -#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
> -
> -#define SWSCI_FUNCTION_CODE(main, sub) \
> - ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
> - (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
> -
> -/* SWSCI: Get BIOS Data (GBDA) */
> -#define SWSCI_GBDA 4
> -#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
> -#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
> -#define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
> -#define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
> -#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
> -#define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
> -#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
> -
> -/* SWSCI: System BIOS Callbacks (SBCB) */
> -#define SWSCI_SBCB 6
> -#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
> -#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
> -#define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
> -#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
> -#define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
> -#define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
> -#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
> -#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
> -#define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
> -#define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
> -#define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
> -#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
> -#define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
> -#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
> -#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
> -#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
> -
> -#define ACPI_OTHER_OUTPUT (0<<8)
> -#define ACPI_VGA_OUTPUT (1<<8)
> -#define ACPI_TV_OUTPUT (2<<8)
> -#define ACPI_DIGITAL_OUTPUT (3<<8)
> -#define ACPI_LVDS_OUTPUT (4<<8)
> -
> -#define MAX_DSLP 1500
> +#include "intel_opregion.h"
As said, I don't see the need to move these defines to a separate
header. This is definitely stuff that we want to keep hidden in one
place, and nobody outside of intel_opregion.c should use these.
>
> #ifdef CONFIG_ACPI
> static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
> @@ -892,13 +689,55 @@ static void swsci_setup(struct drm_device *dev)
> static inline void swsci_setup(struct drm_device *dev) {}
> #endif /* CONFIG_ACPI */
>
> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
> + size_t size,
> + const char *source)
> +{
> + /*
> + * This is the one place where we explicitly discard the address space
> + * (__iomem) of the BIOS/VBT. (And this will cause a sparse complaint.)
> + */
> + const struct vbt_header *vbt = (const struct vbt_header *)_vbt;
> + const struct bdb_header *bdb;
> + size_t offset;
> +
> + if (sizeof(struct vbt_header) > size) {
> + DRM_DEBUG_DRIVER("VBT header incomplete\n");
> + return NULL;
> + }
> +
> + if (memcmp(vbt->signature, "$VBT", 4)) {
> + DRM_DEBUG_DRIVER("VBT invalid signature\n");
> + return NULL;
> + }
> +
> + offset = vbt->bdb_offset;
> + if (offset + sizeof(struct bdb_header) > size) {
> + DRM_DEBUG_DRIVER("BDB header incomplete\n");
> + return NULL;
> + }
> +
> + bdb = (const void *)_vbt + offset;
> + if (offset + bdb->bdb_size > size) {
> + DRM_DEBUG_DRIVER("BDB incomplete\n");
> + return NULL;
> + }
> +
> + DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
> + source, vbt->signature);
> + return bdb;
> +}
> +
> int intel_opregion_setup(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_opregion *opregion = &dev_priv->opregion;
> void __iomem *base;
> + void __iomem *vbt_base;
> u32 asls, mboxes;
> char buf[sizeof(OPREGION_SIGNATURE)];
> + const struct bdb_header *bdb = NULL;
> + size_t size;
> int err = 0;
>
> BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
> @@ -917,7 +756,7 @@ int intel_opregion_setup(struct drm_device *dev)
> INIT_WORK(&opregion->asle_work, asle_work);
> #endif
>
> - base = acpi_os_ioremap(asls, OPREGION_SIZE);
> + base = acpi_os_ioremap(asls, OPREGION_VBT_OFFSET);
Now you leave out mailbox #5. I don't think there's any reason *not* to
ioremap all of opregion here.
> if (!base)
> return -ENOMEM;
>
> @@ -929,7 +768,33 @@ int intel_opregion_setup(struct drm_device *dev)
> goto err_out;
> }
> opregion->header = base;
> - opregion->vbt = base + OPREGION_VBT_OFFSET;
> + /* Assigning the alse to the mailbox 3 of the opregion */
> + opregion->asle = base + OPREGION_ASLE_OFFSET;
That's assigned towards the end of the function *if* the mbox is
supported.
> +
> + /*
> + * Non-zero value in rvda field is an indication to driver that a
> + * valid Raw VBT is stored in that address and driver should not refer
> + * to mailbox4 for getting VBT.
> + */
> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda) {
> + size = opregion->asle->rvds;
> + vbt_base = acpi_os_ioremap(opregion->asle->rvda,
> + size);
> + } else {
> + size = OPREGION_SIZE - OPREGION_VBT_OFFSET;
> + vbt_base = acpi_os_ioremap(asls + OPREGION_VBT_OFFSET,
> + size);
> + }
> +
> + bdb = validate_vbt(vbt_base, size, "OpRegion");
> +
> + if (bdb == NULL) {
> + err = -EINVAL;
> + goto err_vbt;
> + }
> +
> + dev_priv->bdb_start = bdb;
Again, I don't see why you should store this here. Nor I see the need to
actually validate vbt here. You can just as well do it in intel_bios
like before, as long as you assign opregion->vbt here appropriately.
You'll also need to iounmap vbt_base in intel_opregion_fini. That may
need some additional checks if you unconditionally ioremap all of
opregion and conditionally ioremap rvda, and point opregion->vbt to it.
> + opregion->vbt = vbt_base;
>
> opregion->lid_state = base + ACPI_CLID;
>
> @@ -953,6 +818,8 @@ int intel_opregion_setup(struct drm_device *dev)
>
> return 0;
>
> +err_vbt:
> + iounmap(vbt_base);
> err_out:
> iounmap(base);
> return err;
> diff --git a/drivers/gpu/drm/i915/intel_opregion.h b/drivers/gpu/drm/i915/intel_opregion.h
> new file mode 100644
> index 0000000..bcb45ec
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_opregion.h
> @@ -0,0 +1,230 @@
> +/*
> + * Copyright 2008 Intel Corporation <hong.liu@intel.com>
> + * Copyright 2008 Red Hat <mjg@redhat.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 INTEL 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.
> + *
> + */
> +
> +#define PCI_ASLE 0xe4
> +#define PCI_ASLS 0xfc
> +#define PCI_SWSCI 0xe8
> +#define PCI_SWSCI_SCISEL (1 << 15)
> +#define PCI_SWSCI_GSSCIE (1 << 0)
> +
> +#define OPREGION_HEADER_OFFSET 0
> +#define OPREGION_ACPI_OFFSET 0x100
> +#define ACPI_CLID 0x01ac /* current lid state indicator */
> +#define ACPI_CDCK 0x01b0 /* current docking state indicator */
> +#define OPREGION_SWSCI_OFFSET 0x200
> +#define OPREGION_ASLE_OFFSET 0x300
> +#define OPREGION_VBT_OFFSET 0x400
> +
> +#define OPREGION_SIGNATURE "IntelGraphicsMem"
> +#define MBOX_ACPI (1<<0)
> +#define MBOX_SWSCI (1<<1)
> +#define MBOX_ASLE (1<<2)
> +#define MBOX_ASLE_EXT (1<<4)
> +
> +struct opregion_header {
> + u8 signature[16];
> + u32 size;
> + u32 opregion_ver;
> + u8 bios_ver[32];
> + u8 vbios_ver[16];
> + u8 driver_ver[16];
> + u32 mboxes;
> + u32 driver_model;
> + u32 pcon;
> + u8 dver[32];
> + u8 rsvd[124];
> +} __packed;
> +
> +/* OpRegion mailbox #1: public ACPI methods */
> +struct opregion_acpi {
> + u32 drdy; /* driver readiness */
> + u32 csts; /* notification status */
> + u32 cevt; /* current event */
> + u8 rsvd1[20];
> + u32 didl[8]; /* supported display devices ID list */
> + u32 cpdl[8]; /* currently presented display list */
> + u32 cadl[8]; /* currently active display list */
> + u32 nadl[8]; /* next active devices list */
> + u32 aslp; /* ASL sleep time-out */
> + u32 tidx; /* toggle table index */
> + u32 chpd; /* current hotplug enable indicator */
> + u32 clid; /* current lid state*/
> + u32 cdck; /* current docking state */
> + u32 sxsw; /* Sx state resume */
> + u32 evts; /* ASL supported events */
> + u32 cnot; /* current OS notification */
> + u32 nrdy; /* driver status */
> + u32 did2[7]; /* extended supported display devices ID list */
> + u32 cpd2[7]; /* extended attached display devices list */
> + u8 rsvd2[4];
> +} __packed;
> +
> +/* OpRegion mailbox #2: SWSCI */
> +struct opregion_swsci {
> + u32 scic; /* SWSCI command|status|data */
> + u32 parm; /* command parameters */
> + u32 dslp; /* driver sleep time-out */
> + u8 rsvd[244];
> +} __packed;
> +
> +/* OpRegion mailbox #3: ASLE */
> +struct opregion_asle {
> + u32 ardy; /* driver readiness */
> + u32 aslc; /* ASLE interrupt command */
> + u32 tche; /* technology enabled indicator */
> + u32 alsi; /* current ALS illuminance reading */
> + u32 bclp; /* backlight brightness to set */
> + u32 pfit; /* panel fitting state */
> + u32 cblv; /* current brightness level */
> + u16 bclm[20]; /* backlight level duty cycle mapping table */
> + u32 cpfm; /* current panel fitting mode */
> + u32 epfm; /* enabled panel fitting modes */
> + u8 plut[74]; /* panel LUT and identifier */
> + u32 pfmb; /* PWM freq and min brightness */
> + u32 cddv; /* color correction default values */
> + u32 pcft; /* power conservation features */
> + u32 srot; /* supported rotation angles */
> + u32 iuer; /* IUER events */
> + u64 fdss;
> + u32 fdsp;
> + u32 stat;
> + u64 rvda; /* Physical address of raw vbt data */
> + u32 rvds; /* Size of raw vbt data */
> + u8 rsvd[58];
> +} __packed;
> +
> +/* Driver readiness indicator */
> +#define ASLE_ARDY_READY (1 << 0)
> +#define ASLE_ARDY_NOT_READY (0 << 0)
> +
> +/* ASLE Interrupt Command (ASLC) bits */
> +#define ASLC_SET_ALS_ILLUM (1 << 0)
> +#define ASLC_SET_BACKLIGHT (1 << 1)
> +#define ASLC_SET_PFIT (1 << 2)
> +#define ASLC_SET_PWM_FREQ (1 << 3)
> +#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
> +#define ASLC_BUTTON_ARRAY (1 << 5)
> +#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
> +#define ASLC_DOCKING_INDICATOR (1 << 7)
> +#define ASLC_ISCT_STATE_CHANGE (1 << 8)
> +#define ASLC_REQ_MSK 0x1ff
> +/* response bits */
> +#define ASLC_ALS_ILLUM_FAILED (1 << 10)
> +#define ASLC_BACKLIGHT_FAILED (1 << 12)
> +#define ASLC_PFIT_FAILED (1 << 14)
> +#define ASLC_PWM_FREQ_FAILED (1 << 16)
> +#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
> +#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
> +#define ASLC_CONVERTIBLE_FAILED (1 << 22)
> +#define ASLC_DOCKING_FAILED (1 << 24)
> +#define ASLC_ISCT_STATE_FAILED (1 << 26)
> +
> +/* Technology enabled indicator */
> +#define ASLE_TCHE_ALS_EN (1 << 0)
> +#define ASLE_TCHE_BLC_EN (1 << 1)
> +#define ASLE_TCHE_PFIT_EN (1 << 2)
> +#define ASLE_TCHE_PFMB_EN (1 << 3)
> +
> +/* ASLE backlight brightness to set */
> +#define ASLE_BCLP_VALID (1<<31)
> +#define ASLE_BCLP_MSK (~(1<<31))
> +
> +/* ASLE panel fitting request */
> +#define ASLE_PFIT_VALID (1<<31)
> +#define ASLE_PFIT_CENTER (1<<0)
> +#define ASLE_PFIT_STRETCH_TEXT (1<<1)
> +#define ASLE_PFIT_STRETCH_GFX (1<<2)
> +
> +/* PWM frequency and minimum brightness */
> +#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
> +#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
> +#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
> +#define ASLE_PFMB_PWM_VALID (1<<31)
> +
> +#define ASLE_CBLV_VALID (1<<31)
> +
> +/* IUER */
> +#define ASLE_IUER_DOCKING (1 << 7)
> +#define ASLE_IUER_CONVERTIBLE (1 << 6)
> +#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
> +#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
> +#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
> +#define ASLE_IUER_WINDOWS_BTN (1 << 1)
> +#define ASLE_IUER_POWER_BTN (1 << 0)
> +
> +/* Software System Control Interrupt (SWSCI) */
> +#define SWSCI_SCIC_INDICATOR (1 << 0)
> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
> +#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
> +#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
> +#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
> +#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
> +
> +#define SWSCI_FUNCTION_CODE(main, sub) \
> + ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
> + (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
> +
> +/* SWSCI: Get BIOS Data (GBDA) */
> +#define SWSCI_GBDA 4
> +#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
> +#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
> +#define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
> +#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
> +#define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
> +#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
> +
> +/* SWSCI: System BIOS Callbacks (SBCB) */
> +#define SWSCI_SBCB 6
> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
> +#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
> +#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
> +#define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
> +#define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
> +#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
> +#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
> +#define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
> +#define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
> +#define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
> +#define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
> +#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
> +#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
> +#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
> +
> +#define ACPI_OTHER_OUTPUT (0<<8)
> +#define ACPI_VGA_OUTPUT (1<<8)
> +#define ACPI_TV_OUTPUT (2<<8)
> +#define ACPI_DIGITAL_OUTPUT (3<<8)
> +#define ACPI_LVDS_OUTPUT (4<<8)
> +
> +#define MAX_DSLP 1500
The bottom line here is that I think you could get all of this done with
*much* smaller changes. If we get a regression report pointing at this
patch, we'll have a lot of debugging to do to figure out what failed.
BR,
Jani.
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB
2015-09-17 12:10 ` Jani Nikula
@ 2015-09-22 6:37 ` Deepak, M
2015-09-22 7:24 ` Jani Nikula
0 siblings, 1 reply; 25+ messages in thread
From: Deepak, M @ 2015-09-22 6:37 UTC (permalink / raw)
To: Jani Nikula, intel-gfx@lists.freedesktop.org
>-----Original Message-----
>From: Jani Nikula [mailto:jani.nikula@linux.intel.com]
>Sent: Thursday, September 17, 2015 5:41 PM
>To: Deepak, M; intel-gfx@lists.freedesktop.org
>Cc: Deepak, M
>Subject: Re: [Intel-gfx] [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing
>VBT if size of VBT exceeds 6KB
>
>On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
>> Currently the iomap for VBT works only if the size of the VBT is less
>> than 6KB, but if the size of the VBT exceeds 6KB than the physical
>> address and the size of the VBT to be iomapped is specified in the
>> mailbox3 and is iomapped accordingly.
>>
>> v2: - Moving the validate_vbt to opregion file (Jani)
>> - Fix the i915_opregion() in debugfs (Jani)
>>
>> Signed-off-by: Deepak M <m.deepak@intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_debugfs.c | 24 ++-
>> drivers/gpu/drm/i915/i915_drv.h | 4 +
>> drivers/gpu/drm/i915/intel_bios.c | 49 +-----
>> drivers/gpu/drm/i915/intel_opregion.c | 279
>> +++++++++------------------------
>> drivers/gpu/drm/i915/intel_opregion.h | 230
>> +++++++++++++++++++++++++++
>> 5 files changed, 329 insertions(+), 257 deletions(-) create mode
>> 100644 drivers/gpu/drm/i915/intel_opregion.h
>>
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
>> b/drivers/gpu/drm/i915/i915_debugfs.c
>> index 41629fa..5534aa2 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -26,6 +26,8 @@
>> *
>> */
>>
>> +#include <linux/acpi.h>
>> +#include <acpi/video.h>
>> #include <linux/seq_file.h>
>> #include <linux/circ_buf.h>
>> #include <linux/ctype.h>
>> @@ -39,6 +41,7 @@
>> #include "intel_ringbuffer.h"
>> #include <drm/i915_drm.h>
>> #include "i915_drv.h"
>> +#include "intel_opregion.h"
>>
>> enum {
>> ACTIVE_LIST,
>> @@ -1832,7 +1835,7 @@ static int i915_opregion(struct seq_file *m, void
>*unused)
>> struct drm_device *dev = node->minor->dev;
>> struct drm_i915_private *dev_priv = dev->dev_private;
>> struct intel_opregion *opregion = &dev_priv->opregion;
>> - void *data = kmalloc(OPREGION_SIZE, GFP_KERNEL);
>> + void *data = kmalloc(OPREGION_VBT_OFFSET, GFP_KERNEL);
>> int ret;
>>
>> if (data == NULL)
>> @@ -1843,12 +1846,25 @@ static int i915_opregion(struct seq_file *m, void
>*unused)
>> goto out;
>>
>> if (opregion->header) {
>> - memcpy_fromio(data, opregion->header, OPREGION_SIZE);
>> - seq_write(m, data, OPREGION_SIZE);
>> + memcpy_fromio(data, opregion->header,
>OPREGION_VBT_OFFSET);
>> + seq_write(m, data, OPREGION_VBT_OFFSET);
>> + kfree(data);
>> + if (opregion->asle->rvda) {
>> + data = kmalloc(opregion->asle->rvds, GFP_KERNEL);
>> + memcpy_fromio(data,
>> + (const void __iomem *) opregion->asle->rvda,
>> + opregion->asle->rvds);
>> + seq_write(m, data, opregion->asle->rvds);
>> + } else {
>> + data = kmalloc(OPREGION_SIZE -
>OPREGION_VBT_OFFSET,
>> + GFP_KERNEL);
>> + memcpy_fromio(data, opregion->vbt,
>> + OPREGION_SIZE -
>OPREGION_VBT_OFFSET);
>> + seq_write(m, data, OPREGION_SIZE -
>OPREGION_VBT_OFFSET);
>> + }
>
>If rvda != 0, this debugfs file no longer represents the opregion contents.
>Mailboxes #4 and #5 are dropped from the output. BTW, what is mailbox #4
>expected to contain when rvda != 0? (I still don't have access to the latest
>opregion spec version, so can't check what it actually says.)
>
>I am beginning to think we should leave "i915_opregion" debugfs file intact,
>and add a new "i915_vbt" file that contains either mailbox #4 or the data in
>rvda. This might be a cleaner approach.
>
>See my comments below, and you'll see how this would be feasible.
>
[Deepak M] I was thinking of splitting this function into 5 for dumping each mailbox. Which
I felt will be cleaner.
>> }
>>
>> mutex_unlock(&dev->struct_mutex);
>> -
>> out:
>> kfree(data);
>> return 0;
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>> b/drivers/gpu/drm/i915/i915_drv.h index 1287007..507d57a 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1780,6 +1780,7 @@ struct drm_i915_private {
>> struct i915_hotplug hotplug;
>> struct i915_fbc fbc;
>> struct i915_drrs drrs;
>> + const struct bdb_header *bdb_start;
>
>What is wrong with using dev_priv->opregion.vbt for this?
>
>> struct intel_opregion opregion;
>> struct intel_vbt_data vbt;
>>
>> @@ -3306,6 +3307,9 @@ intel_opregion_notify_adapter(struct drm_device
>> *dev, pci_power_t state) } #endif
>>
>> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
>> + size_t size, const char *source);
>> +
>> /* intel_acpi.c */
>> #ifdef CONFIG_ACPI
>> extern void intel_register_dsm_handler(void); diff --git
>> a/drivers/gpu/drm/i915/intel_bios.c
>> b/drivers/gpu/drm/i915/intel_bios.c
>> index 0bf0942..1932a86 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.c
>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>> @@ -1227,49 +1227,6 @@ static const struct dmi_system_id
>intel_no_opregion_vbt[] = {
>> { }
>> };
>>
>> -static const struct bdb_header *validate_vbt(const void __iomem *_base,
>> - size_t size,
>> - const void __iomem *_vbt,
>> - const char *source)
>> -{
>> - /*
>> - * This is the one place where we explicitly discard the address space
>> - * (__iomem) of the BIOS/VBT. (And this will cause a sparse
>complaint.)
>> - * From now on everything is based on 'base', and treated as regular
>> - * memory.
>> - */
>> - const void *base = (const void *) _base;
>> - size_t offset = _vbt - _base;
>> - const struct vbt_header *vbt = base + offset;
>> - const struct bdb_header *bdb;
>> -
>> - if (offset + sizeof(struct vbt_header) > size) {
>> - DRM_DEBUG_DRIVER("VBT header incomplete\n");
>> - return NULL;
>> - }
>> -
>> - if (memcmp(vbt->signature, "$VBT", 4)) {
>> - DRM_DEBUG_DRIVER("VBT invalid signature\n");
>> - return NULL;
>> - }
>> -
>> - offset += vbt->bdb_offset;
>> - if (offset + sizeof(struct bdb_header) > size) {
>> - DRM_DEBUG_DRIVER("BDB header incomplete\n");
>> - return NULL;
>> - }
>> -
>> - bdb = base + offset;
>> - if (offset + bdb->bdb_size > size) {
>> - DRM_DEBUG_DRIVER("BDB incomplete\n");
>> - return NULL;
>> - }
>> -
>> - DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
>> - source, vbt->signature);
>> - return bdb;
>> -}
>> -
>
>Moving of this function should be a separate prep patch.
>
>> static const struct bdb_header *find_vbt(void __iomem *bios, size_t
>> size) {
>> const struct bdb_header *bdb = NULL; @@ -1278,7 +1235,7 @@ static
>> const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
>> /* Scour memory looking for the VBT signature. */
>> for (i = 0; i + 4 < size; i++) {
>> if (ioread32(bios + i) == *((const u32 *) "$VBT")) {
>> - bdb = validate_vbt(bios, size, bios + i, "PCI ROM");
>> + bdb = validate_vbt(bios + i, size - i, "PCI ROM");
>> break;
>> }
>> }
>> @@ -1308,10 +1265,8 @@ intel_parse_bios(struct drm_device *dev)
>>
>> init_vbt_defaults(dev_priv);
>>
>> - /* XXX Should this validation be moved to intel_opregion.c? */
>> if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv-
>>opregion.vbt)
>> - bdb = validate_vbt(dev_priv->opregion.header,
>OPREGION_SIZE,
>> - dev_priv->opregion.vbt, "OpRegion");
>> + bdb = dev_priv->bdb_start;
>
>This should be dev_priv->opregion.vbt.
[Deepak M] validate_vbt function always returns the bdb header and our parsing starts from the bdb_header and not form the dev_priv->opregion.vbt where the VBT header starts. So I have added bdb_start in the dev_priv structure.
>
>>
>> if (bdb == NULL) {
>> size_t size;
>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c
>> b/drivers/gpu/drm/i915/intel_opregion.c
>> index f46231f..3a43db9 100644
>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>> @@ -32,210 +32,7 @@
>> #include <drm/i915_drm.h>
>> #include "i915_drv.h"
>> #include "intel_drv.h"
>> -
>> -#define PCI_ASLE 0xe4
>> -#define PCI_ASLS 0xfc
>> -#define PCI_SWSCI 0xe8
>> -#define PCI_SWSCI_SCISEL (1 << 15)
>> -#define PCI_SWSCI_GSSCIE (1 << 0)
>> -
>> -#define OPREGION_HEADER_OFFSET 0
>> -#define OPREGION_ACPI_OFFSET 0x100
>> -#define ACPI_CLID 0x01ac /* current lid state indicator */
>> -#define ACPI_CDCK 0x01b0 /* current docking state indicator */
>> -#define OPREGION_SWSCI_OFFSET 0x200
>> -#define OPREGION_ASLE_OFFSET 0x300
>> -#define OPREGION_VBT_OFFSET 0x400
>> -
>> -#define OPREGION_SIGNATURE "IntelGraphicsMem"
>> -#define MBOX_ACPI (1<<0)
>> -#define MBOX_SWSCI (1<<1)
>> -#define MBOX_ASLE (1<<2)
>> -#define MBOX_ASLE_EXT (1<<4)
>> -
>> -struct opregion_header {
>> - u8 signature[16];
>> - u32 size;
>> - u32 opregion_ver;
>> - u8 bios_ver[32];
>> - u8 vbios_ver[16];
>> - u8 driver_ver[16];
>> - u32 mboxes;
>> - u32 driver_model;
>> - u32 pcon;
>> - u8 dver[32];
>> - u8 rsvd[124];
>> -} __packed;
>> -
>> -/* OpRegion mailbox #1: public ACPI methods */ -struct opregion_acpi
>> {
>> - u32 drdy; /* driver readiness */
>> - u32 csts; /* notification status */
>> - u32 cevt; /* current event */
>> - u8 rsvd1[20];
>> - u32 didl[8]; /* supported display devices ID list */
>> - u32 cpdl[8]; /* currently presented display list */
>> - u32 cadl[8]; /* currently active display list */
>> - u32 nadl[8]; /* next active devices list */
>> - u32 aslp; /* ASL sleep time-out */
>> - u32 tidx; /* toggle table index */
>> - u32 chpd; /* current hotplug enable indicator */
>> - u32 clid; /* current lid state*/
>> - u32 cdck; /* current docking state */
>> - u32 sxsw; /* Sx state resume */
>> - u32 evts; /* ASL supported events */
>> - u32 cnot; /* current OS notification */
>> - u32 nrdy; /* driver status */
>> - u32 did2[7]; /* extended supported display devices ID list */
>> - u32 cpd2[7]; /* extended attached display devices list */
>> - u8 rsvd2[4];
>> -} __packed;
>> -
>> -/* OpRegion mailbox #2: SWSCI */
>> -struct opregion_swsci {
>> - u32 scic; /* SWSCI command|status|data */
>> - u32 parm; /* command parameters */
>> - u32 dslp; /* driver sleep time-out */
>> - u8 rsvd[244];
>> -} __packed;
>> -
>> -/* OpRegion mailbox #3: ASLE */
>> -struct opregion_asle {
>> - u32 ardy; /* driver readiness */
>> - u32 aslc; /* ASLE interrupt command */
>> - u32 tche; /* technology enabled indicator */
>> - u32 alsi; /* current ALS illuminance reading */
>> - u32 bclp; /* backlight brightness to set */
>> - u32 pfit; /* panel fitting state */
>> - u32 cblv; /* current brightness level */
>> - u16 bclm[20]; /* backlight level duty cycle mapping table */
>> - u32 cpfm; /* current panel fitting mode */
>> - u32 epfm; /* enabled panel fitting modes */
>> - u8 plut[74]; /* panel LUT and identifier */
>> - u32 pfmb; /* PWM freq and min brightness */
>> - u32 cddv; /* color correction default values */
>> - u32 pcft; /* power conservation features */
>> - u32 srot; /* supported rotation angles */
>> - u32 iuer; /* IUER events */
>> - u64 fdss;
>> - u32 fdsp;
>> - u32 stat;
>> - u64 rvda; /* Physical address of raw vbt data */
>> - u32 rvds; /* Size of raw vbt data */
>> - u8 rsvd[58];
>> -} __packed;
>> -
>> -/* Driver readiness indicator */
>> -#define ASLE_ARDY_READY (1 << 0)
>> -#define ASLE_ARDY_NOT_READY (0 << 0)
>> -
>> -/* ASLE Interrupt Command (ASLC) bits */
>> -#define ASLC_SET_ALS_ILLUM (1 << 0)
>> -#define ASLC_SET_BACKLIGHT (1 << 1)
>> -#define ASLC_SET_PFIT (1 << 2)
>> -#define ASLC_SET_PWM_FREQ (1 << 3)
>> -#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
>> -#define ASLC_BUTTON_ARRAY (1 << 5)
>> -#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
>> -#define ASLC_DOCKING_INDICATOR (1 << 7)
>> -#define ASLC_ISCT_STATE_CHANGE (1 << 8)
>> -#define ASLC_REQ_MSK 0x1ff
>> -/* response bits */
>> -#define ASLC_ALS_ILLUM_FAILED (1 << 10)
>> -#define ASLC_BACKLIGHT_FAILED (1 << 12)
>> -#define ASLC_PFIT_FAILED (1 << 14)
>> -#define ASLC_PWM_FREQ_FAILED (1 << 16)
>> -#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
>> -#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
>> -#define ASLC_CONVERTIBLE_FAILED (1 << 22)
>> -#define ASLC_DOCKING_FAILED (1 << 24)
>> -#define ASLC_ISCT_STATE_FAILED (1 << 26)
>> -
>> -/* Technology enabled indicator */
>> -#define ASLE_TCHE_ALS_EN (1 << 0)
>> -#define ASLE_TCHE_BLC_EN (1 << 1)
>> -#define ASLE_TCHE_PFIT_EN (1 << 2)
>> -#define ASLE_TCHE_PFMB_EN (1 << 3)
>> -
>> -/* ASLE backlight brightness to set */
>> -#define ASLE_BCLP_VALID (1<<31)
>> -#define ASLE_BCLP_MSK (~(1<<31))
>> -
>> -/* ASLE panel fitting request */
>> -#define ASLE_PFIT_VALID (1<<31)
>> -#define ASLE_PFIT_CENTER (1<<0)
>> -#define ASLE_PFIT_STRETCH_TEXT (1<<1) -#define
>ASLE_PFIT_STRETCH_GFX
>> (1<<2)
>> -
>> -/* PWM frequency and minimum brightness */ -#define
>> ASLE_PFMB_BRIGHTNESS_MASK (0xff) -#define
>ASLE_PFMB_BRIGHTNESS_VALID
>> (1<<8) -#define ASLE_PFMB_PWM_MASK (0x7ffffe00) -#define
>> ASLE_PFMB_PWM_VALID (1<<31)
>> -
>> -#define ASLE_CBLV_VALID (1<<31)
>> -
>> -/* IUER */
>> -#define ASLE_IUER_DOCKING (1 << 7)
>> -#define ASLE_IUER_CONVERTIBLE (1 << 6)
>> -#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
>> -#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
>> -#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
>> -#define ASLE_IUER_WINDOWS_BTN (1 << 1)
>> -#define ASLE_IUER_POWER_BTN (1 << 0)
>> -
>> -/* Software System Control Interrupt (SWSCI) */
>> -#define SWSCI_SCIC_INDICATOR (1 << 0)
>> -#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
>> -#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
>> -#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
>> -#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
>> -#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
>> -#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
>> -#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
>> -#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
>> -#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
>> -
>> -#define SWSCI_FUNCTION_CODE(main, sub) \
>> - ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
>> - (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
>> -
>> -/* SWSCI: Get BIOS Data (GBDA) */
>> -#define SWSCI_GBDA 4
>> -#define SWSCI_GBDA_SUPPORTED_CALLS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
>> -#define SWSCI_GBDA_REQUESTED_CALLBACKS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
>> -#define SWSCI_GBDA_BOOT_DISPLAY_PREF
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
>> -#define SWSCI_GBDA_PANEL_DETAILS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
>> -#define SWSCI_GBDA_TV_STANDARD
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
>> -#define SWSCI_GBDA_INTERNAL_GRAPHICS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
>> -#define SWSCI_GBDA_SPREAD_SPECTRUM
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
>> -
>> -/* SWSCI: System BIOS Callbacks (SBCB) */
>> -#define SWSCI_SBCB 6
>> -#define SWSCI_SBCB_SUPPORTED_CALLBACKS
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
>> -#define SWSCI_SBCB_INIT_COMPLETION
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
>> -#define SWSCI_SBCB_PRE_HIRES_SET_MODE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
>> -#define SWSCI_SBCB_POST_HIRES_SET_MODE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
>> -#define SWSCI_SBCB_DISPLAY_SWITCH
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
>> -#define SWSCI_SBCB_SET_TV_FORMAT
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
>> -#define SWSCI_SBCB_ADAPTER_POWER_STATE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
>> -#define SWSCI_SBCB_DISPLAY_POWER_STATE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
>> -#define SWSCI_SBCB_SET_BOOT_DISPLAY
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
>> -#define SWSCI_SBCB_SET_PANEL_DETAILS
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
>> -#define SWSCI_SBCB_SET_INTERNAL_GFX
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
>> -#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
>> -#define SWSCI_SBCB_SUSPEND_RESUME
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
>> -#define SWSCI_SBCB_SET_SPREAD_SPECTRUM
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
>> -#define SWSCI_SBCB_POST_VBE_PM
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
>> -#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
>> -
>> -#define ACPI_OTHER_OUTPUT (0<<8)
>> -#define ACPI_VGA_OUTPUT (1<<8)
>> -#define ACPI_TV_OUTPUT (2<<8)
>> -#define ACPI_DIGITAL_OUTPUT (3<<8)
>> -#define ACPI_LVDS_OUTPUT (4<<8)
>> -
>> -#define MAX_DSLP 1500
>> +#include "intel_opregion.h"
>
>As said, I don't see the need to move these defines to a separate header. This
>is definitely stuff that we want to keep hidden in one place, and nobody
>outside of intel_opregion.c should use these.
>
[Deepak M] Need some of these definitions in the debugfs.c file, because of this
had created a new file for macros.
>>
>> #ifdef CONFIG_ACPI
>> static int swsci(struct drm_device *dev, u32 function, u32 parm, u32
>> *parm_out) @@ -892,13 +689,55 @@ static void swsci_setup(struct
>> drm_device *dev) static inline void swsci_setup(struct drm_device
>> *dev) {} #endif /* CONFIG_ACPI */
>>
>> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
>> + size_t size,
>> + const char *source)
>> +{
>> + /*
>> + * This is the one place where we explicitly discard the address space
>> + * (__iomem) of the BIOS/VBT. (And this will cause a sparse
>complaint.)
>> + */
>> + const struct vbt_header *vbt = (const struct vbt_header *)_vbt;
>> + const struct bdb_header *bdb;
>> + size_t offset;
>> +
>> + if (sizeof(struct vbt_header) > size) {
>> + DRM_DEBUG_DRIVER("VBT header incomplete\n");
>> + return NULL;
>> + }
>> +
>> + if (memcmp(vbt->signature, "$VBT", 4)) {
>> + DRM_DEBUG_DRIVER("VBT invalid signature\n");
>> + return NULL;
>> + }
>> +
>> + offset = vbt->bdb_offset;
>> + if (offset + sizeof(struct bdb_header) > size) {
>> + DRM_DEBUG_DRIVER("BDB header incomplete\n");
>> + return NULL;
>> + }
>> +
>> + bdb = (const void *)_vbt + offset;
>> + if (offset + bdb->bdb_size > size) {
>> + DRM_DEBUG_DRIVER("BDB incomplete\n");
>> + return NULL;
>> + }
>> +
>> + DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
>> + source, vbt->signature);
>> + return bdb;
>> +}
>> +
>> int intel_opregion_setup(struct drm_device *dev) {
>> struct drm_i915_private *dev_priv = dev->dev_private;
>> struct intel_opregion *opregion = &dev_priv->opregion;
>> void __iomem *base;
>> + void __iomem *vbt_base;
>> u32 asls, mboxes;
>> char buf[sizeof(OPREGION_SIGNATURE)];
>> + const struct bdb_header *bdb = NULL;
>> + size_t size;
>> int err = 0;
>>
>> BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100); @@ -
>917,7
>> +756,7 @@ int intel_opregion_setup(struct drm_device *dev)
>> INIT_WORK(&opregion->asle_work, asle_work); #endif
>>
>> - base = acpi_os_ioremap(asls, OPREGION_SIZE);
>> + base = acpi_os_ioremap(asls, OPREGION_VBT_OFFSET);
>
>Now you leave out mailbox #5. I don't think there's any reason *not* to
>ioremap all of opregion here.
>
>> if (!base)
>> return -ENOMEM;
>>
>> @@ -929,7 +768,33 @@ int intel_opregion_setup(struct drm_device *dev)
>> goto err_out;
>> }
>> opregion->header = base;
>> - opregion->vbt = base + OPREGION_VBT_OFFSET;
>> + /* Assigning the alse to the mailbox 3 of the opregion */
>> + opregion->asle = base + OPREGION_ASLE_OFFSET;
>
>That's assigned towards the end of the function *if* the mbox is supported.
>
>> +
>> + /*
>> + * Non-zero value in rvda field is an indication to driver that a
>> + * valid Raw VBT is stored in that address and driver should not refer
>> + * to mailbox4 for getting VBT.
>> + */
>> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda) {
>> + size = opregion->asle->rvds;
>> + vbt_base = acpi_os_ioremap(opregion->asle->rvda,
>> + size);
>> + } else {
>> + size = OPREGION_SIZE - OPREGION_VBT_OFFSET;
>> + vbt_base = acpi_os_ioremap(asls +
>OPREGION_VBT_OFFSET,
>> + size);
>> + }
>> +
>> + bdb = validate_vbt(vbt_base, size, "OpRegion");
>> +
>> + if (bdb == NULL) {
>> + err = -EINVAL;
>> + goto err_vbt;
>> + }
>> +
>> + dev_priv->bdb_start = bdb;
>
>Again, I don't see why you should store this here. Nor I see the need to
>actually validate vbt here. You can just as well do it in intel_bios like before, as
>long as you assign opregion->vbt here appropriately.
>
>You'll also need to iounmap vbt_base in intel_opregion_fini. That may need
>some additional checks if you unconditionally ioremap all of opregion and
>conditionally ioremap rvda, and point opregion->vbt to it.
>
[Deepak M] Okay will handle this.
>> + opregion->vbt = vbt_base;
>>
>> opregion->lid_state = base + ACPI_CLID;
>>
>> @@ -953,6 +818,8 @@ int intel_opregion_setup(struct drm_device *dev)
>>
>> return 0;
>>
>> +err_vbt:
>> + iounmap(vbt_base);
>> err_out:
>> iounmap(base);
>> return err;
>> diff --git a/drivers/gpu/drm/i915/intel_opregion.h
>> b/drivers/gpu/drm/i915/intel_opregion.h
>> new file mode 100644
>> index 0000000..bcb45ec
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/intel_opregion.h
>> @@ -0,0 +1,230 @@
>> +/*
>> + * Copyright 2008 Intel Corporation <hong.liu@intel.com>
>> + * Copyright 2008 Red Hat <mjg@redhat.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 INTEL 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.
>> + *
>> + */
>> +
>> +#define PCI_ASLE 0xe4
>> +#define PCI_ASLS 0xfc
>> +#define PCI_SWSCI 0xe8
>> +#define PCI_SWSCI_SCISEL (1 << 15)
>> +#define PCI_SWSCI_GSSCIE (1 << 0)
>> +
>> +#define OPREGION_HEADER_OFFSET 0
>> +#define OPREGION_ACPI_OFFSET 0x100
>> +#define ACPI_CLID 0x01ac /* current lid state indicator */
>> +#define ACPI_CDCK 0x01b0 /* current docking state indicator */
>> +#define OPREGION_SWSCI_OFFSET 0x200
>> +#define OPREGION_ASLE_OFFSET 0x300
>> +#define OPREGION_VBT_OFFSET 0x400
>> +
>> +#define OPREGION_SIGNATURE "IntelGraphicsMem"
>> +#define MBOX_ACPI (1<<0)
>> +#define MBOX_SWSCI (1<<1)
>> +#define MBOX_ASLE (1<<2)
>> +#define MBOX_ASLE_EXT (1<<4)
>> +
>> +struct opregion_header {
>> + u8 signature[16];
>> + u32 size;
>> + u32 opregion_ver;
>> + u8 bios_ver[32];
>> + u8 vbios_ver[16];
>> + u8 driver_ver[16];
>> + u32 mboxes;
>> + u32 driver_model;
>> + u32 pcon;
>> + u8 dver[32];
>> + u8 rsvd[124];
>> +} __packed;
>> +
>> +/* OpRegion mailbox #1: public ACPI methods */ struct opregion_acpi {
>> + u32 drdy; /* driver readiness */
>> + u32 csts; /* notification status */
>> + u32 cevt; /* current event */
>> + u8 rsvd1[20];
>> + u32 didl[8]; /* supported display devices ID list */
>> + u32 cpdl[8]; /* currently presented display list */
>> + u32 cadl[8]; /* currently active display list */
>> + u32 nadl[8]; /* next active devices list */
>> + u32 aslp; /* ASL sleep time-out */
>> + u32 tidx; /* toggle table index */
>> + u32 chpd; /* current hotplug enable indicator */
>> + u32 clid; /* current lid state*/
>> + u32 cdck; /* current docking state */
>> + u32 sxsw; /* Sx state resume */
>> + u32 evts; /* ASL supported events */
>> + u32 cnot; /* current OS notification */
>> + u32 nrdy; /* driver status */
>> + u32 did2[7]; /* extended supported display devices ID list */
>> + u32 cpd2[7]; /* extended attached display devices list */
>> + u8 rsvd2[4];
>> +} __packed;
>> +
>> +/* OpRegion mailbox #2: SWSCI */
>> +struct opregion_swsci {
>> + u32 scic; /* SWSCI command|status|data */
>> + u32 parm; /* command parameters */
>> + u32 dslp; /* driver sleep time-out */
>> + u8 rsvd[244];
>> +} __packed;
>> +
>> +/* OpRegion mailbox #3: ASLE */
>> +struct opregion_asle {
>> + u32 ardy; /* driver readiness */
>> + u32 aslc; /* ASLE interrupt command */
>> + u32 tche; /* technology enabled indicator */
>> + u32 alsi; /* current ALS illuminance reading */
>> + u32 bclp; /* backlight brightness to set */
>> + u32 pfit; /* panel fitting state */
>> + u32 cblv; /* current brightness level */
>> + u16 bclm[20]; /* backlight level duty cycle mapping table */
>> + u32 cpfm; /* current panel fitting mode */
>> + u32 epfm; /* enabled panel fitting modes */
>> + u8 plut[74]; /* panel LUT and identifier */
>> + u32 pfmb; /* PWM freq and min brightness */
>> + u32 cddv; /* color correction default values */
>> + u32 pcft; /* power conservation features */
>> + u32 srot; /* supported rotation angles */
>> + u32 iuer; /* IUER events */
>> + u64 fdss;
>> + u32 fdsp;
>> + u32 stat;
>> + u64 rvda; /* Physical address of raw vbt data */
>> + u32 rvds; /* Size of raw vbt data */
>> + u8 rsvd[58];
>> +} __packed;
>> +
>> +/* Driver readiness indicator */
>> +#define ASLE_ARDY_READY (1 << 0)
>> +#define ASLE_ARDY_NOT_READY (0 << 0)
>> +
>> +/* ASLE Interrupt Command (ASLC) bits */
>> +#define ASLC_SET_ALS_ILLUM (1 << 0)
>> +#define ASLC_SET_BACKLIGHT (1 << 1)
>> +#define ASLC_SET_PFIT (1 << 2)
>> +#define ASLC_SET_PWM_FREQ (1 << 3)
>> +#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
>> +#define ASLC_BUTTON_ARRAY (1 << 5)
>> +#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
>> +#define ASLC_DOCKING_INDICATOR (1 << 7)
>> +#define ASLC_ISCT_STATE_CHANGE (1 << 8)
>> +#define ASLC_REQ_MSK 0x1ff
>> +/* response bits */
>> +#define ASLC_ALS_ILLUM_FAILED (1 << 10)
>> +#define ASLC_BACKLIGHT_FAILED (1 << 12)
>> +#define ASLC_PFIT_FAILED (1 << 14)
>> +#define ASLC_PWM_FREQ_FAILED (1 << 16)
>> +#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
>> +#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
>> +#define ASLC_CONVERTIBLE_FAILED (1 << 22)
>> +#define ASLC_DOCKING_FAILED (1 << 24)
>> +#define ASLC_ISCT_STATE_FAILED (1 << 26)
>> +
>> +/* Technology enabled indicator */
>> +#define ASLE_TCHE_ALS_EN (1 << 0)
>> +#define ASLE_TCHE_BLC_EN (1 << 1)
>> +#define ASLE_TCHE_PFIT_EN (1 << 2)
>> +#define ASLE_TCHE_PFMB_EN (1 << 3)
>> +
>> +/* ASLE backlight brightness to set */
>> +#define ASLE_BCLP_VALID (1<<31)
>> +#define ASLE_BCLP_MSK (~(1<<31))
>> +
>> +/* ASLE panel fitting request */
>> +#define ASLE_PFIT_VALID (1<<31)
>> +#define ASLE_PFIT_CENTER (1<<0)
>> +#define ASLE_PFIT_STRETCH_TEXT (1<<1) #define
>ASLE_PFIT_STRETCH_GFX
>> +(1<<2)
>> +
>> +/* PWM frequency and minimum brightness */ #define
>> +ASLE_PFMB_BRIGHTNESS_MASK (0xff) #define
>ASLE_PFMB_BRIGHTNESS_VALID
>> +(1<<8) #define ASLE_PFMB_PWM_MASK (0x7ffffe00) #define
>> +ASLE_PFMB_PWM_VALID (1<<31)
>> +
>> +#define ASLE_CBLV_VALID (1<<31)
>> +
>> +/* IUER */
>> +#define ASLE_IUER_DOCKING (1 << 7)
>> +#define ASLE_IUER_CONVERTIBLE (1 << 6)
>> +#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
>> +#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
>> +#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
>> +#define ASLE_IUER_WINDOWS_BTN (1 << 1)
>> +#define ASLE_IUER_POWER_BTN (1 << 0)
>> +
>> +/* Software System Control Interrupt (SWSCI) */
>> +#define SWSCI_SCIC_INDICATOR (1 << 0)
>> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
>> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
>> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
>> +#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
>> +#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
>> +#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
>> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
>> +#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
>> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
>> +
>> +#define SWSCI_FUNCTION_CODE(main, sub) \
>> + ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
>> + (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
>> +
>> +/* SWSCI: Get BIOS Data (GBDA) */
>> +#define SWSCI_GBDA 4
>> +#define SWSCI_GBDA_SUPPORTED_CALLS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
>> +#define SWSCI_GBDA_REQUESTED_CALLBACKS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
>> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
>> +#define SWSCI_GBDA_PANEL_DETAILS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
>> +#define SWSCI_GBDA_TV_STANDARD
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
>> +#define SWSCI_GBDA_INTERNAL_GRAPHICS
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
>> +#define SWSCI_GBDA_SPREAD_SPECTRUM
> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
>> +
>> +/* SWSCI: System BIOS Callbacks (SBCB) */
>> +#define SWSCI_SBCB 6
>> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
>> +#define SWSCI_SBCB_INIT_COMPLETION
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
>> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
>> +#define SWSCI_SBCB_POST_HIRES_SET_MODE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
>> +#define SWSCI_SBCB_DISPLAY_SWITCH
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
>> +#define SWSCI_SBCB_SET_TV_FORMAT
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
>> +#define SWSCI_SBCB_ADAPTER_POWER_STATE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
>> +#define SWSCI_SBCB_DISPLAY_POWER_STATE
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
>> +#define SWSCI_SBCB_SET_BOOT_DISPLAY
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
>> +#define SWSCI_SBCB_SET_PANEL_DETAILS
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
>> +#define SWSCI_SBCB_SET_INTERNAL_GFX
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
>> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
>> +#define SWSCI_SBCB_SUSPEND_RESUME
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
>> +#define SWSCI_SBCB_SET_SPREAD_SPECTRUM
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
>> +#define SWSCI_SBCB_POST_VBE_PM
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
>> +#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
>> +
>> +#define ACPI_OTHER_OUTPUT (0<<8)
>> +#define ACPI_VGA_OUTPUT (1<<8)
>> +#define ACPI_TV_OUTPUT (2<<8)
>> +#define ACPI_DIGITAL_OUTPUT (3<<8)
>> +#define ACPI_LVDS_OUTPUT (4<<8)
>> +
>> +#define MAX_DSLP 1500
>
>The bottom line here is that I think you could get all of this done with
>*much* smaller changes. If we get a regression report pointing at this patch,
>we'll have a lot of debugging to do to figure out what failed.
>
[Deepak M] Okay will try to break this patch into smaller one`s.
>BR,
>Jani.
>
>
>
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>--
>Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB
2015-09-22 6:37 ` Deepak, M
@ 2015-09-22 7:24 ` Jani Nikula
0 siblings, 0 replies; 25+ messages in thread
From: Jani Nikula @ 2015-09-22 7:24 UTC (permalink / raw)
To: Deepak, M, intel-gfx@lists.freedesktop.org
On Tue, 22 Sep 2015, "Deepak, M" <m.deepak@intel.com> wrote:
>>-----Original Message-----
>>From: Jani Nikula [mailto:jani.nikula@linux.intel.com]
>>Sent: Thursday, September 17, 2015 5:41 PM
>>To: Deepak, M; intel-gfx@lists.freedesktop.org
>>Cc: Deepak, M
>>Subject: Re: [Intel-gfx] [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing
>>VBT if size of VBT exceeds 6KB
>>
>>On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
>>> Currently the iomap for VBT works only if the size of the VBT is less
>>> than 6KB, but if the size of the VBT exceeds 6KB than the physical
>>> address and the size of the VBT to be iomapped is specified in the
>>> mailbox3 and is iomapped accordingly.
>>>
>>> v2: - Moving the validate_vbt to opregion file (Jani)
>>> - Fix the i915_opregion() in debugfs (Jani)
>>>
>>> Signed-off-by: Deepak M <m.deepak@intel.com>
>>> ---
>>> drivers/gpu/drm/i915/i915_debugfs.c | 24 ++-
>>> drivers/gpu/drm/i915/i915_drv.h | 4 +
>>> drivers/gpu/drm/i915/intel_bios.c | 49 +-----
>>> drivers/gpu/drm/i915/intel_opregion.c | 279
>>> +++++++++------------------------
>>> drivers/gpu/drm/i915/intel_opregion.h | 230
>>> +++++++++++++++++++++++++++
>>> 5 files changed, 329 insertions(+), 257 deletions(-) create mode
>>> 100644 drivers/gpu/drm/i915/intel_opregion.h
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
>>> b/drivers/gpu/drm/i915/i915_debugfs.c
>>> index 41629fa..5534aa2 100644
>>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>>> @@ -26,6 +26,8 @@
>>> *
>>> */
>>>
>>> +#include <linux/acpi.h>
>>> +#include <acpi/video.h>
>>> #include <linux/seq_file.h>
>>> #include <linux/circ_buf.h>
>>> #include <linux/ctype.h>
>>> @@ -39,6 +41,7 @@
>>> #include "intel_ringbuffer.h"
>>> #include <drm/i915_drm.h>
>>> #include "i915_drv.h"
>>> +#include "intel_opregion.h"
>>>
>>> enum {
>>> ACTIVE_LIST,
>>> @@ -1832,7 +1835,7 @@ static int i915_opregion(struct seq_file *m, void
>>*unused)
>>> struct drm_device *dev = node->minor->dev;
>>> struct drm_i915_private *dev_priv = dev->dev_private;
>>> struct intel_opregion *opregion = &dev_priv->opregion;
>>> - void *data = kmalloc(OPREGION_SIZE, GFP_KERNEL);
>>> + void *data = kmalloc(OPREGION_VBT_OFFSET, GFP_KERNEL);
>>> int ret;
>>>
>>> if (data == NULL)
>>> @@ -1843,12 +1846,25 @@ static int i915_opregion(struct seq_file *m, void
>>*unused)
>>> goto out;
>>>
>>> if (opregion->header) {
>>> - memcpy_fromio(data, opregion->header, OPREGION_SIZE);
>>> - seq_write(m, data, OPREGION_SIZE);
>>> + memcpy_fromio(data, opregion->header,
>>OPREGION_VBT_OFFSET);
>>> + seq_write(m, data, OPREGION_VBT_OFFSET);
>>> + kfree(data);
>>> + if (opregion->asle->rvda) {
>>> + data = kmalloc(opregion->asle->rvds, GFP_KERNEL);
>>> + memcpy_fromio(data,
>>> + (const void __iomem *) opregion->asle->rvda,
>>> + opregion->asle->rvds);
>>> + seq_write(m, data, opregion->asle->rvds);
>>> + } else {
>>> + data = kmalloc(OPREGION_SIZE -
>>OPREGION_VBT_OFFSET,
>>> + GFP_KERNEL);
>>> + memcpy_fromio(data, opregion->vbt,
>>> + OPREGION_SIZE -
>>OPREGION_VBT_OFFSET);
>>> + seq_write(m, data, OPREGION_SIZE -
>>OPREGION_VBT_OFFSET);
>>> + }
>>
>>If rvda != 0, this debugfs file no longer represents the opregion contents.
>>Mailboxes #4 and #5 are dropped from the output. BTW, what is mailbox #4
>>expected to contain when rvda != 0? (I still don't have access to the latest
>>opregion spec version, so can't check what it actually says.)
>>
>>I am beginning to think we should leave "i915_opregion" debugfs file intact,
>>and add a new "i915_vbt" file that contains either mailbox #4 or the data in
>>rvda. This might be a cleaner approach.
>>
>>See my comments below, and you'll see how this would be feasible.
>>
> [Deepak M] I was thinking of splitting this function into 5 for dumping each mailbox. Which
> I felt will be cleaner.
Please have i915_opregion and i915_vbt as I explained.
>>> }
>>>
>>> mutex_unlock(&dev->struct_mutex);
>>> -
>>> out:
>>> kfree(data);
>>> return 0;
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>>> b/drivers/gpu/drm/i915/i915_drv.h index 1287007..507d57a 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -1780,6 +1780,7 @@ struct drm_i915_private {
>>> struct i915_hotplug hotplug;
>>> struct i915_fbc fbc;
>>> struct i915_drrs drrs;
>>> + const struct bdb_header *bdb_start;
>>
>>What is wrong with using dev_priv->opregion.vbt for this?
>>
>>> struct intel_opregion opregion;
>>> struct intel_vbt_data vbt;
>>>
>>> @@ -3306,6 +3307,9 @@ intel_opregion_notify_adapter(struct drm_device
>>> *dev, pci_power_t state) } #endif
>>>
>>> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
>>> + size_t size, const char *source);
>>> +
>>> /* intel_acpi.c */
>>> #ifdef CONFIG_ACPI
>>> extern void intel_register_dsm_handler(void); diff --git
>>> a/drivers/gpu/drm/i915/intel_bios.c
>>> b/drivers/gpu/drm/i915/intel_bios.c
>>> index 0bf0942..1932a86 100644
>>> --- a/drivers/gpu/drm/i915/intel_bios.c
>>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>>> @@ -1227,49 +1227,6 @@ static const struct dmi_system_id
>>intel_no_opregion_vbt[] = {
>>> { }
>>> };
>>>
>>> -static const struct bdb_header *validate_vbt(const void __iomem *_base,
>>> - size_t size,
>>> - const void __iomem *_vbt,
>>> - const char *source)
>>> -{
>>> - /*
>>> - * This is the one place where we explicitly discard the address space
>>> - * (__iomem) of the BIOS/VBT. (And this will cause a sparse
>>complaint.)
>>> - * From now on everything is based on 'base', and treated as regular
>>> - * memory.
>>> - */
>>> - const void *base = (const void *) _base;
>>> - size_t offset = _vbt - _base;
>>> - const struct vbt_header *vbt = base + offset;
>>> - const struct bdb_header *bdb;
>>> -
>>> - if (offset + sizeof(struct vbt_header) > size) {
>>> - DRM_DEBUG_DRIVER("VBT header incomplete\n");
>>> - return NULL;
>>> - }
>>> -
>>> - if (memcmp(vbt->signature, "$VBT", 4)) {
>>> - DRM_DEBUG_DRIVER("VBT invalid signature\n");
>>> - return NULL;
>>> - }
>>> -
>>> - offset += vbt->bdb_offset;
>>> - if (offset + sizeof(struct bdb_header) > size) {
>>> - DRM_DEBUG_DRIVER("BDB header incomplete\n");
>>> - return NULL;
>>> - }
>>> -
>>> - bdb = base + offset;
>>> - if (offset + bdb->bdb_size > size) {
>>> - DRM_DEBUG_DRIVER("BDB incomplete\n");
>>> - return NULL;
>>> - }
>>> -
>>> - DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
>>> - source, vbt->signature);
>>> - return bdb;
>>> -}
>>> -
>>
>>Moving of this function should be a separate prep patch.
>>
>>> static const struct bdb_header *find_vbt(void __iomem *bios, size_t
>>> size) {
>>> const struct bdb_header *bdb = NULL; @@ -1278,7 +1235,7 @@ static
>>> const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
>>> /* Scour memory looking for the VBT signature. */
>>> for (i = 0; i + 4 < size; i++) {
>>> if (ioread32(bios + i) == *((const u32 *) "$VBT")) {
>>> - bdb = validate_vbt(bios, size, bios + i, "PCI ROM");
>>> + bdb = validate_vbt(bios + i, size - i, "PCI ROM");
>>> break;
>>> }
>>> }
>>> @@ -1308,10 +1265,8 @@ intel_parse_bios(struct drm_device *dev)
>>>
>>> init_vbt_defaults(dev_priv);
>>>
>>> - /* XXX Should this validation be moved to intel_opregion.c? */
>>> if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv-
>>>opregion.vbt)
>>> - bdb = validate_vbt(dev_priv->opregion.header,
>>OPREGION_SIZE,
>>> - dev_priv->opregion.vbt, "OpRegion");
>>> + bdb = dev_priv->bdb_start;
>>
>>This should be dev_priv->opregion.vbt.
> [Deepak M] validate_vbt function always returns the bdb header and our parsing starts from the bdb_header and not form the dev_priv->opregion.vbt where the VBT header starts. So I have added bdb_start in the dev_priv structure.
>>
Please don't add new fields when you can reuse existing ones.
>>>
>>> if (bdb == NULL) {
>>> size_t size;
>>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c
>>> b/drivers/gpu/drm/i915/intel_opregion.c
>>> index f46231f..3a43db9 100644
>>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>>> @@ -32,210 +32,7 @@
>>> #include <drm/i915_drm.h>
>>> #include "i915_drv.h"
>>> #include "intel_drv.h"
>>> -
>>> -#define PCI_ASLE 0xe4
>>> -#define PCI_ASLS 0xfc
>>> -#define PCI_SWSCI 0xe8
>>> -#define PCI_SWSCI_SCISEL (1 << 15)
>>> -#define PCI_SWSCI_GSSCIE (1 << 0)
>>> -
>>> -#define OPREGION_HEADER_OFFSET 0
>>> -#define OPREGION_ACPI_OFFSET 0x100
>>> -#define ACPI_CLID 0x01ac /* current lid state indicator */
>>> -#define ACPI_CDCK 0x01b0 /* current docking state indicator */
>>> -#define OPREGION_SWSCI_OFFSET 0x200
>>> -#define OPREGION_ASLE_OFFSET 0x300
>>> -#define OPREGION_VBT_OFFSET 0x400
>>> -
>>> -#define OPREGION_SIGNATURE "IntelGraphicsMem"
>>> -#define MBOX_ACPI (1<<0)
>>> -#define MBOX_SWSCI (1<<1)
>>> -#define MBOX_ASLE (1<<2)
>>> -#define MBOX_ASLE_EXT (1<<4)
>>> -
>>> -struct opregion_header {
>>> - u8 signature[16];
>>> - u32 size;
>>> - u32 opregion_ver;
>>> - u8 bios_ver[32];
>>> - u8 vbios_ver[16];
>>> - u8 driver_ver[16];
>>> - u32 mboxes;
>>> - u32 driver_model;
>>> - u32 pcon;
>>> - u8 dver[32];
>>> - u8 rsvd[124];
>>> -} __packed;
>>> -
>>> -/* OpRegion mailbox #1: public ACPI methods */ -struct opregion_acpi
>>> {
>>> - u32 drdy; /* driver readiness */
>>> - u32 csts; /* notification status */
>>> - u32 cevt; /* current event */
>>> - u8 rsvd1[20];
>>> - u32 didl[8]; /* supported display devices ID list */
>>> - u32 cpdl[8]; /* currently presented display list */
>>> - u32 cadl[8]; /* currently active display list */
>>> - u32 nadl[8]; /* next active devices list */
>>> - u32 aslp; /* ASL sleep time-out */
>>> - u32 tidx; /* toggle table index */
>>> - u32 chpd; /* current hotplug enable indicator */
>>> - u32 clid; /* current lid state*/
>>> - u32 cdck; /* current docking state */
>>> - u32 sxsw; /* Sx state resume */
>>> - u32 evts; /* ASL supported events */
>>> - u32 cnot; /* current OS notification */
>>> - u32 nrdy; /* driver status */
>>> - u32 did2[7]; /* extended supported display devices ID list */
>>> - u32 cpd2[7]; /* extended attached display devices list */
>>> - u8 rsvd2[4];
>>> -} __packed;
>>> -
>>> -/* OpRegion mailbox #2: SWSCI */
>>> -struct opregion_swsci {
>>> - u32 scic; /* SWSCI command|status|data */
>>> - u32 parm; /* command parameters */
>>> - u32 dslp; /* driver sleep time-out */
>>> - u8 rsvd[244];
>>> -} __packed;
>>> -
>>> -/* OpRegion mailbox #3: ASLE */
>>> -struct opregion_asle {
>>> - u32 ardy; /* driver readiness */
>>> - u32 aslc; /* ASLE interrupt command */
>>> - u32 tche; /* technology enabled indicator */
>>> - u32 alsi; /* current ALS illuminance reading */
>>> - u32 bclp; /* backlight brightness to set */
>>> - u32 pfit; /* panel fitting state */
>>> - u32 cblv; /* current brightness level */
>>> - u16 bclm[20]; /* backlight level duty cycle mapping table */
>>> - u32 cpfm; /* current panel fitting mode */
>>> - u32 epfm; /* enabled panel fitting modes */
>>> - u8 plut[74]; /* panel LUT and identifier */
>>> - u32 pfmb; /* PWM freq and min brightness */
>>> - u32 cddv; /* color correction default values */
>>> - u32 pcft; /* power conservation features */
>>> - u32 srot; /* supported rotation angles */
>>> - u32 iuer; /* IUER events */
>>> - u64 fdss;
>>> - u32 fdsp;
>>> - u32 stat;
>>> - u64 rvda; /* Physical address of raw vbt data */
>>> - u32 rvds; /* Size of raw vbt data */
>>> - u8 rsvd[58];
>>> -} __packed;
>>> -
>>> -/* Driver readiness indicator */
>>> -#define ASLE_ARDY_READY (1 << 0)
>>> -#define ASLE_ARDY_NOT_READY (0 << 0)
>>> -
>>> -/* ASLE Interrupt Command (ASLC) bits */
>>> -#define ASLC_SET_ALS_ILLUM (1 << 0)
>>> -#define ASLC_SET_BACKLIGHT (1 << 1)
>>> -#define ASLC_SET_PFIT (1 << 2)
>>> -#define ASLC_SET_PWM_FREQ (1 << 3)
>>> -#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
>>> -#define ASLC_BUTTON_ARRAY (1 << 5)
>>> -#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
>>> -#define ASLC_DOCKING_INDICATOR (1 << 7)
>>> -#define ASLC_ISCT_STATE_CHANGE (1 << 8)
>>> -#define ASLC_REQ_MSK 0x1ff
>>> -/* response bits */
>>> -#define ASLC_ALS_ILLUM_FAILED (1 << 10)
>>> -#define ASLC_BACKLIGHT_FAILED (1 << 12)
>>> -#define ASLC_PFIT_FAILED (1 << 14)
>>> -#define ASLC_PWM_FREQ_FAILED (1 << 16)
>>> -#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
>>> -#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
>>> -#define ASLC_CONVERTIBLE_FAILED (1 << 22)
>>> -#define ASLC_DOCKING_FAILED (1 << 24)
>>> -#define ASLC_ISCT_STATE_FAILED (1 << 26)
>>> -
>>> -/* Technology enabled indicator */
>>> -#define ASLE_TCHE_ALS_EN (1 << 0)
>>> -#define ASLE_TCHE_BLC_EN (1 << 1)
>>> -#define ASLE_TCHE_PFIT_EN (1 << 2)
>>> -#define ASLE_TCHE_PFMB_EN (1 << 3)
>>> -
>>> -/* ASLE backlight brightness to set */
>>> -#define ASLE_BCLP_VALID (1<<31)
>>> -#define ASLE_BCLP_MSK (~(1<<31))
>>> -
>>> -/* ASLE panel fitting request */
>>> -#define ASLE_PFIT_VALID (1<<31)
>>> -#define ASLE_PFIT_CENTER (1<<0)
>>> -#define ASLE_PFIT_STRETCH_TEXT (1<<1) -#define
>>ASLE_PFIT_STRETCH_GFX
>>> (1<<2)
>>> -
>>> -/* PWM frequency and minimum brightness */ -#define
>>> ASLE_PFMB_BRIGHTNESS_MASK (0xff) -#define
>>ASLE_PFMB_BRIGHTNESS_VALID
>>> (1<<8) -#define ASLE_PFMB_PWM_MASK (0x7ffffe00) -#define
>>> ASLE_PFMB_PWM_VALID (1<<31)
>>> -
>>> -#define ASLE_CBLV_VALID (1<<31)
>>> -
>>> -/* IUER */
>>> -#define ASLE_IUER_DOCKING (1 << 7)
>>> -#define ASLE_IUER_CONVERTIBLE (1 << 6)
>>> -#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
>>> -#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
>>> -#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
>>> -#define ASLE_IUER_WINDOWS_BTN (1 << 1)
>>> -#define ASLE_IUER_POWER_BTN (1 << 0)
>>> -
>>> -/* Software System Control Interrupt (SWSCI) */
>>> -#define SWSCI_SCIC_INDICATOR (1 << 0)
>>> -#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
>>> -#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
>>> -#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
>>> -#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
>>> -#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
>>> -#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
>>> -#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
>>> -#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
>>> -#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
>>> -
>>> -#define SWSCI_FUNCTION_CODE(main, sub) \
>>> - ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
>>> - (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
>>> -
>>> -/* SWSCI: Get BIOS Data (GBDA) */
>>> -#define SWSCI_GBDA 4
>>> -#define SWSCI_GBDA_SUPPORTED_CALLS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
>>> -#define SWSCI_GBDA_REQUESTED_CALLBACKS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
>>> -#define SWSCI_GBDA_BOOT_DISPLAY_PREF
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
>>> -#define SWSCI_GBDA_PANEL_DETAILS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
>>> -#define SWSCI_GBDA_TV_STANDARD
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
>>> -#define SWSCI_GBDA_INTERNAL_GRAPHICS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
>>> -#define SWSCI_GBDA_SPREAD_SPECTRUM
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
>>> -
>>> -/* SWSCI: System BIOS Callbacks (SBCB) */
>>> -#define SWSCI_SBCB 6
>>> -#define SWSCI_SBCB_SUPPORTED_CALLBACKS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
>>> -#define SWSCI_SBCB_INIT_COMPLETION
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
>>> -#define SWSCI_SBCB_PRE_HIRES_SET_MODE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
>>> -#define SWSCI_SBCB_POST_HIRES_SET_MODE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
>>> -#define SWSCI_SBCB_DISPLAY_SWITCH
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
>>> -#define SWSCI_SBCB_SET_TV_FORMAT
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
>>> -#define SWSCI_SBCB_ADAPTER_POWER_STATE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
>>> -#define SWSCI_SBCB_DISPLAY_POWER_STATE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
>>> -#define SWSCI_SBCB_SET_BOOT_DISPLAY
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
>>> -#define SWSCI_SBCB_SET_PANEL_DETAILS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
>>> -#define SWSCI_SBCB_SET_INTERNAL_GFX
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
>>> -#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
>>> -#define SWSCI_SBCB_SUSPEND_RESUME
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
>>> -#define SWSCI_SBCB_SET_SPREAD_SPECTRUM
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
>>> -#define SWSCI_SBCB_POST_VBE_PM
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
>>> -#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
>>> -
>>> -#define ACPI_OTHER_OUTPUT (0<<8)
>>> -#define ACPI_VGA_OUTPUT (1<<8)
>>> -#define ACPI_TV_OUTPUT (2<<8)
>>> -#define ACPI_DIGITAL_OUTPUT (3<<8)
>>> -#define ACPI_LVDS_OUTPUT (4<<8)
>>> -
>>> -#define MAX_DSLP 1500
>>> +#include "intel_opregion.h"
>>
>>As said, I don't see the need to move these defines to a separate header. This
>>is definitely stuff that we want to keep hidden in one place, and nobody
>>outside of intel_opregion.c should use these.
>>
> [Deepak M] Need some of these definitions in the debugfs.c file, because of this
> had created a new file for macros.
Please rework your debugfs handling to not need these. If needed, add an
interface to intel_opregion.c to do what you want.
>
>>>
>>> #ifdef CONFIG_ACPI
>>> static int swsci(struct drm_device *dev, u32 function, u32 parm, u32
>>> *parm_out) @@ -892,13 +689,55 @@ static void swsci_setup(struct
>>> drm_device *dev) static inline void swsci_setup(struct drm_device
>>> *dev) {} #endif /* CONFIG_ACPI */
>>>
>>> +const struct bdb_header *validate_vbt(const void __iomem *_vbt,
>>> + size_t size,
>>> + const char *source)
>>> +{
>>> + /*
>>> + * This is the one place where we explicitly discard the address space
>>> + * (__iomem) of the BIOS/VBT. (And this will cause a sparse
>>complaint.)
>>> + */
>>> + const struct vbt_header *vbt = (const struct vbt_header *)_vbt;
>>> + const struct bdb_header *bdb;
>>> + size_t offset;
>>> +
>>> + if (sizeof(struct vbt_header) > size) {
>>> + DRM_DEBUG_DRIVER("VBT header incomplete\n");
>>> + return NULL;
>>> + }
>>> +
>>> + if (memcmp(vbt->signature, "$VBT", 4)) {
>>> + DRM_DEBUG_DRIVER("VBT invalid signature\n");
>>> + return NULL;
>>> + }
>>> +
>>> + offset = vbt->bdb_offset;
>>> + if (offset + sizeof(struct bdb_header) > size) {
>>> + DRM_DEBUG_DRIVER("BDB header incomplete\n");
>>> + return NULL;
>>> + }
>>> +
>>> + bdb = (const void *)_vbt + offset;
>>> + if (offset + bdb->bdb_size > size) {
>>> + DRM_DEBUG_DRIVER("BDB incomplete\n");
>>> + return NULL;
>>> + }
>>> +
>>> + DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
>>> + source, vbt->signature);
>>> + return bdb;
>>> +}
>>> +
>>> int intel_opregion_setup(struct drm_device *dev) {
>>> struct drm_i915_private *dev_priv = dev->dev_private;
>>> struct intel_opregion *opregion = &dev_priv->opregion;
>>> void __iomem *base;
>>> + void __iomem *vbt_base;
>>> u32 asls, mboxes;
>>> char buf[sizeof(OPREGION_SIGNATURE)];
>>> + const struct bdb_header *bdb = NULL;
>>> + size_t size;
>>> int err = 0;
>>>
>>> BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100); @@ -
>>917,7
>>> +756,7 @@ int intel_opregion_setup(struct drm_device *dev)
>>> INIT_WORK(&opregion->asle_work, asle_work); #endif
>>>
>>> - base = acpi_os_ioremap(asls, OPREGION_SIZE);
>>> + base = acpi_os_ioremap(asls, OPREGION_VBT_OFFSET);
>>
>>Now you leave out mailbox #5. I don't think there's any reason *not* to
>>ioremap all of opregion here.
>>
>>> if (!base)
>>> return -ENOMEM;
>>>
>>> @@ -929,7 +768,33 @@ int intel_opregion_setup(struct drm_device *dev)
>>> goto err_out;
>>> }
>>> opregion->header = base;
>>> - opregion->vbt = base + OPREGION_VBT_OFFSET;
>>> + /* Assigning the alse to the mailbox 3 of the opregion */
>>> + opregion->asle = base + OPREGION_ASLE_OFFSET;
>>
>>That's assigned towards the end of the function *if* the mbox is supported.
>>
>>> +
>>> + /*
>>> + * Non-zero value in rvda field is an indication to driver that a
>>> + * valid Raw VBT is stored in that address and driver should not refer
>>> + * to mailbox4 for getting VBT.
>>> + */
>>> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda) {
>>> + size = opregion->asle->rvds;
>>> + vbt_base = acpi_os_ioremap(opregion->asle->rvda,
>>> + size);
>>> + } else {
>>> + size = OPREGION_SIZE - OPREGION_VBT_OFFSET;
>>> + vbt_base = acpi_os_ioremap(asls +
>>OPREGION_VBT_OFFSET,
>>> + size);
>>> + }
>>> +
>>> + bdb = validate_vbt(vbt_base, size, "OpRegion");
>>> +
>>> + if (bdb == NULL) {
>>> + err = -EINVAL;
>>> + goto err_vbt;
>>> + }
>>> +
>>> + dev_priv->bdb_start = bdb;
>>
>>Again, I don't see why you should store this here. Nor I see the need to
>>actually validate vbt here. You can just as well do it in intel_bios like before, as
>>long as you assign opregion->vbt here appropriately.
>>
>>You'll also need to iounmap vbt_base in intel_opregion_fini. That may need
>>some additional checks if you unconditionally ioremap all of opregion and
>>conditionally ioremap rvda, and point opregion->vbt to it.
>>
> [Deepak M] Okay will handle this.
>>> + opregion->vbt = vbt_base;
>>>
>>> opregion->lid_state = base + ACPI_CLID;
>>>
>>> @@ -953,6 +818,8 @@ int intel_opregion_setup(struct drm_device *dev)
>>>
>>> return 0;
>>>
>>> +err_vbt:
>>> + iounmap(vbt_base);
>>> err_out:
>>> iounmap(base);
>>> return err;
>>> diff --git a/drivers/gpu/drm/i915/intel_opregion.h
>>> b/drivers/gpu/drm/i915/intel_opregion.h
>>> new file mode 100644
>>> index 0000000..bcb45ec
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/i915/intel_opregion.h
>>> @@ -0,0 +1,230 @@
>>> +/*
>>> + * Copyright 2008 Intel Corporation <hong.liu@intel.com>
>>> + * Copyright 2008 Red Hat <mjg@redhat.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 INTEL 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.
>>> + *
>>> + */
>>> +
>>> +#define PCI_ASLE 0xe4
>>> +#define PCI_ASLS 0xfc
>>> +#define PCI_SWSCI 0xe8
>>> +#define PCI_SWSCI_SCISEL (1 << 15)
>>> +#define PCI_SWSCI_GSSCIE (1 << 0)
>>> +
>>> +#define OPREGION_HEADER_OFFSET 0
>>> +#define OPREGION_ACPI_OFFSET 0x100
>>> +#define ACPI_CLID 0x01ac /* current lid state indicator */
>>> +#define ACPI_CDCK 0x01b0 /* current docking state indicator */
>>> +#define OPREGION_SWSCI_OFFSET 0x200
>>> +#define OPREGION_ASLE_OFFSET 0x300
>>> +#define OPREGION_VBT_OFFSET 0x400
>>> +
>>> +#define OPREGION_SIGNATURE "IntelGraphicsMem"
>>> +#define MBOX_ACPI (1<<0)
>>> +#define MBOX_SWSCI (1<<1)
>>> +#define MBOX_ASLE (1<<2)
>>> +#define MBOX_ASLE_EXT (1<<4)
>>> +
>>> +struct opregion_header {
>>> + u8 signature[16];
>>> + u32 size;
>>> + u32 opregion_ver;
>>> + u8 bios_ver[32];
>>> + u8 vbios_ver[16];
>>> + u8 driver_ver[16];
>>> + u32 mboxes;
>>> + u32 driver_model;
>>> + u32 pcon;
>>> + u8 dver[32];
>>> + u8 rsvd[124];
>>> +} __packed;
>>> +
>>> +/* OpRegion mailbox #1: public ACPI methods */ struct opregion_acpi {
>>> + u32 drdy; /* driver readiness */
>>> + u32 csts; /* notification status */
>>> + u32 cevt; /* current event */
>>> + u8 rsvd1[20];
>>> + u32 didl[8]; /* supported display devices ID list */
>>> + u32 cpdl[8]; /* currently presented display list */
>>> + u32 cadl[8]; /* currently active display list */
>>> + u32 nadl[8]; /* next active devices list */
>>> + u32 aslp; /* ASL sleep time-out */
>>> + u32 tidx; /* toggle table index */
>>> + u32 chpd; /* current hotplug enable indicator */
>>> + u32 clid; /* current lid state*/
>>> + u32 cdck; /* current docking state */
>>> + u32 sxsw; /* Sx state resume */
>>> + u32 evts; /* ASL supported events */
>>> + u32 cnot; /* current OS notification */
>>> + u32 nrdy; /* driver status */
>>> + u32 did2[7]; /* extended supported display devices ID list */
>>> + u32 cpd2[7]; /* extended attached display devices list */
>>> + u8 rsvd2[4];
>>> +} __packed;
>>> +
>>> +/* OpRegion mailbox #2: SWSCI */
>>> +struct opregion_swsci {
>>> + u32 scic; /* SWSCI command|status|data */
>>> + u32 parm; /* command parameters */
>>> + u32 dslp; /* driver sleep time-out */
>>> + u8 rsvd[244];
>>> +} __packed;
>>> +
>>> +/* OpRegion mailbox #3: ASLE */
>>> +struct opregion_asle {
>>> + u32 ardy; /* driver readiness */
>>> + u32 aslc; /* ASLE interrupt command */
>>> + u32 tche; /* technology enabled indicator */
>>> + u32 alsi; /* current ALS illuminance reading */
>>> + u32 bclp; /* backlight brightness to set */
>>> + u32 pfit; /* panel fitting state */
>>> + u32 cblv; /* current brightness level */
>>> + u16 bclm[20]; /* backlight level duty cycle mapping table */
>>> + u32 cpfm; /* current panel fitting mode */
>>> + u32 epfm; /* enabled panel fitting modes */
>>> + u8 plut[74]; /* panel LUT and identifier */
>>> + u32 pfmb; /* PWM freq and min brightness */
>>> + u32 cddv; /* color correction default values */
>>> + u32 pcft; /* power conservation features */
>>> + u32 srot; /* supported rotation angles */
>>> + u32 iuer; /* IUER events */
>>> + u64 fdss;
>>> + u32 fdsp;
>>> + u32 stat;
>>> + u64 rvda; /* Physical address of raw vbt data */
>>> + u32 rvds; /* Size of raw vbt data */
>>> + u8 rsvd[58];
>>> +} __packed;
>>> +
>>> +/* Driver readiness indicator */
>>> +#define ASLE_ARDY_READY (1 << 0)
>>> +#define ASLE_ARDY_NOT_READY (0 << 0)
>>> +
>>> +/* ASLE Interrupt Command (ASLC) bits */
>>> +#define ASLC_SET_ALS_ILLUM (1 << 0)
>>> +#define ASLC_SET_BACKLIGHT (1 << 1)
>>> +#define ASLC_SET_PFIT (1 << 2)
>>> +#define ASLC_SET_PWM_FREQ (1 << 3)
>>> +#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
>>> +#define ASLC_BUTTON_ARRAY (1 << 5)
>>> +#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
>>> +#define ASLC_DOCKING_INDICATOR (1 << 7)
>>> +#define ASLC_ISCT_STATE_CHANGE (1 << 8)
>>> +#define ASLC_REQ_MSK 0x1ff
>>> +/* response bits */
>>> +#define ASLC_ALS_ILLUM_FAILED (1 << 10)
>>> +#define ASLC_BACKLIGHT_FAILED (1 << 12)
>>> +#define ASLC_PFIT_FAILED (1 << 14)
>>> +#define ASLC_PWM_FREQ_FAILED (1 << 16)
>>> +#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
>>> +#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
>>> +#define ASLC_CONVERTIBLE_FAILED (1 << 22)
>>> +#define ASLC_DOCKING_FAILED (1 << 24)
>>> +#define ASLC_ISCT_STATE_FAILED (1 << 26)
>>> +
>>> +/* Technology enabled indicator */
>>> +#define ASLE_TCHE_ALS_EN (1 << 0)
>>> +#define ASLE_TCHE_BLC_EN (1 << 1)
>>> +#define ASLE_TCHE_PFIT_EN (1 << 2)
>>> +#define ASLE_TCHE_PFMB_EN (1 << 3)
>>> +
>>> +/* ASLE backlight brightness to set */
>>> +#define ASLE_BCLP_VALID (1<<31)
>>> +#define ASLE_BCLP_MSK (~(1<<31))
>>> +
>>> +/* ASLE panel fitting request */
>>> +#define ASLE_PFIT_VALID (1<<31)
>>> +#define ASLE_PFIT_CENTER (1<<0)
>>> +#define ASLE_PFIT_STRETCH_TEXT (1<<1) #define
>>ASLE_PFIT_STRETCH_GFX
>>> +(1<<2)
>>> +
>>> +/* PWM frequency and minimum brightness */ #define
>>> +ASLE_PFMB_BRIGHTNESS_MASK (0xff) #define
>>ASLE_PFMB_BRIGHTNESS_VALID
>>> +(1<<8) #define ASLE_PFMB_PWM_MASK (0x7ffffe00) #define
>>> +ASLE_PFMB_PWM_VALID (1<<31)
>>> +
>>> +#define ASLE_CBLV_VALID (1<<31)
>>> +
>>> +/* IUER */
>>> +#define ASLE_IUER_DOCKING (1 << 7)
>>> +#define ASLE_IUER_CONVERTIBLE (1 << 6)
>>> +#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
>>> +#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
>>> +#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
>>> +#define ASLE_IUER_WINDOWS_BTN (1 << 1)
>>> +#define ASLE_IUER_POWER_BTN (1 << 0)
>>> +
>>> +/* Software System Control Interrupt (SWSCI) */
>>> +#define SWSCI_SCIC_INDICATOR (1 << 0)
>>> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
>>> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
>>> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
>>> +#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
>>> +#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
>>> +#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
>>> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
>>> +#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
>>> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
>>> +
>>> +#define SWSCI_FUNCTION_CODE(main, sub) \
>>> + ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
>>> + (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
>>> +
>>> +/* SWSCI: Get BIOS Data (GBDA) */
>>> +#define SWSCI_GBDA 4
>>> +#define SWSCI_GBDA_SUPPORTED_CALLS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
>>> +#define SWSCI_GBDA_REQUESTED_CALLBACKS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
>>> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
>>> +#define SWSCI_GBDA_PANEL_DETAILS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
>>> +#define SWSCI_GBDA_TV_STANDARD
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
>>> +#define SWSCI_GBDA_INTERNAL_GRAPHICS
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
>>> +#define SWSCI_GBDA_SPREAD_SPECTRUM
>> SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
>>> +
>>> +/* SWSCI: System BIOS Callbacks (SBCB) */
>>> +#define SWSCI_SBCB 6
>>> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
>>> +#define SWSCI_SBCB_INIT_COMPLETION
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
>>> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
>>> +#define SWSCI_SBCB_POST_HIRES_SET_MODE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
>>> +#define SWSCI_SBCB_DISPLAY_SWITCH
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
>>> +#define SWSCI_SBCB_SET_TV_FORMAT
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
>>> +#define SWSCI_SBCB_ADAPTER_POWER_STATE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
>>> +#define SWSCI_SBCB_DISPLAY_POWER_STATE
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
>>> +#define SWSCI_SBCB_SET_BOOT_DISPLAY
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
>>> +#define SWSCI_SBCB_SET_PANEL_DETAILS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
>>> +#define SWSCI_SBCB_SET_INTERNAL_GFX
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
>>> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
>>> +#define SWSCI_SBCB_SUSPEND_RESUME
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
>>> +#define SWSCI_SBCB_SET_SPREAD_SPECTRUM
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
>>> +#define SWSCI_SBCB_POST_VBE_PM
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
>>> +#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
>>> +
>>> +#define ACPI_OTHER_OUTPUT (0<<8)
>>> +#define ACPI_VGA_OUTPUT (1<<8)
>>> +#define ACPI_TV_OUTPUT (2<<8)
>>> +#define ACPI_DIGITAL_OUTPUT (3<<8)
>>> +#define ACPI_LVDS_OUTPUT (4<<8)
>>> +
>>> +#define MAX_DSLP 1500
>>
>>The bottom line here is that I think you could get all of this done with
>>*much* smaller changes. If we get a regression report pointing at this patch,
>>we'll have a lot of debugging to do to figure out what failed.
>>
> [Deepak M] Okay will try to break this patch into smaller one`s.
>>BR,
>>Jani.
>>
>>
>>
>>> --
>>> 1.7.9.5
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>>--
>>Jani Nikula, Intel Open Source Technology Center
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread
* [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (2 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 03/11] drm/i915: Parsing VBT if size of VBT exceeds 6KB Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-17 12:18 ` Jani Nikula
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 05/11] drm/i915: Added support the v3 mipi sequence block Deepak M
` (6 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
Currently the field in bdb header which indicates the VBT size
is of 2 bytes, but there are some cases where VBT size exceeds
64KB in which case this field may not contain the correct VBT size.
So its better to get the VBT size from the mailbox3 if
VBT is not present in the mailbox4 of opregion.
v2: - Use opregion filed from dev_priv struct instead of creating
a new field in dev_priv (Jani)
- Have vbt_size field vaild in all scenarios (Jani)
- rebase
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 2 ++
drivers/gpu/drm/i915/intel_bios.c | 42 +++++++++++++++++++--------------
drivers/gpu/drm/i915/intel_opregion.c | 6 +++++
3 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 507d57a..91ccbc6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1777,6 +1777,8 @@ struct drm_i915_private {
u32 pm_rps_events;
u32 pipestat_irq_mask[I915_MAX_PIPES];
+ u32 vbt_size;
+
struct i915_hotplug hotplug;
struct i915_fbc fbc;
struct i915_drrs drrs;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 1932a86..34a1042 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -37,17 +37,19 @@
static int panel_type;
static const void *
-find_section(const void *_bdb, int section_id)
+find_section(struct drm_i915_private *dev_priv,
+ const void *_bdb, int section_id)
{
const struct bdb_header *bdb = _bdb;
const u8 *base = _bdb;
int index = 0;
- u16 total, current_size;
+ u32 total, current_size;
u8 current_id;
/* skip to first section */
index += bdb->header_size;
- total = bdb->bdb_size;
+
+ total = dev_priv->vbt_size;
/* walk the sections looking for section_id */
while (index + 3 < total) {
@@ -179,7 +181,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
struct drm_display_mode *panel_fixed_mode;
int drrs_mode;
- lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
+ lvds_options = find_section(dev_priv, bdb, BDB_LVDS_OPTIONS);
if (!lvds_options)
return;
@@ -211,11 +213,12 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
break;
}
- lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
+ lvds_lfp_data = find_section(dev_priv, bdb, BDB_LVDS_LFP_DATA);
if (!lvds_lfp_data)
return;
- lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
+ lvds_lfp_data_ptrs = find_section(dev_priv, bdb,
+ BDB_LVDS_LFP_DATA_PTRS);
if (!lvds_lfp_data_ptrs)
return;
@@ -257,7 +260,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
const struct bdb_lfp_backlight_data *backlight_data;
const struct bdb_lfp_backlight_data_entry *entry;
- backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
+ backlight_data = find_section(dev_priv, bdb, BDB_LVDS_BACKLIGHT);
if (!backlight_data)
return;
@@ -305,14 +308,15 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
if (index == -1) {
const struct bdb_sdvo_lvds_options *sdvo_lvds_options;
- sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
+ sdvo_lvds_options = find_section(dev_priv, bdb,
+ BDB_SDVO_LVDS_OPTIONS);
if (!sdvo_lvds_options)
return;
index = sdvo_lvds_options->panel_type;
}
- dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
+ dvo_timing = find_section(dev_priv, bdb, BDB_SDVO_PANEL_DTDS);
if (!dvo_timing)
return;
@@ -349,7 +353,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
struct drm_device *dev = dev_priv->dev;
const struct bdb_general_features *general;
- general = find_section(bdb, BDB_GENERAL_FEATURES);
+ general = find_section(dev_priv, bdb, BDB_GENERAL_FEATURES);
if (general) {
dev_priv->vbt.int_tv_support = general->int_tv_support;
dev_priv->vbt.int_crt_support = general->int_crt_support;
@@ -374,7 +378,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
{
const struct bdb_general_definitions *general;
- general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+ general = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
if (general) {
u16 block_size = get_blocksize(general);
if (block_size >= sizeof(*general)) {
@@ -405,7 +409,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
int i, child_device_num, count;
u16 block_size;
- p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+ p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
if (!p_defs) {
DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
return;
@@ -491,7 +495,7 @@ parse_driver_features(struct drm_i915_private *dev_priv,
{
const struct bdb_driver_features *driver;
- driver = find_section(bdb, BDB_DRIVER_FEATURES);
+ driver = find_section(dev_priv, bdb, BDB_DRIVER_FEATURES);
if (!driver)
return;
@@ -519,7 +523,7 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
const struct edp_power_seq *edp_pps;
const struct edp_link_params *edp_link_params;
- edp = find_section(bdb, BDB_EDP);
+ edp = find_section(dev_priv, bdb, BDB_EDP);
if (!edp) {
if (dev_priv->vbt.edp_support)
DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
@@ -630,7 +634,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
const struct bdb_psr *psr;
const struct psr_table *psr_table;
- psr = find_section(bdb, BDB_PSR);
+ psr = find_section(dev_priv, bdb, BDB_PSR);
if (!psr) {
DRM_DEBUG_KMS("No PSR BDB found.\n");
return;
@@ -768,7 +772,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
/* Parse #52 for panel index used from panel_type already
* parsed
*/
- start = find_section(bdb, BDB_MIPI_CONFIG);
+ start = find_section(dev_priv, bdb, BDB_MIPI_CONFIG);
if (!start) {
DRM_DEBUG_KMS("No MIPI config BDB found");
return;
@@ -799,7 +803,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
/* Check if we have sequence block as well */
- sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
+ sequence = find_section(dev_priv, bdb, BDB_MIPI_SEQUENCE);
if (!sequence) {
DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n");
return;
@@ -1077,7 +1081,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
u8 expected_size;
u16 block_size;
- p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+ p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
if (!p_defs) {
DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
return;
@@ -1280,6 +1284,8 @@ intel_parse_bios(struct drm_device *dev)
pci_unmap_rom(pdev, bios);
return -1;
}
+
+ dev_priv->vbt_size = bdb->bdb_size;
}
/* Grab useful general definitions */
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 3a43db9..c2f1a4a 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -793,6 +793,12 @@ int intel_opregion_setup(struct drm_device *dev)
goto err_vbt;
}
+ /* Assigning the vbt_size based on the VBT location */
+ if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
+ dev_priv->vbt_size = opregion->asle->rvds;
+ else
+ dev_priv->vbt_size = bdb->bdb_size;
+
dev_priv->bdb_start = bdb;
opregion->vbt = vbt_base;
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion Deepak M
@ 2015-09-17 12:18 ` Jani Nikula
2015-09-17 13:31 ` Jani Nikula
2015-09-22 6:24 ` Deepak, M
0 siblings, 2 replies; 25+ messages in thread
From: Jani Nikula @ 2015-09-17 12:18 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
> Currently the field in bdb header which indicates the VBT size
> is of 2 bytes, but there are some cases where VBT size exceeds
> 64KB in which case this field may not contain the correct VBT size.
> So its better to get the VBT size from the mailbox3 if
> VBT is not present in the mailbox4 of opregion.
>
> v2: - Use opregion filed from dev_priv struct instead of creating
> a new field in dev_priv (Jani)
> - Have vbt_size field vaild in all scenarios (Jani)
> - rebase
>
> Signed-off-by: Deepak M <m.deepak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 ++
> drivers/gpu/drm/i915/intel_bios.c | 42 +++++++++++++++++++--------------
> drivers/gpu/drm/i915/intel_opregion.c | 6 +++++
> 3 files changed, 32 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 507d57a..91ccbc6 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1777,6 +1777,8 @@ struct drm_i915_private {
> u32 pm_rps_events;
> u32 pipestat_irq_mask[I915_MAX_PIPES];
>
> + u32 vbt_size;
No. dev_priv is not a random area to throw things into. The place you're
looking for is dev_priv->opregion, i.e. struct intel_opregion.
> +
> struct i915_hotplug hotplug;
> struct i915_fbc fbc;
> struct i915_drrs drrs;
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index 1932a86..34a1042 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -37,17 +37,19 @@
> static int panel_type;
>
> static const void *
> -find_section(const void *_bdb, int section_id)
> +find_section(struct drm_i915_private *dev_priv,
> + const void *_bdb, int section_id)
> {
> const struct bdb_header *bdb = _bdb;
> const u8 *base = _bdb;
> int index = 0;
> - u16 total, current_size;
> + u32 total, current_size;
> u8 current_id;
>
> /* skip to first section */
> index += bdb->header_size;
> - total = bdb->bdb_size;
> +
> + total = dev_priv->vbt_size;
vbt_size != bdb_size. See below.
>
> /* walk the sections looking for section_id */
> while (index + 3 < total) {
> @@ -179,7 +181,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
> struct drm_display_mode *panel_fixed_mode;
> int drrs_mode;
>
> - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
> + lvds_options = find_section(dev_priv, bdb, BDB_LVDS_OPTIONS);
> if (!lvds_options)
> return;
>
> @@ -211,11 +213,12 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
> break;
> }
>
> - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
> + lvds_lfp_data = find_section(dev_priv, bdb, BDB_LVDS_LFP_DATA);
> if (!lvds_lfp_data)
> return;
>
> - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
> + lvds_lfp_data_ptrs = find_section(dev_priv, bdb,
> + BDB_LVDS_LFP_DATA_PTRS);
> if (!lvds_lfp_data_ptrs)
> return;
>
> @@ -257,7 +260,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
> const struct bdb_lfp_backlight_data *backlight_data;
> const struct bdb_lfp_backlight_data_entry *entry;
>
> - backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
> + backlight_data = find_section(dev_priv, bdb, BDB_LVDS_BACKLIGHT);
> if (!backlight_data)
> return;
>
> @@ -305,14 +308,15 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
> if (index == -1) {
> const struct bdb_sdvo_lvds_options *sdvo_lvds_options;
>
> - sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
> + sdvo_lvds_options = find_section(dev_priv, bdb,
> + BDB_SDVO_LVDS_OPTIONS);
> if (!sdvo_lvds_options)
> return;
>
> index = sdvo_lvds_options->panel_type;
> }
>
> - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
> + dvo_timing = find_section(dev_priv, bdb, BDB_SDVO_PANEL_DTDS);
> if (!dvo_timing)
> return;
>
> @@ -349,7 +353,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
> struct drm_device *dev = dev_priv->dev;
> const struct bdb_general_features *general;
>
> - general = find_section(bdb, BDB_GENERAL_FEATURES);
> + general = find_section(dev_priv, bdb, BDB_GENERAL_FEATURES);
> if (general) {
> dev_priv->vbt.int_tv_support = general->int_tv_support;
> dev_priv->vbt.int_crt_support = general->int_crt_support;
> @@ -374,7 +378,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
> {
> const struct bdb_general_definitions *general;
>
> - general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
> + general = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
> if (general) {
> u16 block_size = get_blocksize(general);
> if (block_size >= sizeof(*general)) {
> @@ -405,7 +409,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
> int i, child_device_num, count;
> u16 block_size;
>
> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
> if (!p_defs) {
> DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
> return;
> @@ -491,7 +495,7 @@ parse_driver_features(struct drm_i915_private *dev_priv,
> {
> const struct bdb_driver_features *driver;
>
> - driver = find_section(bdb, BDB_DRIVER_FEATURES);
> + driver = find_section(dev_priv, bdb, BDB_DRIVER_FEATURES);
> if (!driver)
> return;
>
> @@ -519,7 +523,7 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
> const struct edp_power_seq *edp_pps;
> const struct edp_link_params *edp_link_params;
>
> - edp = find_section(bdb, BDB_EDP);
> + edp = find_section(dev_priv, bdb, BDB_EDP);
> if (!edp) {
> if (dev_priv->vbt.edp_support)
> DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
> @@ -630,7 +634,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
> const struct bdb_psr *psr;
> const struct psr_table *psr_table;
>
> - psr = find_section(bdb, BDB_PSR);
> + psr = find_section(dev_priv, bdb, BDB_PSR);
> if (!psr) {
> DRM_DEBUG_KMS("No PSR BDB found.\n");
> return;
> @@ -768,7 +772,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
> /* Parse #52 for panel index used from panel_type already
> * parsed
> */
> - start = find_section(bdb, BDB_MIPI_CONFIG);
> + start = find_section(dev_priv, bdb, BDB_MIPI_CONFIG);
> if (!start) {
> DRM_DEBUG_KMS("No MIPI config BDB found");
> return;
> @@ -799,7 +803,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
> dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
>
> /* Check if we have sequence block as well */
> - sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
> + sequence = find_section(dev_priv, bdb, BDB_MIPI_SEQUENCE);
> if (!sequence) {
> DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n");
> return;
> @@ -1077,7 +1081,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
> u8 expected_size;
> u16 block_size;
>
> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
> if (!p_defs) {
> DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
> return;
> @@ -1280,6 +1284,8 @@ intel_parse_bios(struct drm_device *dev)
> pci_unmap_rom(pdev, bios);
> return -1;
> }
> +
> + dev_priv->vbt_size = bdb->bdb_size;
> }
>
> /* Grab useful general definitions */
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index 3a43db9..c2f1a4a 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -793,6 +793,12 @@ int intel_opregion_setup(struct drm_device *dev)
> goto err_vbt;
> }
>
> + /* Assigning the vbt_size based on the VBT location */
> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
> + dev_priv->vbt_size = opregion->asle->rvds;
IIUC this one includes VBT Header...
> + else
> + dev_priv->vbt_size = bdb->bdb_size;
...and this one doesn't, so one of them will be wrong in the size checks
in find_section.
If you have a variable called "vbt_size" it better include all of VBT,
and not just part of it.
BR,
Jani.
> +
> dev_priv->bdb_start = bdb;
> opregion->vbt = vbt_base;
>
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion
2015-09-17 12:18 ` Jani Nikula
@ 2015-09-17 13:31 ` Jani Nikula
2015-09-22 6:11 ` Deepak, M
2015-09-22 6:24 ` Deepak, M
1 sibling, 1 reply; 25+ messages in thread
From: Jani Nikula @ 2015-09-17 13:31 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
On Thu, 17 Sep 2015, Jani Nikula <jani.nikula@linux.intel.com> wrote:
> On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
>> Currently the field in bdb header which indicates the VBT size
>> is of 2 bytes, but there are some cases where VBT size exceeds
>> 64KB in which case this field may not contain the correct VBT size.
>> So its better to get the VBT size from the mailbox3 if
>> VBT is not present in the mailbox4 of opregion.
>>
>> v2: - Use opregion filed from dev_priv struct instead of creating
>> a new field in dev_priv (Jani)
>> - Have vbt_size field vaild in all scenarios (Jani)
>> - rebase
>>
>> Signed-off-by: Deepak M <m.deepak@intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_drv.h | 2 ++
>> drivers/gpu/drm/i915/intel_bios.c | 42 +++++++++++++++++++--------------
>> drivers/gpu/drm/i915/intel_opregion.c | 6 +++++
>> 3 files changed, 32 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 507d57a..91ccbc6 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1777,6 +1777,8 @@ struct drm_i915_private {
>> u32 pm_rps_events;
>> u32 pipestat_irq_mask[I915_MAX_PIPES];
>>
>> + u32 vbt_size;
>
> No. dev_priv is not a random area to throw things into. The place you're
> looking for is dev_priv->opregion, i.e. struct intel_opregion.
>
>> +
>> struct i915_hotplug hotplug;
>> struct i915_fbc fbc;
>> struct i915_drrs drrs;
>> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
>> index 1932a86..34a1042 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.c
>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>> @@ -37,17 +37,19 @@
>> static int panel_type;
>>
>> static const void *
>> -find_section(const void *_bdb, int section_id)
>> +find_section(struct drm_i915_private *dev_priv,
>> + const void *_bdb, int section_id)
>> {
>> const struct bdb_header *bdb = _bdb;
>> const u8 *base = _bdb;
>> int index = 0;
>> - u16 total, current_size;
>> + u32 total, current_size;
>> u8 current_id;
>>
>> /* skip to first section */
>> index += bdb->header_size;
>> - total = bdb->bdb_size;
>> +
>> + total = dev_priv->vbt_size;
>
> vbt_size != bdb_size. See below.
>
>>
>> /* walk the sections looking for section_id */
>> while (index + 3 < total) {
>> @@ -179,7 +181,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
>> struct drm_display_mode *panel_fixed_mode;
>> int drrs_mode;
>>
>> - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
>> + lvds_options = find_section(dev_priv, bdb, BDB_LVDS_OPTIONS);
>> if (!lvds_options)
>> return;
>>
>> @@ -211,11 +213,12 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
>> break;
>> }
>>
>> - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
>> + lvds_lfp_data = find_section(dev_priv, bdb, BDB_LVDS_LFP_DATA);
>> if (!lvds_lfp_data)
>> return;
>>
>> - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
>> + lvds_lfp_data_ptrs = find_section(dev_priv, bdb,
>> + BDB_LVDS_LFP_DATA_PTRS);
>> if (!lvds_lfp_data_ptrs)
>> return;
>>
>> @@ -257,7 +260,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
>> const struct bdb_lfp_backlight_data *backlight_data;
>> const struct bdb_lfp_backlight_data_entry *entry;
>>
>> - backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
>> + backlight_data = find_section(dev_priv, bdb, BDB_LVDS_BACKLIGHT);
>> if (!backlight_data)
>> return;
>>
>> @@ -305,14 +308,15 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
>> if (index == -1) {
>> const struct bdb_sdvo_lvds_options *sdvo_lvds_options;
>>
>> - sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
>> + sdvo_lvds_options = find_section(dev_priv, bdb,
>> + BDB_SDVO_LVDS_OPTIONS);
>> if (!sdvo_lvds_options)
>> return;
>>
>> index = sdvo_lvds_options->panel_type;
>> }
>>
>> - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
>> + dvo_timing = find_section(dev_priv, bdb, BDB_SDVO_PANEL_DTDS);
>> if (!dvo_timing)
>> return;
>>
>> @@ -349,7 +353,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
>> struct drm_device *dev = dev_priv->dev;
>> const struct bdb_general_features *general;
>>
>> - general = find_section(bdb, BDB_GENERAL_FEATURES);
>> + general = find_section(dev_priv, bdb, BDB_GENERAL_FEATURES);
>> if (general) {
>> dev_priv->vbt.int_tv_support = general->int_tv_support;
>> dev_priv->vbt.int_crt_support = general->int_crt_support;
>> @@ -374,7 +378,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
>> {
>> const struct bdb_general_definitions *general;
>>
>> - general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>> + general = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>> if (general) {
>> u16 block_size = get_blocksize(general);
>> if (block_size >= sizeof(*general)) {
>> @@ -405,7 +409,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
>> int i, child_device_num, count;
>> u16 block_size;
>>
>> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>> if (!p_defs) {
>> DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
>> return;
>> @@ -491,7 +495,7 @@ parse_driver_features(struct drm_i915_private *dev_priv,
>> {
>> const struct bdb_driver_features *driver;
>>
>> - driver = find_section(bdb, BDB_DRIVER_FEATURES);
>> + driver = find_section(dev_priv, bdb, BDB_DRIVER_FEATURES);
>> if (!driver)
>> return;
>>
>> @@ -519,7 +523,7 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
>> const struct edp_power_seq *edp_pps;
>> const struct edp_link_params *edp_link_params;
>>
>> - edp = find_section(bdb, BDB_EDP);
>> + edp = find_section(dev_priv, bdb, BDB_EDP);
>> if (!edp) {
>> if (dev_priv->vbt.edp_support)
>> DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
>> @@ -630,7 +634,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
>> const struct bdb_psr *psr;
>> const struct psr_table *psr_table;
>>
>> - psr = find_section(bdb, BDB_PSR);
>> + psr = find_section(dev_priv, bdb, BDB_PSR);
>> if (!psr) {
>> DRM_DEBUG_KMS("No PSR BDB found.\n");
>> return;
>> @@ -768,7 +772,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
>> /* Parse #52 for panel index used from panel_type already
>> * parsed
>> */
>> - start = find_section(bdb, BDB_MIPI_CONFIG);
>> + start = find_section(dev_priv, bdb, BDB_MIPI_CONFIG);
>> if (!start) {
>> DRM_DEBUG_KMS("No MIPI config BDB found");
>> return;
>> @@ -799,7 +803,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
>> dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
>>
>> /* Check if we have sequence block as well */
>> - sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
>> + sequence = find_section(dev_priv, bdb, BDB_MIPI_SEQUENCE);
>> if (!sequence) {
>> DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n");
>> return;
>> @@ -1077,7 +1081,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
>> u8 expected_size;
>> u16 block_size;
>>
>> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>> if (!p_defs) {
>> DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
>> return;
>> @@ -1280,6 +1284,8 @@ intel_parse_bios(struct drm_device *dev)
>> pci_unmap_rom(pdev, bios);
>> return -1;
>> }
>> +
>> + dev_priv->vbt_size = bdb->bdb_size;
>> }
>>
>> /* Grab useful general definitions */
>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
>> index 3a43db9..c2f1a4a 100644
>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>> @@ -793,6 +793,12 @@ int intel_opregion_setup(struct drm_device *dev)
>> goto err_vbt;
>> }
>>
>> + /* Assigning the vbt_size based on the VBT location */
>> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
>> + dev_priv->vbt_size = opregion->asle->rvds;
>
> IIUC this one includes VBT Header...
>
>> + else
>> + dev_priv->vbt_size = bdb->bdb_size;
>
> ...and this one doesn't, so one of them will be wrong in the size checks
> in find_section.
>
> If you have a variable called "vbt_size" it better include all of VBT,
> and not just part of it.
Okay, this is not your fault, but it's hard for me to review the code
because the VBT spec still has these inconsistensies:
VBT Table Size in VBT Header includes "VBT header, BDB Header and all
Data blocks". VBT Table Size is a 16-bit value. How can the MIPI
Sequence Block require a separate 32-bit size field, when it then
couldn't fit in the VBT?
BDB Size in BDB Header includes "BDB Header and all Data blocks". BDB
Size is a 16-bit value. Same thing.
BR,
Jani.
>
>
> BR,
> Jani.
>
>
>> +
>> dev_priv->bdb_start = bdb;
>> opregion->vbt = vbt_base;
>>
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Jani Nikula, Intel Open Source Technology Center
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion
2015-09-17 13:31 ` Jani Nikula
@ 2015-09-22 6:11 ` Deepak, M
0 siblings, 0 replies; 25+ messages in thread
From: Deepak, M @ 2015-09-22 6:11 UTC (permalink / raw)
To: Jani Nikula, intel-gfx@lists.freedesktop.org
>-----Original Message-----
>From: Jani Nikula [mailto:jani.nikula@linux.intel.com]
>Sent: Thursday, September 17, 2015 7:01 PM
>To: Deepak, M; intel-gfx@lists.freedesktop.org
>Cc: Deepak, M
>Subject: Re: [Intel-gfx] [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using
>the approprite vbt size if vbt is not in mailbox4 of opregion
>
>On Thu, 17 Sep 2015, Jani Nikula <jani.nikula@linux.intel.com> wrote:
>> On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
>>> Currently the field in bdb header which indicates the VBT size is of
>>> 2 bytes, but there are some cases where VBT size exceeds 64KB in
>>> which case this field may not contain the correct VBT size.
>>> So its better to get the VBT size from the mailbox3 if VBT is not
>>> present in the mailbox4 of opregion.
>>>
>>> v2: - Use opregion filed from dev_priv struct instead of creating
>>> a new field in dev_priv (Jani)
>>> - Have vbt_size field vaild in all scenarios (Jani)
>>> - rebase
>>>
>>> Signed-off-by: Deepak M <m.deepak@intel.com>
>>> ---
>>> drivers/gpu/drm/i915/i915_drv.h | 2 ++
>>> drivers/gpu/drm/i915/intel_bios.c | 42 +++++++++++++++++++---------
>-----
>>> drivers/gpu/drm/i915/intel_opregion.c | 6 +++++
>>> 3 files changed, 32 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>>> b/drivers/gpu/drm/i915/i915_drv.h index 507d57a..91ccbc6 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -1777,6 +1777,8 @@ struct drm_i915_private {
>>> u32 pm_rps_events;
>>> u32 pipestat_irq_mask[I915_MAX_PIPES];
>>>
>>> + u32 vbt_size;
>>
>> No. dev_priv is not a random area to throw things into. The place
>> you're looking for is dev_priv->opregion, i.e. struct intel_opregion.
>>
>>> +
>>> struct i915_hotplug hotplug;
>>> struct i915_fbc fbc;
>>> struct i915_drrs drrs;
>>> diff --git a/drivers/gpu/drm/i915/intel_bios.c
>>> b/drivers/gpu/drm/i915/intel_bios.c
>>> index 1932a86..34a1042 100644
>>> --- a/drivers/gpu/drm/i915/intel_bios.c
>>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>>> @@ -37,17 +37,19 @@
>>> static int panel_type;
>>>
>>> static const void *
>>> -find_section(const void *_bdb, int section_id)
>>> +find_section(struct drm_i915_private *dev_priv,
>>> + const void *_bdb, int section_id)
>>> {
>>> const struct bdb_header *bdb = _bdb;
>>> const u8 *base = _bdb;
>>> int index = 0;
>>> - u16 total, current_size;
>>> + u32 total, current_size;
>>> u8 current_id;
>>>
>>> /* skip to first section */
>>> index += bdb->header_size;
>>> - total = bdb->bdb_size;
>>> +
>>> + total = dev_priv->vbt_size;
>>
>> vbt_size != bdb_size. See below.
>>
>>>
>>> /* walk the sections looking for section_id */
>>> while (index + 3 < total) {
>>> @@ -179,7 +181,7 @@ parse_lfp_panel_data(struct drm_i915_private
>*dev_priv,
>>> struct drm_display_mode *panel_fixed_mode;
>>> int drrs_mode;
>>>
>>> - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
>>> + lvds_options = find_section(dev_priv, bdb, BDB_LVDS_OPTIONS);
>>> if (!lvds_options)
>>> return;
>>>
>>> @@ -211,11 +213,12 @@ parse_lfp_panel_data(struct drm_i915_private
>*dev_priv,
>>> break;
>>> }
>>>
>>> - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
>>> + lvds_lfp_data = find_section(dev_priv, bdb, BDB_LVDS_LFP_DATA);
>>> if (!lvds_lfp_data)
>>> return;
>>>
>>> - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
>>> + lvds_lfp_data_ptrs = find_section(dev_priv, bdb,
>>> + BDB_LVDS_LFP_DATA_PTRS);
>>> if (!lvds_lfp_data_ptrs)
>>> return;
>>>
>>> @@ -257,7 +260,7 @@ parse_lfp_backlight(struct drm_i915_private
>*dev_priv,
>>> const struct bdb_lfp_backlight_data *backlight_data;
>>> const struct bdb_lfp_backlight_data_entry *entry;
>>>
>>> - backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
>>> + backlight_data = find_section(dev_priv, bdb, BDB_LVDS_BACKLIGHT);
>>> if (!backlight_data)
>>> return;
>>>
>>> @@ -305,14 +308,15 @@ parse_sdvo_panel_data(struct drm_i915_private
>*dev_priv,
>>> if (index == -1) {
>>> const struct bdb_sdvo_lvds_options *sdvo_lvds_options;
>>>
>>> - sdvo_lvds_options = find_section(bdb,
>BDB_SDVO_LVDS_OPTIONS);
>>> + sdvo_lvds_options = find_section(dev_priv, bdb,
>>> + BDB_SDVO_LVDS_OPTIONS);
>>> if (!sdvo_lvds_options)
>>> return;
>>>
>>> index = sdvo_lvds_options->panel_type;
>>> }
>>>
>>> - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
>>> + dvo_timing = find_section(dev_priv, bdb, BDB_SDVO_PANEL_DTDS);
>>> if (!dvo_timing)
>>> return;
>>>
>>> @@ -349,7 +353,7 @@ parse_general_features(struct drm_i915_private
>*dev_priv,
>>> struct drm_device *dev = dev_priv->dev;
>>> const struct bdb_general_features *general;
>>>
>>> - general = find_section(bdb, BDB_GENERAL_FEATURES);
>>> + general = find_section(dev_priv, bdb, BDB_GENERAL_FEATURES);
>>> if (general) {
>>> dev_priv->vbt.int_tv_support = general->int_tv_support;
>>> dev_priv->vbt.int_crt_support = general->int_crt_support;
>@@
>>> -374,7 +378,7 @@ parse_general_definitions(struct drm_i915_private
>>> *dev_priv, {
>>> const struct bdb_general_definitions *general;
>>>
>>> - general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>>> + general = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>>> if (general) {
>>> u16 block_size = get_blocksize(general);
>>> if (block_size >= sizeof(*general)) { @@ -405,7 +409,7 @@
>>> parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
>>> int i, child_device_num, count;
>>> u16 block_size;
>>>
>>> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>>> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>>> if (!p_defs) {
>>> DRM_DEBUG_KMS("No general definition block is found,
>unable to construct sdvo mapping.\n");
>>> return;
>>> @@ -491,7 +495,7 @@ parse_driver_features(struct drm_i915_private
>>> *dev_priv, {
>>> const struct bdb_driver_features *driver;
>>>
>>> - driver = find_section(bdb, BDB_DRIVER_FEATURES);
>>> + driver = find_section(dev_priv, bdb, BDB_DRIVER_FEATURES);
>>> if (!driver)
>>> return;
>>>
>>> @@ -519,7 +523,7 @@ parse_edp(struct drm_i915_private *dev_priv,
>const struct bdb_header *bdb)
>>> const struct edp_power_seq *edp_pps;
>>> const struct edp_link_params *edp_link_params;
>>>
>>> - edp = find_section(bdb, BDB_EDP);
>>> + edp = find_section(dev_priv, bdb, BDB_EDP);
>>> if (!edp) {
>>> if (dev_priv->vbt.edp_support)
>>> DRM_DEBUG_KMS("No eDP BDB found but eDP panel
>supported.\n"); @@
>>> -630,7 +634,7 @@ parse_psr(struct drm_i915_private *dev_priv, const
>struct bdb_header *bdb)
>>> const struct bdb_psr *psr;
>>> const struct psr_table *psr_table;
>>>
>>> - psr = find_section(bdb, BDB_PSR);
>>> + psr = find_section(dev_priv, bdb, BDB_PSR);
>>> if (!psr) {
>>> DRM_DEBUG_KMS("No PSR BDB found.\n");
>>> return;
>>> @@ -768,7 +772,7 @@ parse_mipi(struct drm_i915_private *dev_priv,
>const struct bdb_header *bdb)
>>> /* Parse #52 for panel index used from panel_type already
>>> * parsed
>>> */
>>> - start = find_section(bdb, BDB_MIPI_CONFIG);
>>> + start = find_section(dev_priv, bdb, BDB_MIPI_CONFIG);
>>> if (!start) {
>>> DRM_DEBUG_KMS("No MIPI config BDB found");
>>> return;
>>> @@ -799,7 +803,7 @@ parse_mipi(struct drm_i915_private *dev_priv,
>const struct bdb_header *bdb)
>>> dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
>>>
>>> /* Check if we have sequence block as well */
>>> - sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
>>> + sequence = find_section(dev_priv, bdb, BDB_MIPI_SEQUENCE);
>>> if (!sequence) {
>>> DRM_DEBUG_KMS("No MIPI Sequence found, parsing
>complete\n");
>>> return;
>>> @@ -1077,7 +1081,7 @@ parse_device_mapping(struct drm_i915_private
>*dev_priv,
>>> u8 expected_size;
>>> u16 block_size;
>>>
>>> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>>> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>>> if (!p_defs) {
>>> DRM_DEBUG_KMS("No general definition block is found, no
>devices defined.\n");
>>> return;
>>> @@ -1280,6 +1284,8 @@ intel_parse_bios(struct drm_device *dev)
>>> pci_unmap_rom(pdev, bios);
>>> return -1;
>>> }
>>> +
>>> + dev_priv->vbt_size = bdb->bdb_size;
>>> }
>>>
>>> /* Grab useful general definitions */ diff --git
>>> a/drivers/gpu/drm/i915/intel_opregion.c
>>> b/drivers/gpu/drm/i915/intel_opregion.c
>>> index 3a43db9..c2f1a4a 100644
>>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>>> @@ -793,6 +793,12 @@ int intel_opregion_setup(struct drm_device *dev)
>>> goto err_vbt;
>>> }
>>>
>>> + /* Assigning the vbt_size based on the VBT location */
>>> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
>>> + dev_priv->vbt_size = opregion->asle->rvds;
>>
>> IIUC this one includes VBT Header...
>>
>>> + else
>>> + dev_priv->vbt_size = bdb->bdb_size;
>>
>> ...and this one doesn't, so one of them will be wrong in the size
>> checks in find_section.
>>
>> If you have a variable called "vbt_size" it better include all of VBT,
>> and not just part of it.
>
>Okay, this is not your fault, but it's hard for me to review the code because
>the VBT spec still has these inconsistensies:
>
>VBT Table Size in VBT Header includes "VBT header, BDB Header and all Data
>blocks". VBT Table Size is a 16-bit value. How can the MIPI Sequence Block
>require a separate 32-bit size field, when it then couldn't fit in the VBT?
>
[Deepak M] Yes, there is a miss in the VBT spec and then these VBT`s are already used in the products.
Here is what I thought to counter it, with an assumption:
When the VBT is not present in the mailbox4 then VBT size needs to be read from the mailbox3 and this VBT size field
is of 4 bytes which implies that it can be more than 64KB (2^16 - max size which can be stored in the VBT Table size in the VBT header )also.
If the VBT size is more than 64KB then the VBT size field in the bdb header can't be relied. So assumption is ; it's better to consider
the vbt size from the mailbox3 when the VBT is not present in mailbox4.
>BDB Size in BDB Header includes "BDB Header and all Data blocks". BDB Size is
>a 16-bit value. Same thing.
>
>BR,
>Jani.
>
>
>
>>
>>
>> BR,
>> Jani.
>>
>>
>>> +
>>> dev_priv->bdb_start = bdb;
>>> opregion->vbt = vbt_base;
>>>
>>> --
>>> 1.7.9.5
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>> --
>> Jani Nikula, Intel Open Source Technology Center
>
>--
>Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion
2015-09-17 12:18 ` Jani Nikula
2015-09-17 13:31 ` Jani Nikula
@ 2015-09-22 6:24 ` Deepak, M
1 sibling, 0 replies; 25+ messages in thread
From: Deepak, M @ 2015-09-22 6:24 UTC (permalink / raw)
To: Jani Nikula, intel-gfx@lists.freedesktop.org
>-----Original Message-----
>From: Jani Nikula [mailto:jani.nikula@linux.intel.com]
>Sent: Thursday, September 17, 2015 5:48 PM
>To: Deepak, M; intel-gfx@lists.freedesktop.org
>Cc: Deepak, M
>Subject: Re: [Intel-gfx] [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using
>the approprite vbt size if vbt is not in mailbox4 of opregion
>
>On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
>> Currently the field in bdb header which indicates the VBT size is of 2
>> bytes, but there are some cases where VBT size exceeds 64KB in which
>> case this field may not contain the correct VBT size.
>> So its better to get the VBT size from the mailbox3 if VBT is not
>> present in the mailbox4 of opregion.
>>
>> v2: - Use opregion filed from dev_priv struct instead of creating
>> a new field in dev_priv (Jani)
>> - Have vbt_size field vaild in all scenarios (Jani)
>> - rebase
>>
>> Signed-off-by: Deepak M <m.deepak@intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_drv.h | 2 ++
>> drivers/gpu/drm/i915/intel_bios.c | 42 +++++++++++++++++++----------
>----
>> drivers/gpu/drm/i915/intel_opregion.c | 6 +++++
>> 3 files changed, 32 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>> b/drivers/gpu/drm/i915/i915_drv.h index 507d57a..91ccbc6 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1777,6 +1777,8 @@ struct drm_i915_private {
>> u32 pm_rps_events;
>> u32 pipestat_irq_mask[I915_MAX_PIPES];
>>
>> + u32 vbt_size;
>
>No. dev_priv is not a random area to throw things into. The place you're
>looking for is dev_priv->opregion, i.e. struct intel_opregion.
>
>> +
>> struct i915_hotplug hotplug;
>> struct i915_fbc fbc;
>> struct i915_drrs drrs;
>> diff --git a/drivers/gpu/drm/i915/intel_bios.c
>> b/drivers/gpu/drm/i915/intel_bios.c
>> index 1932a86..34a1042 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.c
>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>> @@ -37,17 +37,19 @@
>> static int panel_type;
>>
>> static const void *
>> -find_section(const void *_bdb, int section_id)
>> +find_section(struct drm_i915_private *dev_priv,
>> + const void *_bdb, int section_id)
>> {
>> const struct bdb_header *bdb = _bdb;
>> const u8 *base = _bdb;
>> int index = 0;
>> - u16 total, current_size;
>> + u32 total, current_size;
>> u8 current_id;
>>
>> /* skip to first section */
>> index += bdb->header_size;
>> - total = bdb->bdb_size;
>> +
>> + total = dev_priv->vbt_size;
>
>vbt_size != bdb_size. See below.
>
>>
>> /* walk the sections looking for section_id */
>> while (index + 3 < total) {
>> @@ -179,7 +181,7 @@ parse_lfp_panel_data(struct drm_i915_private
>*dev_priv,
>> struct drm_display_mode *panel_fixed_mode;
>> int drrs_mode;
>>
>> - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
>> + lvds_options = find_section(dev_priv, bdb, BDB_LVDS_OPTIONS);
>> if (!lvds_options)
>> return;
>>
>> @@ -211,11 +213,12 @@ parse_lfp_panel_data(struct drm_i915_private
>*dev_priv,
>> break;
>> }
>>
>> - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
>> + lvds_lfp_data = find_section(dev_priv, bdb, BDB_LVDS_LFP_DATA);
>> if (!lvds_lfp_data)
>> return;
>>
>> - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
>> + lvds_lfp_data_ptrs = find_section(dev_priv, bdb,
>> + BDB_LVDS_LFP_DATA_PTRS);
>> if (!lvds_lfp_data_ptrs)
>> return;
>>
>> @@ -257,7 +260,7 @@ parse_lfp_backlight(struct drm_i915_private
>*dev_priv,
>> const struct bdb_lfp_backlight_data *backlight_data;
>> const struct bdb_lfp_backlight_data_entry *entry;
>>
>> - backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
>> + backlight_data = find_section(dev_priv, bdb, BDB_LVDS_BACKLIGHT);
>> if (!backlight_data)
>> return;
>>
>> @@ -305,14 +308,15 @@ parse_sdvo_panel_data(struct drm_i915_private
>*dev_priv,
>> if (index == -1) {
>> const struct bdb_sdvo_lvds_options *sdvo_lvds_options;
>>
>> - sdvo_lvds_options = find_section(bdb,
>BDB_SDVO_LVDS_OPTIONS);
>> + sdvo_lvds_options = find_section(dev_priv, bdb,
>> + BDB_SDVO_LVDS_OPTIONS);
>> if (!sdvo_lvds_options)
>> return;
>>
>> index = sdvo_lvds_options->panel_type;
>> }
>>
>> - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
>> + dvo_timing = find_section(dev_priv, bdb, BDB_SDVO_PANEL_DTDS);
>> if (!dvo_timing)
>> return;
>>
>> @@ -349,7 +353,7 @@ parse_general_features(struct drm_i915_private
>*dev_priv,
>> struct drm_device *dev = dev_priv->dev;
>> const struct bdb_general_features *general;
>>
>> - general = find_section(bdb, BDB_GENERAL_FEATURES);
>> + general = find_section(dev_priv, bdb, BDB_GENERAL_FEATURES);
>> if (general) {
>> dev_priv->vbt.int_tv_support = general->int_tv_support;
>> dev_priv->vbt.int_crt_support = general->int_crt_support;
>@@ -374,7
>> +378,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
>> {
>> const struct bdb_general_definitions *general;
>>
>> - general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>> + general = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>> if (general) {
>> u16 block_size = get_blocksize(general);
>> if (block_size >= sizeof(*general)) { @@ -405,7 +409,7 @@
>> parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
>> int i, child_device_num, count;
>> u16 block_size;
>>
>> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>> if (!p_defs) {
>> DRM_DEBUG_KMS("No general definition block is found,
>unable to construct sdvo mapping.\n");
>> return;
>> @@ -491,7 +495,7 @@ parse_driver_features(struct drm_i915_private
>> *dev_priv, {
>> const struct bdb_driver_features *driver;
>>
>> - driver = find_section(bdb, BDB_DRIVER_FEATURES);
>> + driver = find_section(dev_priv, bdb, BDB_DRIVER_FEATURES);
>> if (!driver)
>> return;
>>
>> @@ -519,7 +523,7 @@ parse_edp(struct drm_i915_private *dev_priv, const
>struct bdb_header *bdb)
>> const struct edp_power_seq *edp_pps;
>> const struct edp_link_params *edp_link_params;
>>
>> - edp = find_section(bdb, BDB_EDP);
>> + edp = find_section(dev_priv, bdb, BDB_EDP);
>> if (!edp) {
>> if (dev_priv->vbt.edp_support)
>> DRM_DEBUG_KMS("No eDP BDB found but eDP panel
>supported.\n"); @@
>> -630,7 +634,7 @@ parse_psr(struct drm_i915_private *dev_priv, const
>struct bdb_header *bdb)
>> const struct bdb_psr *psr;
>> const struct psr_table *psr_table;
>>
>> - psr = find_section(bdb, BDB_PSR);
>> + psr = find_section(dev_priv, bdb, BDB_PSR);
>> if (!psr) {
>> DRM_DEBUG_KMS("No PSR BDB found.\n");
>> return;
>> @@ -768,7 +772,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const
>struct bdb_header *bdb)
>> /* Parse #52 for panel index used from panel_type already
>> * parsed
>> */
>> - start = find_section(bdb, BDB_MIPI_CONFIG);
>> + start = find_section(dev_priv, bdb, BDB_MIPI_CONFIG);
>> if (!start) {
>> DRM_DEBUG_KMS("No MIPI config BDB found");
>> return;
>> @@ -799,7 +803,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const
>struct bdb_header *bdb)
>> dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
>>
>> /* Check if we have sequence block as well */
>> - sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
>> + sequence = find_section(dev_priv, bdb, BDB_MIPI_SEQUENCE);
>> if (!sequence) {
>> DRM_DEBUG_KMS("No MIPI Sequence found, parsing
>complete\n");
>> return;
>> @@ -1077,7 +1081,7 @@ parse_device_mapping(struct drm_i915_private
>*dev_priv,
>> u8 expected_size;
>> u16 block_size;
>>
>> - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
>> + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS);
>> if (!p_defs) {
>> DRM_DEBUG_KMS("No general definition block is found, no
>devices defined.\n");
>> return;
>> @@ -1280,6 +1284,8 @@ intel_parse_bios(struct drm_device *dev)
>> pci_unmap_rom(pdev, bios);
>> return -1;
>> }
>> +
>> + dev_priv->vbt_size = bdb->bdb_size;
>> }
>>
>> /* Grab useful general definitions */ diff --git
>> a/drivers/gpu/drm/i915/intel_opregion.c
>> b/drivers/gpu/drm/i915/intel_opregion.c
>> index 3a43db9..c2f1a4a 100644
>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>> @@ -793,6 +793,12 @@ int intel_opregion_setup(struct drm_device *dev)
>> goto err_vbt;
>> }
>>
>> + /* Assigning the vbt_size based on the VBT location */
>> + if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
>> + dev_priv->vbt_size = opregion->asle->rvds;
>
>IIUC this one includes VBT Header...
>
>> + else
>> + dev_priv->vbt_size = bdb->bdb_size;
>
>...and this one doesn't, so one of them will be wrong in the size checks in
>find_section.
>
>If you have a variable called "vbt_size" it better include all of VBT, and not just
>part of it.
[Deepak M] Agreed, will fix this.
>
>
>BR,
>Jani.
>
>
>> +
>> dev_priv->bdb_start = bdb;
>> opregion->vbt = vbt_base;
>>
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>--
>Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread
* [MIPI SEQ PARSING v2 PATCH 05/11] drm/i915: Added support the v3 mipi sequence block
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (3 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 04/11] drm/i915: Using the approprite vbt size if vbt is not in mailbox4 of opregion Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-17 14:38 ` Jani Nikula
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 06/11] drm/i915: extending gpio read/write to other cores Deepak M
` (5 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
From: vkorjani <vikas.korjani@intel.com>
The Block 53 of the VBT, which is the MIPI sequence block
has undergone a design change because of which the parsing
logic has to be changed.
The current code will handle the parsing of v3 and other
lower versions of the MIPI sequence block.
v2: rebase
Signed-off-by: vkorjani <vikas.korjani@intel.com>
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/intel_bios.c | 119 +++++++++++++++++++++++-----
drivers/gpu/drm/i915/intel_bios.h | 8 ++
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 7 ++
3 files changed, 114 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 34a1042..cea641f 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -45,6 +45,7 @@ find_section(struct drm_i915_private *dev_priv,
int index = 0;
u32 total, current_size;
u8 current_id;
+ u8 version;
/* skip to first section */
index += bdb->header_size;
@@ -56,7 +57,17 @@ find_section(struct drm_i915_private *dev_priv,
current_id = *(base + index);
index++;
- current_size = *((const u16 *)(base + index));
+ if (current_id == BDB_MIPI_SEQUENCE) {
+ version = *(base + index + 2);
+ if (version >= 3)
+ current_size = *((const u32 *)(base +
+ index + 3));
+ else
+ current_size = *((const u16 *)(base + index));
+ } else {
+ current_size = *((const u16 *)(base + index));
+ }
+
index += 2;
if (index + current_size > total)
@@ -745,6 +756,55 @@ static u8 *goto_next_sequence(u8 *data, int *size)
return data;
}
+static u8 *goto_next_sequence_v3(u8 *data, int *size)
+{
+ int tmp = *size;
+ int op_size;
+
+ if (--tmp < 0)
+ return NULL;
+
+ /* Skip the panel id and the sequence size */
+ data = data + 5;
+ while (*data != 0) {
+ u8 element_type = *data++;
+
+ switch (element_type) {
+ default:
+ DRM_ERROR("Unknown element type %d\n", element_type);
+ case MIPI_SEQ_ELEM_SEND_PKT:
+ case MIPI_SEQ_ELEM_DELAY:
+ case MIPI_SEQ_ELEM_GPIO:
+ case MIPI_SEQ_ELEM_I2C:
+ case MIPI_SEQ_ELEM_SPI:
+ case MIPI_SEQ_ELEM_PMIC:
+ /*
+ * skip by this element payload size
+ * skip elem id, command flag and data type
+ */
+ op_size = *data++;
+ tmp = tmp - (op_size + 1);
+ if (tmp < 0)
+ return NULL;
+
+ /* skip by len */
+ data += op_size;
+ break;
+ }
+ }
+
+ /* goto next sequence or end of block byte */
+ if (--tmp < 0)
+ return NULL;
+
+ /* Skip the end element marker */
+ data++;
+
+ /* update amount of data left for the sequence block to be parsed */
+ *size = tmp;
+ return data;
+}
+
static void
parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
{
@@ -754,7 +814,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
const struct mipi_pps_data *pps;
u8 *data;
const u8 *seq_data;
- int i, panel_id, seq_size;
+ int i, panel_id, panel_seq_size;
u16 block_size;
/* parse MIPI blocks only if LFP type is MIPI */
@@ -811,29 +871,40 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
DRM_DEBUG_DRIVER("Found MIPI sequence block\n");
- block_size = get_blocksize(sequence);
-
/*
* parse the sequence block for individual sequences
*/
dev_priv->vbt.dsi.seq_version = sequence->version;
seq_data = &sequence->data[0];
+ if (dev_priv->vbt.dsi.seq_version >= 3) {
+ block_size = *((unsigned int *)seq_data);
+ seq_data = seq_data + 4;
+ } else
+ block_size = get_blocksize(sequence);
/*
* sequence block is variable length and hence we need to parse and
* get the sequence data for specific panel id
*/
for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) {
- panel_id = *seq_data;
- seq_size = *((u16 *) (seq_data + 1));
+ panel_id = *seq_data++;
+ if (dev_priv->vbt.dsi.seq_version >= 3) {
+ panel_seq_size = *((u32 *)seq_data);
+ seq_data += sizeof(u32);
+ } else {
+ panel_seq_size = *((u16 *)seq_data);
+ seq_data += sizeof(u16);
+ }
+
if (panel_id == panel_type)
break;
- /* skip the sequence including seq header of 3 bytes */
- seq_data = seq_data + 3 + seq_size;
+ seq_data += panel_seq_size;
+
if ((seq_data - &sequence->data[0]) > block_size) {
- DRM_ERROR("Sequence start is beyond sequence block size, corrupted sequence block\n");
+ DRM_ERROR("Sequence start is beyond seq block size\n");
+ DRM_ERROR("Corrupted sequence block\n");
return;
}
}
@@ -845,13 +916,14 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
/* check if found sequence is completely within the sequence block
* just being paranoid */
- if (seq_size > block_size) {
+ if (panel_seq_size > block_size) {
DRM_ERROR("Corrupted sequence/size, bailing out\n");
return;
}
- /* skip the panel id(1 byte) and seq size(2 bytes) */
- dev_priv->vbt.dsi.data = kmemdup(seq_data + 3, seq_size, GFP_KERNEL);
+
+ dev_priv->vbt.dsi.data = kmemdup(seq_data, panel_seq_size, GFP_KERNEL);
+
if (!dev_priv->vbt.dsi.data)
return;
@@ -860,29 +932,36 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
* There are only 5 types of sequences as of now
*/
data = dev_priv->vbt.dsi.data;
- dev_priv->vbt.dsi.size = seq_size;
+ dev_priv->vbt.dsi.size = panel_seq_size;
/* two consecutive 0x00 indicate end of all sequences */
- while (1) {
+ while (*data != 0) {
int seq_id = *data;
+ int seq_size;
+
if (MIPI_SEQ_MAX > seq_id && seq_id > MIPI_SEQ_UNDEFINED) {
dev_priv->vbt.dsi.sequence[seq_id] = data;
DRM_DEBUG_DRIVER("Found mipi sequence - %d\n", seq_id);
} else {
- DRM_ERROR("undefined sequence\n");
- goto err;
+ DRM_ERROR("undefined sequence - %d\n", seq_id);
+ seq_size = *(data + 1);
+ if (dev_priv->vbt.dsi.seq_version >= 3) {
+ data = data + seq_size + 1;
+ continue;
+ } else
+ goto err;
}
/* partial parsing to skip elements */
- data = goto_next_sequence(data, &seq_size);
+ if (dev_priv->vbt.dsi.seq_version >= 3)
+ data = goto_next_sequence_v3(data, &panel_seq_size);
+ else
+ data = goto_next_sequence(data, &panel_seq_size);
if (data == NULL) {
DRM_ERROR("Sequence elements going beyond block itself. Sequence block parsing failed\n");
goto err;
}
-
- if (*data == 0)
- break; /* end of sequence reached */
}
DRM_DEBUG_DRIVER("MIPI related vbt parsing complete\n");
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 21a7f3f..7a4ba41 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -948,6 +948,12 @@ enum mipi_seq {
MIPI_SEQ_DISPLAY_ON,
MIPI_SEQ_DISPLAY_OFF,
MIPI_SEQ_DEASSERT_RESET,
+ MIPI_SEQ_BACKLIGHT_ON,
+ MIPI_SEQ_BACKLIGHT_OFF,
+ MIPI_SEQ_TEAR_ON,
+ MIPI_SEQ_TEAR_OFF,
+ MIPI_SEQ_POWER_ON,
+ MIPI_SEQ_POWER_OFF,
MIPI_SEQ_MAX
};
@@ -957,6 +963,8 @@ enum mipi_seq_element {
MIPI_SEQ_ELEM_DELAY,
MIPI_SEQ_ELEM_GPIO,
MIPI_SEQ_ELEM_I2C,
+ MIPI_SEQ_ELEM_SPI,
+ MIPI_SEQ_ELEM_PMIC,
MIPI_SEQ_ELEM_STATUS,
MIPI_SEQ_ELEM_MAX
};
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 9989f61..c6a6fa1 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -317,6 +317,8 @@ static const char * const seq_name[] = {
static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
{
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
fn_mipi_elem_exec mipi_elem_exec;
int index;
@@ -327,6 +329,8 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
/* go to the first element of the sequence */
data++;
+ if (dev_priv->vbt.dsi.seq_version >= 3)
+ data = data + 4;
/* parse each byte till we reach end of sequence byte - 0x00 */
while (1) {
@@ -340,6 +344,9 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
/* goto element payload */
data++;
+ if (dev_priv->vbt.dsi.seq_version >= 3)
+ data++;
+
/* execute the element specific rotines */
data = mipi_elem_exec(intel_dsi, data);
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 05/11] drm/i915: Added support the v3 mipi sequence block
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 05/11] drm/i915: Added support the v3 mipi sequence block Deepak M
@ 2015-09-17 14:38 ` Jani Nikula
2015-09-22 6:23 ` Deepak, M
0 siblings, 1 reply; 25+ messages in thread
From: Jani Nikula @ 2015-09-17 14:38 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
> From: vkorjani <vikas.korjani@intel.com>
>
> The Block 53 of the VBT, which is the MIPI sequence block
> has undergone a design change because of which the parsing
> logic has to be changed.
>
> The current code will handle the parsing of v3 and other
> lower versions of the MIPI sequence block.
>
> v2: rebase
>
> Signed-off-by: vkorjani <vikas.korjani@intel.com>
> Signed-off-by: Deepak M <m.deepak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_bios.c | 119 +++++++++++++++++++++++-----
> drivers/gpu/drm/i915/intel_bios.h | 8 ++
> drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 7 ++
> 3 files changed, 114 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index 34a1042..cea641f 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -45,6 +45,7 @@ find_section(struct drm_i915_private *dev_priv,
> int index = 0;
> u32 total, current_size;
> u8 current_id;
> + u8 version;
>
> /* skip to first section */
> index += bdb->header_size;
> @@ -56,7 +57,17 @@ find_section(struct drm_i915_private *dev_priv,
> current_id = *(base + index);
> index++;
>
> - current_size = *((const u16 *)(base + index));
> + if (current_id == BDB_MIPI_SEQUENCE) {
> + version = *(base + index + 2);
> + if (version >= 3)
> + current_size = *((const u32 *)(base +
> + index + 3));
> + else
> + current_size = *((const u16 *)(base + index));
> + } else {
> + current_size = *((const u16 *)(base + index));
> + }
> +
While reviewing I've realized the old kernels will hit this hard. I've
submitted a patch [1] to be applied to v4.3-rc and older stable kernels
so that they fail gracefully instead of starting to parse garbage. The
real parsing is too big to backport to upstream stable. Please review.
[1] http://mid.gmane.org/1442497327-27033-1-git-send-email-jani.nikula@intel.com
> index += 2;
>
> if (index + current_size > total)
> @@ -745,6 +756,55 @@ static u8 *goto_next_sequence(u8 *data, int *size)
> return data;
> }
>
> +static u8 *goto_next_sequence_v3(u8 *data, int *size)
> +{
> + int tmp = *size;
> + int op_size;
> +
> + if (--tmp < 0)
> + return NULL;
> +
> + /* Skip the panel id and the sequence size */
It's not panel id, it's the sequence byte, right?
You could also store data + 1 + size of sequence, and check whether data
ends up pointing at the same place in the end. They should.
Shouldn't you also take 4 bytes of sequence size field into account in
tmp?
> + data = data + 5;
> + while (*data != 0) {
> + u8 element_type = *data++;
> +
> + switch (element_type) {
Would be helpful to refer to operation_byte like in the spec.
> + default:
> + DRM_ERROR("Unknown element type %d\n", element_type);
> + case MIPI_SEQ_ELEM_SEND_PKT:
> + case MIPI_SEQ_ELEM_DELAY:
> + case MIPI_SEQ_ELEM_GPIO:
> + case MIPI_SEQ_ELEM_I2C:
> + case MIPI_SEQ_ELEM_SPI:
> + case MIPI_SEQ_ELEM_PMIC:
> + /*
> + * skip by this element payload size
> + * skip elem id, command flag and data type
> + */
> + op_size = *data++;
> + tmp = tmp - (op_size + 1);
> + if (tmp < 0)
> + return NULL;
Isn't each operation operation byte | size of operation | payload size,
i.e. your tmp change is one byte short?
The fact that the goto_next_sequence* functions increase data and
decrease size is getting increasingly confusing to follow. One simple
alternative would be to calculate some endp = start + size up front, and
then pass the endp around, and check if we're about to go past the end
marker.
This is not a problem with your series, it was there already. And fixing
it doesn't have to be part of your series. It just really takes ages to
review this approach of range checking. Unless I close my eyes and trust
there are no off-by-ones anywhere. But that kind of defeats the purpose
of review...
> +
> + /* skip by len */
> + data += op_size;
> + break;
> + }
> + }
> +
> + /* goto next sequence or end of block byte */
> + if (--tmp < 0)
> + return NULL;
> +
> + /* Skip the end element marker */
> + data++;
> +
> + /* update amount of data left for the sequence block to be parsed */
> + *size = tmp;
> + return data;
> +}
> +
> static void
> parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
> {
> @@ -754,7 +814,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
> const struct mipi_pps_data *pps;
> u8 *data;
> const u8 *seq_data;
> - int i, panel_id, seq_size;
> + int i, panel_id, panel_seq_size;
> u16 block_size;
>
> /* parse MIPI blocks only if LFP type is MIPI */
> @@ -811,29 +871,40 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
>
> DRM_DEBUG_DRIVER("Found MIPI sequence block\n");
>
> - block_size = get_blocksize(sequence);
> -
> /*
> * parse the sequence block for individual sequences
> */
> dev_priv->vbt.dsi.seq_version = sequence->version;
>
> seq_data = &sequence->data[0];
> + if (dev_priv->vbt.dsi.seq_version >= 3) {
> + block_size = *((unsigned int *)seq_data);
(const u32 *)
> + seq_data = seq_data + 4;
> + } else
> + block_size = get_blocksize(sequence);
block_size should be changed to u32.
>
> /*
> * sequence block is variable length and hence we need to parse and
> * get the sequence data for specific panel id
> */
> for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) {
> - panel_id = *seq_data;
> - seq_size = *((u16 *) (seq_data + 1));
> + panel_id = *seq_data++;
> + if (dev_priv->vbt.dsi.seq_version >= 3) {
> + panel_seq_size = *((u32 *)seq_data);
> + seq_data += sizeof(u32);
> + } else {
> + panel_seq_size = *((u16 *)seq_data);
> + seq_data += sizeof(u16);
> + }
> +
> if (panel_id == panel_type)
> break;
>
> - /* skip the sequence including seq header of 3 bytes */
> - seq_data = seq_data + 3 + seq_size;
> + seq_data += panel_seq_size;
> +
> if ((seq_data - &sequence->data[0]) > block_size) {
> - DRM_ERROR("Sequence start is beyond sequence block size, corrupted sequence block\n");
> + DRM_ERROR("Sequence start is beyond seq block size\n");
> + DRM_ERROR("Corrupted sequence block\n");
Please don't add two consecutive DRM_ERRORs for the same error.
> return;
> }
> }
> @@ -845,13 +916,14 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
>
> /* check if found sequence is completely within the sequence block
> * just being paranoid */
> - if (seq_size > block_size) {
> + if (panel_seq_size > block_size) {
> DRM_ERROR("Corrupted sequence/size, bailing out\n");
> return;
> }
>
> - /* skip the panel id(1 byte) and seq size(2 bytes) */
> - dev_priv->vbt.dsi.data = kmemdup(seq_data + 3, seq_size, GFP_KERNEL);
> +
> + dev_priv->vbt.dsi.data = kmemdup(seq_data, panel_seq_size, GFP_KERNEL);
> +
> if (!dev_priv->vbt.dsi.data)
> return;
>
> @@ -860,29 +932,36 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
> * There are only 5 types of sequences as of now
> */
> data = dev_priv->vbt.dsi.data;
> - dev_priv->vbt.dsi.size = seq_size;
> + dev_priv->vbt.dsi.size = panel_seq_size;
>
> /* two consecutive 0x00 indicate end of all sequences */
> - while (1) {
> + while (*data != 0) {
> int seq_id = *data;
> + int seq_size;
u32
> +
> if (MIPI_SEQ_MAX > seq_id && seq_id > MIPI_SEQ_UNDEFINED) {
> dev_priv->vbt.dsi.sequence[seq_id] = data;
> DRM_DEBUG_DRIVER("Found mipi sequence - %d\n", seq_id);
> } else {
> - DRM_ERROR("undefined sequence\n");
> - goto err;
> + DRM_ERROR("undefined sequence - %d\n", seq_id);
> + seq_size = *(data + 1);
Needs to be *((const u32 *)(data + 1)) or you'll ignore 3 highest order
bytes.
> + if (dev_priv->vbt.dsi.seq_version >= 3) {
> + data = data + seq_size + 1;
> + continue;
> + } else
> + goto err;
> }
>
> /* partial parsing to skip elements */
> - data = goto_next_sequence(data, &seq_size);
> + if (dev_priv->vbt.dsi.seq_version >= 3)
> + data = goto_next_sequence_v3(data, &panel_seq_size);
> + else
> + data = goto_next_sequence(data, &panel_seq_size);
>
> if (data == NULL) {
> DRM_ERROR("Sequence elements going beyond block itself. Sequence block parsing failed\n");
> goto err;
> }
> -
> - if (*data == 0)
> - break; /* end of sequence reached */
> }
>
> DRM_DEBUG_DRIVER("MIPI related vbt parsing complete\n");
> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
> index 21a7f3f..7a4ba41 100644
> --- a/drivers/gpu/drm/i915/intel_bios.h
> +++ b/drivers/gpu/drm/i915/intel_bios.h
> @@ -948,6 +948,12 @@ enum mipi_seq {
> MIPI_SEQ_DISPLAY_ON,
> MIPI_SEQ_DISPLAY_OFF,
> MIPI_SEQ_DEASSERT_RESET,
> + MIPI_SEQ_BACKLIGHT_ON,
> + MIPI_SEQ_BACKLIGHT_OFF,
> + MIPI_SEQ_TEAR_ON,
> + MIPI_SEQ_TEAR_OFF,
> + MIPI_SEQ_POWER_ON,
> + MIPI_SEQ_POWER_OFF,
> MIPI_SEQ_MAX
> };
>
> @@ -957,6 +963,8 @@ enum mipi_seq_element {
> MIPI_SEQ_ELEM_DELAY,
> MIPI_SEQ_ELEM_GPIO,
> MIPI_SEQ_ELEM_I2C,
> + MIPI_SEQ_ELEM_SPI,
> + MIPI_SEQ_ELEM_PMIC,
> MIPI_SEQ_ELEM_STATUS,
Again, MIPI_SEQ_ELEM_STATUS is not spec.
> MIPI_SEQ_ELEM_MAX
> };
> diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> index 9989f61..c6a6fa1 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> @@ -317,6 +317,8 @@ static const char * const seq_name[] = {
>
> static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
> {
> + struct drm_device *dev = intel_dsi->base.base.dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> fn_mipi_elem_exec mipi_elem_exec;
> int index;
>
> @@ -327,6 +329,8 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
>
> /* go to the first element of the sequence */
> data++;
> + if (dev_priv->vbt.dsi.seq_version >= 3)
> + data = data + 4;
>
> /* parse each byte till we reach end of sequence byte - 0x00 */
> while (1) {
> @@ -340,6 +344,9 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
> /* goto element payload */
> data++;
>
> + if (dev_priv->vbt.dsi.seq_version >= 3)
> + data++;
> +
> /* execute the element specific rotines */
> data = mipi_elem_exec(intel_dsi, data);
>
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 05/11] drm/i915: Added support the v3 mipi sequence block
2015-09-17 14:38 ` Jani Nikula
@ 2015-09-22 6:23 ` Deepak, M
0 siblings, 0 replies; 25+ messages in thread
From: Deepak, M @ 2015-09-22 6:23 UTC (permalink / raw)
To: Jani Nikula, intel-gfx@lists.freedesktop.org
>-----Original Message-----
>From: Jani Nikula [mailto:jani.nikula@linux.intel.com]
>Sent: Thursday, September 17, 2015 8:09 PM
>To: Deepak, M; intel-gfx@lists.freedesktop.org
>Cc: Deepak, M
>Subject: Re: [Intel-gfx] [MIPI SEQ PARSING v2 PATCH 05/11] drm/i915: Added
>support the v3 mipi sequence block
>
>On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
>> From: vkorjani <vikas.korjani@intel.com>
>>
>> The Block 53 of the VBT, which is the MIPI sequence block has
>> undergone a design change because of which the parsing logic has to be
>> changed.
>>
>> The current code will handle the parsing of v3 and other lower
>> versions of the MIPI sequence block.
>>
>> v2: rebase
>>
>> Signed-off-by: vkorjani <vikas.korjani@intel.com>
>> Signed-off-by: Deepak M <m.deepak@intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_bios.c | 119
>+++++++++++++++++++++++-----
>> drivers/gpu/drm/i915/intel_bios.h | 8 ++
>> drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 7 ++
>> 3 files changed, 114 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_bios.c
>> b/drivers/gpu/drm/i915/intel_bios.c
>> index 34a1042..cea641f 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.c
>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>> @@ -45,6 +45,7 @@ find_section(struct drm_i915_private *dev_priv,
>> int index = 0;
>> u32 total, current_size;
>> u8 current_id;
>> + u8 version;
>>
>> /* skip to first section */
>> index += bdb->header_size;
>> @@ -56,7 +57,17 @@ find_section(struct drm_i915_private *dev_priv,
>> current_id = *(base + index);
>> index++;
>>
>> - current_size = *((const u16 *)(base + index));
>> + if (current_id == BDB_MIPI_SEQUENCE) {
>> + version = *(base + index + 2);
>> + if (version >= 3)
>> + current_size = *((const u32 *)(base +
>> + index + 3));
>> + else
>> + current_size = *((const u16 *)(base + index));
>> + } else {
>> + current_size = *((const u16 *)(base + index));
>> + }
>> +
>
>While reviewing I've realized the old kernels will hit this hard. I've submitted a
>patch [1] to be applied to v4.3-rc and older stable kernels so that they fail
>gracefully instead of starting to parse garbage. The real parsing is too big to
>backport to upstream stable. Please review.
>
>[1] http://mid.gmane.org/1442497327-27033-1-git-send-email-
>jani.nikula@intel.com
>
>> index += 2;
>>
>> if (index + current_size > total)
>> @@ -745,6 +756,55 @@ static u8 *goto_next_sequence(u8 *data, int *size)
>> return data;
>> }
>>
>> +static u8 *goto_next_sequence_v3(u8 *data, int *size) {
>> + int tmp = *size;
>> + int op_size;
>> +
>> + if (--tmp < 0)
>> + return NULL;
>> +
>> + /* Skip the panel id and the sequence size */
>
>It's not panel id, it's the sequence byte, right?
>
>You could also store data + 1 + size of sequence, and check whether data ends
>up pointing at the same place in the end. They should.
>
>Shouldn't you also take 4 bytes of sequence size field into account in tmp?
>
>> + data = data + 5;
>> + while (*data != 0) {
>> + u8 element_type = *data++;
>> +
>> + switch (element_type) {
>
>Would be helpful to refer to operation_byte like in the spec.
>
>> + default:
>> + DRM_ERROR("Unknown element type %d\n",
>element_type);
>> + case MIPI_SEQ_ELEM_SEND_PKT:
>> + case MIPI_SEQ_ELEM_DELAY:
>> + case MIPI_SEQ_ELEM_GPIO:
>> + case MIPI_SEQ_ELEM_I2C:
>> + case MIPI_SEQ_ELEM_SPI:
>> + case MIPI_SEQ_ELEM_PMIC:
>> + /*
>> + * skip by this element payload size
>> + * skip elem id, command flag and data type
>> + */
>> + op_size = *data++;
>> + tmp = tmp - (op_size + 1);
>> + if (tmp < 0)
>> + return NULL;
>
>Isn't each operation operation byte | size of operation | payload size, i.e. your
>tmp change is one byte short?
>
>The fact that the goto_next_sequence* functions increase data and decrease
>size is getting increasingly confusing to follow. One simple alternative would
>be to calculate some endp = start + size up front, and then pass the endp
>around, and check if we're about to go past the end marker.
>
>This is not a problem with your series, it was there already. And fixing it
>doesn't have to be part of your series. It just really takes ages to review this
>approach of range checking. Unless I close my eyes and trust there are no off-
>by-ones anywhere. But that kind of defeats the purpose of review...
>
[Deepak M] Okay will try to simplify the logic.
>> +
>> + /* skip by len */
>> + data += op_size;
>> + break;
>> + }
>> + }
>> +
>> + /* goto next sequence or end of block byte */
>> + if (--tmp < 0)
>> + return NULL;
>> +
>> + /* Skip the end element marker */
>> + data++;
>> +
>> + /* update amount of data left for the sequence block to be parsed */
>> + *size = tmp;
>> + return data;
>> +}
>> +
>> static void
>> parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header
>> *bdb) { @@ -754,7 +814,7 @@ parse_mipi(struct drm_i915_private
>> *dev_priv, const struct bdb_header *bdb)
>> const struct mipi_pps_data *pps;
>> u8 *data;
>> const u8 *seq_data;
>> - int i, panel_id, seq_size;
>> + int i, panel_id, panel_seq_size;
>> u16 block_size;
>>
>> /* parse MIPI blocks only if LFP type is MIPI */ @@ -811,29 +871,40
>> @@ parse_mipi(struct drm_i915_private *dev_priv, const struct
>> bdb_header *bdb)
>>
>> DRM_DEBUG_DRIVER("Found MIPI sequence block\n");
>>
>> - block_size = get_blocksize(sequence);
>> -
>> /*
>> * parse the sequence block for individual sequences
>> */
>> dev_priv->vbt.dsi.seq_version = sequence->version;
>>
>> seq_data = &sequence->data[0];
>> + if (dev_priv->vbt.dsi.seq_version >= 3) {
>> + block_size = *((unsigned int *)seq_data);
>
>(const u32 *)
>
>> + seq_data = seq_data + 4;
>> + } else
>> + block_size = get_blocksize(sequence);
>
>block_size should be changed to u32.
>
>>
>> /*
>> * sequence block is variable length and hence we need to parse and
>> * get the sequence data for specific panel id
>> */
>> for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) {
>> - panel_id = *seq_data;
>> - seq_size = *((u16 *) (seq_data + 1));
>> + panel_id = *seq_data++;
>> + if (dev_priv->vbt.dsi.seq_version >= 3) {
>> + panel_seq_size = *((u32 *)seq_data);
>> + seq_data += sizeof(u32);
>> + } else {
>> + panel_seq_size = *((u16 *)seq_data);
>> + seq_data += sizeof(u16);
>> + }
>> +
>> if (panel_id == panel_type)
>> break;
>>
>> - /* skip the sequence including seq header of 3 bytes */
>> - seq_data = seq_data + 3 + seq_size;
>> + seq_data += panel_seq_size;
>> +
>> if ((seq_data - &sequence->data[0]) > block_size) {
>> - DRM_ERROR("Sequence start is beyond sequence
>block size, corrupted sequence block\n");
>> + DRM_ERROR("Sequence start is beyond seq block
>size\n");
>> + DRM_ERROR("Corrupted sequence block\n");
>
>Please don't add two consecutive DRM_ERRORs for the same error.
>
>> return;
>> }
>> }
>> @@ -845,13 +916,14 @@ parse_mipi(struct drm_i915_private *dev_priv,
>> const struct bdb_header *bdb)
>>
>> /* check if found sequence is completely within the sequence block
>> * just being paranoid */
>> - if (seq_size > block_size) {
>> + if (panel_seq_size > block_size) {
>> DRM_ERROR("Corrupted sequence/size, bailing out\n");
>> return;
>> }
>>
>> - /* skip the panel id(1 byte) and seq size(2 bytes) */
>> - dev_priv->vbt.dsi.data = kmemdup(seq_data + 3, seq_size,
>GFP_KERNEL);
>> +
>> + dev_priv->vbt.dsi.data = kmemdup(seq_data, panel_seq_size,
>> +GFP_KERNEL);
>> +
>> if (!dev_priv->vbt.dsi.data)
>> return;
>>
>> @@ -860,29 +932,36 @@ parse_mipi(struct drm_i915_private *dev_priv,
>const struct bdb_header *bdb)
>> * There are only 5 types of sequences as of now
>> */
>> data = dev_priv->vbt.dsi.data;
>> - dev_priv->vbt.dsi.size = seq_size;
>> + dev_priv->vbt.dsi.size = panel_seq_size;
>>
>> /* two consecutive 0x00 indicate end of all sequences */
>> - while (1) {
>> + while (*data != 0) {
>> int seq_id = *data;
>> + int seq_size;
>
>u32
>
>> +
>> if (MIPI_SEQ_MAX > seq_id && seq_id >
>MIPI_SEQ_UNDEFINED) {
>> dev_priv->vbt.dsi.sequence[seq_id] = data;
>> DRM_DEBUG_DRIVER("Found mipi sequence - %d\n",
>seq_id);
>> } else {
>> - DRM_ERROR("undefined sequence\n");
>> - goto err;
>> + DRM_ERROR("undefined sequence - %d\n", seq_id);
>> + seq_size = *(data + 1);
>
>Needs to be *((const u32 *)(data + 1)) or you'll ignore 3 highest order bytes.
>
>> + if (dev_priv->vbt.dsi.seq_version >= 3) {
>> + data = data + seq_size + 1;
>> + continue;
>> + } else
>> + goto err;
>> }
>>
>> /* partial parsing to skip elements */
>> - data = goto_next_sequence(data, &seq_size);
>> + if (dev_priv->vbt.dsi.seq_version >= 3)
>> + data = goto_next_sequence_v3(data,
>&panel_seq_size);
>> + else
>> + data = goto_next_sequence(data, &panel_seq_size);
>>
>> if (data == NULL) {
>> DRM_ERROR("Sequence elements going beyond
>block itself. Sequence block parsing failed\n");
>> goto err;
>> }
>> -
>> - if (*data == 0)
>> - break; /* end of sequence reached */
>> }
>>
>> DRM_DEBUG_DRIVER("MIPI related vbt parsing complete\n"); diff --
>git
>> a/drivers/gpu/drm/i915/intel_bios.h
>> b/drivers/gpu/drm/i915/intel_bios.h
>> index 21a7f3f..7a4ba41 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.h
>> +++ b/drivers/gpu/drm/i915/intel_bios.h
>> @@ -948,6 +948,12 @@ enum mipi_seq {
>> MIPI_SEQ_DISPLAY_ON,
>> MIPI_SEQ_DISPLAY_OFF,
>> MIPI_SEQ_DEASSERT_RESET,
>> + MIPI_SEQ_BACKLIGHT_ON,
>> + MIPI_SEQ_BACKLIGHT_OFF,
>> + MIPI_SEQ_TEAR_ON,
>> + MIPI_SEQ_TEAR_OFF,
>> + MIPI_SEQ_POWER_ON,
>> + MIPI_SEQ_POWER_OFF,
>> MIPI_SEQ_MAX
>> };
>>
>> @@ -957,6 +963,8 @@ enum mipi_seq_element {
>> MIPI_SEQ_ELEM_DELAY,
>> MIPI_SEQ_ELEM_GPIO,
>> MIPI_SEQ_ELEM_I2C,
>> + MIPI_SEQ_ELEM_SPI,
>> + MIPI_SEQ_ELEM_PMIC,
>> MIPI_SEQ_ELEM_STATUS,
>
>Again, MIPI_SEQ_ELEM_STATUS is not spec.
>
>> MIPI_SEQ_ELEM_MAX
>> };
>> diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> index 9989f61..c6a6fa1 100644
>> --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
>> @@ -317,6 +317,8 @@ static const char * const seq_name[] = {
>>
>> static void generic_exec_sequence(struct intel_dsi *intel_dsi, const
>> u8 *data) {
>> + struct drm_device *dev = intel_dsi->base.base.dev;
>> + struct drm_i915_private *dev_priv = dev->dev_private;
>> fn_mipi_elem_exec mipi_elem_exec;
>> int index;
>>
>> @@ -327,6 +329,8 @@ static void generic_exec_sequence(struct intel_dsi
>> *intel_dsi, const u8 *data)
>>
>> /* go to the first element of the sequence */
>> data++;
>> + if (dev_priv->vbt.dsi.seq_version >= 3)
>> + data = data + 4;
>>
>> /* parse each byte till we reach end of sequence byte - 0x00 */
>> while (1) {
>> @@ -340,6 +344,9 @@ static void generic_exec_sequence(struct intel_dsi
>*intel_dsi, const u8 *data)
>> /* goto element payload */
>> data++;
>>
>> + if (dev_priv->vbt.dsi.seq_version >= 3)
>> + data++;
>> +
>> /* execute the element specific rotines */
>> data = mipi_elem_exec(intel_dsi, data);
>>
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>--
>Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread
* [MIPI SEQ PARSING v2 PATCH 06/11] drm/i915: extending gpio read/write to other cores
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (4 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 05/11] drm/i915: Added support the v3 mipi sequence block Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 07/11] drm/i915: Added the generic gpio sequence support and gpio table Deepak M
` (4 subsequent siblings)
10 siblings, 0 replies; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
Adding a argument to the gpio read/write functions
which accepts the block name.
v2: rebase
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 5 +++--
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 4 ++--
drivers/gpu/drm/i915/intel_sideband.c | 9 +++++----
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 91ccbc6..ed3b19b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3363,8 +3363,9 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
-u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+u32 vlv_gpio_read(struct drm_i915_private *dev_priv, u8 core_offset, u32 reg);
+void vlv_gpio_write(struct drm_i915_private *dev_priv, u8 core_offset,
+ u32 reg, u32 val);
u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index c6a6fa1..02f1cd5 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -276,14 +276,14 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
if (!gtable[gpio].init) {
/* program the function */
/* FIXME: remove constant below */
- vlv_gpio_nc_write(dev_priv, function, 0x2000CC00);
+ vlv_gpio_write(dev_priv, IOSF_PORT_GPIO_NC, function, 0x2000CC00);
gtable[gpio].init = 1;
}
val = 0x4 | action;
/* pull up/down */
- vlv_gpio_nc_write(dev_priv, pad, val);
+ vlv_gpio_write(dev_priv, IOSF_PORT_GPIO_NC, pad, val);
mutex_unlock(&dev_priv->sb_lock);
return data;
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 8831fc5..3e0cbe6 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -129,17 +129,18 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
return val;
}
-u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg)
+u32 vlv_gpio_read(struct drm_i915_private *dev_priv, u8 core_offset, u32 reg)
{
u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), core_offset,
SB_CRRDDA_NP, reg, &val);
return val;
}
-void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+void vlv_gpio_write(struct drm_i915_private *dev_priv, u8 core_offset,
+ u32 reg, u32 val)
{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), core_offset,
SB_CRWRDA_NP, reg, &val);
}
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* [MIPI SEQ PARSING v2 PATCH 07/11] drm/i915: Added the generic gpio sequence support and gpio table
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (5 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 06/11] drm/i915: extending gpio read/write to other cores Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-17 14:44 ` Jani Nikula
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 08/11] drm/i915: GPIO for CHT generic MIPI Deepak M
` (3 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
The generic gpio is sequence is parsed from the VBT and the
GPIO table is updated with the North core, South core and
SUS core elements.
v2: Move changes in sideband.c file to new patch(Jani), rebase
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 5 +
drivers/gpu/drm/i915/intel_dsi.h | 351 ++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 215 ++++++++++++++++-
3 files changed, 559 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 84ed9ab..5bef50c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -568,6 +568,11 @@
#define IOSF_PORT_DPIO 0x12
#define IOSF_PORT_DPIO_2 0x1a
#define IOSF_PORT_GPIO_NC 0x13
+#define IOSF_PORT_GPIO_SC 0x48
+#define IOSF_PORT_GPIO_SUS 0xA8
+#define MAX_GPIO_NUM_NC 26
+#define MAX_GPIO_NUM_SC 128
+#define MAX_GPIO_NUM 172
#define IOSF_PORT_CCK 0x14
#define IOSF_PORT_CCU 0xA9
#define IOSF_PORT_GPS_CORE 0x48
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 42a6859..fc89a6b 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -34,6 +34,357 @@
#define DSI_DUAL_LINK_FRONT_BACK 1
#define DSI_DUAL_LINK_PIXEL_ALT 2
+#define HV_DDI0_HPD_GPIONC_0_PCONF0 0x4130
+#define HV_DDI0_HPD_GPIONC_0_PAD 0x4138
+#define HV_DDI0_DDC_SDA_GPIONC_1_PCONF0 0x4120
+#define HV_DDI0_DDC_SDA_GPIONC_1_PAD 0x4128
+#define HV_DDI0_DDC_SCL_GPIONC_2_PCONF0 0x4110
+#define HV_DDI0_DDC_SCL_GPIONC_2_PAD 0x4118
+#define PANEL0_VDDEN_GPIONC_3_PCONF0 0x4140
+#define PANEL0_VDDEN_GPIONC_3_PAD 0x4148
+#define PANEL0_BKLTEN_GPIONC_4_PCONF0 0x4150
+#define PANEL0_BKLTEN_GPIONC_4_PAD 0x4158
+#define PANEL0_BKLTCTL_GPIONC_5_PCONF0 0x4160
+#define PANEL0_BKLTCTL_GPIONC_5_PAD 0x4168
+#define HV_DDI1_HPD_GPIONC_6_PCONF0 0x4180
+#define HV_DDI1_HPD_GPIONC_6_PAD 0x4188
+#define HV_DDI1_DDC_SDA_GPIONC_7_PCONF0 0x4190
+#define HV_DDI1_DDC_SDA_GPIONC_7_PAD 0x4198
+#define HV_DDI1_DDC_SCL_GPIONC_8_PCONF0 0x4170
+#define HV_DDI1_DDC_SCL_GPIONC_8_PAD 0x4178
+#define PANEL1_VDDEN_GPIONC_9_PCONF0 0x4100
+#define PANEL1_VDDEN_GPIONC_9_PAD 0x4108
+#define PANEL1_BKLTEN_GPIONC_10_PCONF0 0x40E0
+#define PANEL1_BKLTEN_GPIONC_10_PAD 0x40E8
+#define PANEL1_BKLTCTL_GPIONC_11_PCONF0 0x40F0
+#define PANEL1_BKLTCTL_GPIONC_11_PAD 0x40F8
+#define GP_INTD_DSI_TE1_GPIONC_12_PCONF0 0x40C0
+#define GP_INTD_DSI_TE1_GPIONC_12_PAD 0x40C8
+#define HV_DDI2_DDC_SDA_GPIONC_13_PCONF0 0x41A0
+#define HV_DDI2_DDC_SDA_GPIONC_13_PAD 0x41A8
+#define HV_DDI2_DDC_SCL_GPIONC_14_PCONF0 0x41B0
+#define HV_DDI2_DDC_SCL_GPIONC_14_PAD 0x41B8
+#define GP_CAMERASB00_GPIONC_15_PCONF0 0x4010
+#define GP_CAMERASB00_GPIONC_15_PAD 0x4018
+#define GP_CAMERASB01_GPIONC_16_PCONF0 0x4040
+#define GP_CAMERASB01_GPIONC_16_PAD 0x4048
+#define GP_CAMERASB02_GPIONC_17_PCONF0 0x4080
+#define GP_CAMERASB02_GPIONC_17_PAD 0x4088
+#define GP_CAMERASB03_GPIONC_18_PCONF0 0x40B0
+#define GP_CAMERASB03_GPIONC_18_PAD 0x40B8
+#define GP_CAMERASB04_GPIONC_19_PCONF0 0x4000
+#define GP_CAMERASB04_GPIONC_19_PAD 0x4008
+#define GP_CAMERASB05_GPIONC_20_PCONF0 0x4030
+#define GP_CAMERASB05_GPIONC_20_PAD 0x4038
+#define GP_CAMERASB06_GPIONC_21_PCONF0 0x4060
+#define GP_CAMERASB06_GPIONC_21_PAD 0x4068
+#define GP_CAMERASB07_GPIONC_22_PCONF0 0x40A0
+#define GP_CAMERASB07_GPIONC_22_PAD 0x40A8
+#define GP_CAMERASB08_GPIONC_23_PCONF0 0x40D0
+#define GP_CAMERASB08_GPIONC_23_PAD 0x40D8
+#define GP_CAMERASB09_GPIONC_24_PCONF0 0x4020
+#define GP_CAMERASB09_GPIONC_24_PAD 0x4028
+#define GP_CAMERASB10_GPIONC_25_PCONF0 0x4050
+#define GP_CAMERASB10_GPIONC_25_PAD 0x4058
+#define GP_CAMERASB11_GPIONC_26_PCONF0 0x4090
+#define GP_CAMERASB11_GPIONC_26_PAD 0x4098
+
+#define SATA_GP0_GPIOC_0_PCONF0 0x4550
+#define SATA_GP0_GPIOC_0_PAD 0x4558
+#define SATA_GP1_GPIOC_1_PCONF0 0x4590
+#define SATA_GP1_GPIOC_1_PAD 0x4598
+#define SATA_LEDN_GPIOC_2_PCONF0 0x45D0
+#define SATA_LEDN_GPIOC_2_PAD 0x45D8
+#define PCIE_CLKREQ0B_GPIOC_3_PCONF0 0x4600
+#define PCIE_CLKREQ0B_GPIOC_3_PAD 0x4608
+#define PCIE_CLKREQ1B_GPIOC_4_PCONF0 0x4630
+#define PCIE_CLKREQ1B_GPIOC_4_PAD 0x4638
+#define PCIE_CLKREQ2B_GPIOC_5_PCONF0 0x4660
+#define PCIE_CLKREQ2B_GPIOC_5_PAD 0x4668
+#define PCIE_CLKREQ3B_GPIOC_6_PCONF0 0x4620
+#define PCIE_CLKREQ3B_GPIOC_6_PAD 0x4628
+#define PCIE_CLKREQ4B_GPIOC_7_PCONF0 0x4650
+#define PCIE_CLKREQ4B_GPIOC_7_PAD 0x4658
+#define HDA_RSTB_GPIOC_8_PCONF0 0x4220
+#define HDA_RSTB_GPIOC_8_PAD 0x4228
+#define HDA_SYNC_GPIOC_9_PCONF0 0x4250
+#define HDA_SYNC_GPIOC_9_PAD 0x4258
+#define HDA_CLK_GPIOC_10_PCONF0 0x4240
+#define HDA_CLK_GPIOC_10_PAD 0x4248
+#define HDA_SDO_GPIOC_11_PCONF0 0x4260
+#define HDA_SDO_GPIOC_11_PAD 0x4268
+#define HDA_SDI0_GPIOC_12_PCONF0 0x4270
+#define HDA_SDI0_GPIOC_12_PAD 0x4278
+#define HDA_SDI1_GPIOC_13_PCONF0 0x4230
+#define HDA_SDI1_GPIOC_13_PAD 0x4238
+#define HDA_DOCKRSTB_GPIOC_14_PCONF0 0x4280
+#define HDA_DOCKRSTB_GPIOC_14_PAD 0x4288
+#define HDA_DOCKENB_GPIOC_15_PCONF0 0x4540
+#define HDA_DOCKENB_GPIOC_15_PAD 0x4548
+#define SDMMC1_CLK_GPIOC_16_PCONF0 0x43E0
+#define SDMMC1_CLK_GPIOC_16_PAD 0x43E8
+#define SDMMC1_D0_GPIOC_17_PCONF0 0x43D0
+#define SDMMC1_D0_GPIOC_17_PAD 0x43D8
+#define SDMMC1_D1_GPIOC_18_PCONF0 0x4400
+#define SDMMC1_D1_GPIOC_18_PAD 0x4408
+#define SDMMC1_D2_GPIOC_19_PCONF0 0x43B0
+#define SDMMC1_D2_GPIOC_19_PAD 0x43B8
+#define SDMMC1_D3_CD_B_GPIOC_20_PCONF0 0x4360
+#define SDMMC1_D3_CD_B_GPIOC_20_PAD 0x4368
+#define MMC1_D4_SD_WE_GPIOC_21_PCONF0 0x4380
+#define MMC1_D4_SD_WE_GPIOC_21_PAD 0x4388
+#define MMC1_D5_GPIOC_22_PCONF0 0x43C0
+#define MMC1_D5_GPIOC_22_PAD 0x43C8
+#define MMC1_D6_GPIOC_23_PCONF0 0x4370
+#define MMC1_D6_GPIOC_23_PAD 0x4378
+#define MMC1_D7_GPIOC_24_PCONF0 0x43F0
+#define MMC1_D7_GPIOC_24_PAD 0x43F8
+#define SDMMC1_CMD_GPIOC_25_PCONF0 0x4390
+#define SDMMC1_CMD_GPIOC_25_PAD 0x4398
+#define MMC1_RESET_B_GPIOC_26_PCONF0 0x4330
+#define MMC1_RESET_B_GPIOC_26_PAD 0x4338
+#define SDMMC2_CLK_GPIOC_27_PCONF0 0x4320
+#define SDMMC2_CLK_GPIOC_27_PAD 0x4328
+#define SDMMC2_D0_GPIOC_28_PCONF0 0x4350
+#define SDMMC2_D0_GPIOC_28_PAD 0x4358
+#define SDMMC2_D1_GPIOC_29_PCONF0 0x42F0
+#define SDMMC2_D1_GPIOC_29_PAD 0x42F8
+#define SDMMC2_D2_GPIOC_30_PCONF0 0x4340
+#define SDMMC2_D2_GPIOC_30_PAD 0x4348
+#define SDMMC2_D3_CD_B_GPIOC_31_PCONF0 0x4310
+#define SDMMC2_D3_CD_B_GPIOC_31_PAD 0x4318
+#define SDMMC2_CMD_GPIOC_32_PCONF0 0x4300
+#define SDMMC2_CMD_GPIOC_32_PAD 0x4308
+#define SDMMC3_CLK_GPIOC_33_PCONF0 0x42B0
+#define SDMMC3_CLK_GPIOC_33_PAD 0x42B8
+#define SDMMC3_D0_GPIOC_34_PCONF0 0x42E0
+#define SDMMC3_D0_GPIOC_34_PAD 0x42E8
+#define SDMMC3_D1_GPIOC_35_PCONF0 0x4290
+#define SDMMC3_D1_GPIOC_35_PAD 0x4298
+#define SDMMC3_D2_GPIOC_36_PCONF0 0x42D0
+#define SDMMC3_D2_GPIOC_36_PAD 0x42D8
+#define SDMMC3_D3_GPIOC_37_PCONF0 0x42A0
+#define SDMMC3_D3_GPIOC_37_PAD 0x42A8
+#define SDMMC3_CD_B_GPIOC_38_PCONF0 0x43A0
+#define SDMMC3_CD_B_GPIOC_38_PAD 0x43A8
+#define SDMMC3_CMD_GPIOC_39_PCONF0 0x42C0
+#define SDMMC3_CMD_GPIOC_39_PAD 0x42C8
+#define SDMMC3_1P8_EN_GPIOC_40_PCONF0 0x45F0
+#define SDMMC3_1P8_EN_GPIOC_40_PAD 0x45F8
+#define SDMMC3_PWR_EN_B_GPIOC_41_PCONF0 0x4690
+#define SDMMC3_PWR_EN_B_GPIOC_41_PAD 0x4698
+#define LPC_AD0_GPIOC_42_PCONF0 0x4460
+#define LPC_AD0_GPIOC_42_PAD 0x4468
+#define LPC_AD1_GPIOC_43_PCONF0 0x4440
+#define LPC_AD1_GPIOC_43_PAD 0x4448
+#define LPC_AD2_GPIOC_44_PCONF0 0x4430
+#define LPC_AD2_GPIOC_44_PAD 0x4438
+#define LPC_AD3_GPIOC_45_PCONF0 0x4420
+#define LPC_AD3_GPIOC_45_PAD 0x4428
+#define LPC_FRAMEB_GPIOC_46_PCONF0 0x4450
+#define LPC_FRAMEB_GPIOC_46_PAD 0x4458
+#define LPC_CLKOUT0_GPIOC_47_PCONF0 0x4470
+#define LPC_CLKOUT0_GPIOC_47_PAD 0x4478
+#define LPC_CLKOUT1_GPIOC_48_PCONF0 0x4410
+#define LPC_CLKOUT1_GPIOC_48_PAD 0x4418
+#define LPC_CLKRUNB_GPIOC_49_PCONF0 0x4480
+#define LPC_CLKRUNB_GPIOC_49_PAD 0x4488
+#define ILB_SERIRQ_GPIOC_50_PCONF0 0x4560
+#define ILB_SERIRQ_GPIOC_50_PAD 0x4568
+#define SMB_DATA_GPIOC_51_PCONF0 0x45A0
+#define SMB_DATA_GPIOC_51_PAD 0x45A8
+#define SMB_CLK_GPIOC_52_PCONF0 0x4580
+#define SMB_CLK_GPIOC_52_PAD 0x4588
+#define SMB_ALERTB_GPIOC_53_PCONF0 0x45C0
+#define SMB_ALERTB_GPIOC_53_PAD 0x45C8
+#define SPKR_GPIOC_54_PCONF0 0x4670
+#define SPKR_GPIOC_54_PAD 0x4678
+#define MHSI_ACDATA_GPIOC_55_PCONF0 0x44D0
+#define MHSI_ACDATA_GPIOC_55_PAD 0x44D8
+#define MHSI_ACFLAG_GPIOC_56_PCONF0 0x44F0
+#define MHSI_ACFLAG_GPIOC_56_PAD 0x44F8
+#define MHSI_ACREADY_GPIOC_57_PCONF0 0x4530
+#define MHSI_ACREADY_GPIOC_57_PAD 0x4538
+#define MHSI_ACWAKE_GPIOC_58_PCONF0 0x44E0
+#define MHSI_ACWAKE_GPIOC_58_PAD 0x44E8
+#define MHSI_CADATA_GPIOC_59_PCONF0 0x4510
+#define MHSI_CADATA_GPIOC_59_PAD 0x4518
+#define MHSI_CAFLAG_GPIOC_60_PCONF0 0x4500
+#define MHSI_CAFLAG_GPIOC_60_PAD 0x4508
+#define MHSI_CAREADY_GPIOC_61_PCONF0 0x4520
+#define MHSI_CAREADY_GPIOC_61_PAD 0x4528
+#define GP_SSP_2_CLK_GPIOC_62_PCONF0 0x40D0
+#define GP_SSP_2_CLK_GPIOC_62_PAD 0x40D8
+#define GP_SSP_2_FS_GPIOC_63_PCONF0 0x40C0
+#define GP_SSP_2_FS_GPIOC_63_PAD 0x40C8
+#define GP_SSP_2_RXD_GPIOC_64_PCONF0 0x40F0
+#define GP_SSP_2_RXD_GPIOC_64_PAD 0x40F8
+#define GP_SSP_2_TXD_GPIOC_65_PCONF0 0x40E0
+#define GP_SSP_2_TXD_GPIOC_65_PAD 0x40E8
+#define SPI1_CS0_B_GPIOC_66_PCONF0 0x4110
+#define SPI1_CS0_B_GPIOC_66_PAD 0x4118
+#define SPI1_MISO_GPIOC_67_PCONF0 0x4120
+#define SPI1_MISO_GPIOC_67_PAD 0x4128
+#define SPI1_MOSI_GPIOC_68_PCONF0 0x4130
+#define SPI1_MOSI_GPIOC_68_PAD 0x4138
+#define SPI1_CLK_GPIOC_69_PCONF0 0x4100
+#define SPI1_CLK_GPIOC_69_PAD 0x4108
+#define UART1_RXD_GPIOC_70_PCONF0 0x4020
+#define UART1_RXD_GPIOC_70_PAD 0x4028
+#define UART1_TXD_GPIOC_71_PCONF0 0x4010
+#define UART1_TXD_GPIOC_71_PAD 0x4018
+#define UART1_RTS_B_GPIOC_72_PCONF0 0x4000
+#define UART1_RTS_B_GPIOC_72_PAD 0x4008
+#define UART1_CTS_B_GPIOC_73_PCONF0 0x4040
+#define UART1_CTS_B_GPIOC_73_PAD 0x4048
+#define UART2_RXD_GPIOC_74_PCONF0 0x4060
+#define UART2_RXD_GPIOC_74_PAD 0x4068
+#define UART2_TXD_GPIOC_75_PCONF0 0x4070
+#define UART2_TXD_GPIOC_75_PAD 0x4078
+#define UART2_RTS_B_GPIOC_76_PCONF0 0x4090
+#define UART2_RTS_B_GPIOC_76_PAD 0x4098
+#define UART2_CTS_B_GPIOC_77_PCONF0 0x4080
+#define UART2_CTS_B_GPIOC_77_PAD 0x4088
+#define I2C0_SDA_GPIOC_78_PCONF0 0x4210
+#define I2C0_SDA_GPIOC_78_PAD 0x4218
+#define I2C0_SCL_GPIOC_79_PCONF0 0x4200
+#define I2C0_SCL_GPIOC_79_PAD 0x4208
+#define I2C1_SDA_GPIOC_80_PCONF0 0x41F0
+#define I2C1_SDA_GPIOC_80_PAD 0x41F8
+#define I2C1_SCL_GPIOC_81_PCONF0 0x41E0
+#define I2C1_SCL_GPIOC_81_PAD 0x41E8
+#define I2C2_SDA_GPIOC_82_PCONF0 0x41D0
+#define I2C2_SDA_GPIOC_82_PAD 0x41D8
+#define I2C2_SCL_GPIOC_83_PCONF0 0x41B0
+#define I2C2_SCL_GPIOC_83_PAD 0x41B8
+#define I2C3_SDA_GPIOC_84_PCONF0 0x4190
+#define I2C2_SCL_GPIOC_83_PAD 0x41B8
+#define I2C3_SDA_GPIOC_84_PCONF0 0x4190
+#define I2C3_SDA_GPIOC_84_PAD 0x4198
+#define I2C3_SCL_GPIOC_85_PCONF0 0x41C0
+#define I2C3_SCL_GPIOC_85_PAD 0x41C8
+#define I2C4_SDA_GPIOC_86_PCONF0 0x41A0
+#define I2C4_SDA_GPIOC_86_PAD 0x41A8
+#define I2C4_SCL_GPIOC_87_PCONF0 0x4170
+#define I2C4_SCL_GPIOC_87_PAD 0x4178
+#define I2C5_SDA_GPIOC_88_PCONF0 0x4150
+#define I2C5_SDA_GPIOC_88_PAD 0x4158
+#define I2C5_SCL_GPIOC_89_PCONF0 0x4140
+#define I2C5_SCL_GPIOC_89_PAD 0x4148
+#define I2C6_SDA_GPIOC_90_PCONF0 0x4180
+#define I2C6_SDA_GPIOC_90_PAD 0x4188
+#define I2C6_SCL_GPIOC_91_PCONF0 0x4160
+#define I2C6_SCL_GPIOC_91_PAD 0x4168
+#define I2C_NFC_SDA_GPIOC_92_PCONF0 0x4050
+#define I2C_NFC_SDA_GPIOC_92_PAD 0x4058
+#define I2C_NFC_SCL_GPIOC_93_PCONF0 0x4030
+#define I2C_NFC_SCL_GPIOC_93_PAD 0x4038
+#define PWM0_GPIOC_94_PCONF0 0x40A0
+#define PWM0_GPIOC_94_PAD 0x40A8
+#define PWM1_GPIOC_95_PCONF0 0x40B0
+#define PWM1_GPIOC_95_PAD 0x40B8
+#define PLT_CLK0_GPIOC_96_PCONF0 0x46A0
+#define PLT_CLK0_GPIOC_96_PAD 0x46A8
+#define PLT_CLK1_GPIOC_97_PCONF0 0x4570
+#define PLT_CLK1_GPIOC_97_PAD 0x4578
+#define PLT_CLK2_GPIOC_98_PCONF0 0x45B0
+#define PLT_CLK2_GPIOC_98_PAD 0x45B8
+#define PLT_CLK3_GPIOC_99_PCONF0 0x4680
+#define PLT_CLK3_GPIOC_99_PAD 0x4688
+#define PLT_CLK4_GPIOC_100_PCONF0 0x4610
+#define PLT_CLK4_GPIOC_100_PAD 0x4618
+#define PLT_CLK5_GPIOC_101_PCONF0 0x4640
+#define PLT_CLK5_GPIOC_101_PAD 0x4648
+
+#define GPIO_SUS0_GPIO_SUS0_PCONF0 0x41D0
+#define GPIO_SUS0_GPIO_SUS0_PAD 0x41D8
+#define GPIO_SUS1_GPIO_SUS1_PCONF0 0x4210
+#define GPIO_SUS1_GPIO_SUS1_PAD 0x4218
+#define GPIO_SUS2_GPIO_SUS2_PCONF0 0x41E0
+#define GPIO_SUS2_GPIO_SUS2_PAD 0x41E8
+#define GPIO_SUS3_GPIO_SUS3_PCONF0 0x41F0
+#define GPIO_SUS3_GPIO_SUS3_PAD 0x41F8
+#define GPIO_SUS4_GPIO_SUS4_PCONF0 0x4200
+#define GPIO_SUS4_GPIO_SUS4_PAD 0x4208
+#define GPIO_SUS5_GPIO_SUS5_PCONF0 0x4220
+#define GPIO_SUS5_GPIO_SUS5_PAD 0x4228
+#define GPIO_SUS6_GPIO_SUS6_PCONF0 0x4240
+#define GPIO_SUS6_GPIO_SUS6_PAD 0x4248
+#define GPIO_SUS7_GPIO_SUS7_PCONF0 0x4230
+#define GPIO_SUS7_GPIO_SUS7_PAD 0x4238
+#define SEC_GPIO_SUS8_GPIO_SUS8_PCONF0 0x4260
+#define SEC_GPIO_SUS8_GPIO_SUS8_PAD 0x4268
+#define SEC_GPIO_SUS9_GPIO_SUS9_PCONF0 0x4250
+#define SEC_GPIO_SUS9_GPIO_SUS9_PAD 0x4258
+#define SEC_GPIO_SUS10_GPIO_SUS10_PCONF0 0x4120
+#define SEC_GPIO_SUS10_GPIO_SUS10_PAD 0x4128
+#define SUSPWRDNACK_GPIOS_11_PCONF0 0x4070
+#define SUSPWRDNACK_GPIOS_11_PAD 0x4078
+#define PMU_SUSCLK_GPIOS_12_PCONF0 0x40B0
+#define PMU_SUSCLK_GPIOS_12_PAD 0x40B8
+#define PMU_SLP_S0IX_B_GPIOS_13_PCONF0 0x4140
+#define PMU_SLP_S0IX_B_GPIOS_13_PAD 0x4148
+#define PMU_SLP_LAN_B_GPIOS_14_PCONF0 0x4110
+#define PMU_SLP_LAN_B_GPIOS_14_PAD 0x4118
+#define PMU_WAKE_B_GPIOS_15_PCONF0 0x4010
+#define PMU_WAKE_B_GPIOS_15_PAD 0x4018
+#define PMU_PWRBTN_B_GPIOS_16_PCONF0 0x4080
+#define PMU_PWRBTN_B_GPIOS_16_PAD 0x4088
+#define PMU_WAKE_LAN_B_GPIOS_17_PCONF0 0x40A0
+#define PMU_WAKE_LAN_B_GPIOS_17_PAD 0x40A8
+#define SUS_STAT_B_GPIOS_18_PCONF0 0x4130
+#define SUS_STAT_B_GPIOS_18_PAD 0x4138
+#define USB_OC0_B_GPIOS_19_PCONF0 0x40C0
+#define USB_OC0_B_GPIOS_19_PAD 0x40C8
+#define USB_OC1_B_GPIOS_20_PCONF0 0x4000
+#define USB_OC1_B_GPIOS_20_PAD 0x4008
+#define SPI_CS1_B_GPIOS_21_PCONF0 0x4020
+#define SPI_CS1_B_GPIOS_21_PAD 0x4028
+#define GPIO_DFX0_GPIOS_22_PCONF0 0x4170
+#define GPIO_DFX0_GPIOS_22_PAD 0x4178
+#define GPIO_DFX1_GPIOS_23_PCONF0 0x4270
+#define GPIO_DFX1_GPIOS_23_PAD 0x4278
+#define GPIO_DFX2_GPIOS_24_PCONF0 0x41C0
+#define GPIO_DFX2_GPIOS_24_PAD 0x41C8
+#define GPIO_DFX3_GPIOS_25_PCONF0 0x41B0
+#define GPIO_DFX3_GPIOS_25_PAD 0x41B8
+#define GPIO_DFX4_GPIOS_26_PCONF0 0x4160
+#define GPIO_DFX4_GPIOS_26_PAD 0x4168
+#define GPIO_DFX5_GPIOS_27_PCONF0 0x4150
+#define GPIO_DFX5_GPIOS_27_PAD 0x4158
+#define GPIO_DFX6_GPIOS_28_PCONF0 0x4180
+#define GPIO_DFX6_GPIOS_28_PAD 0x4188
+#define GPIO_DFX7_GPIOS_29_PCONF0 0x4190
+#define GPIO_DFX7_GPIOS_29_PAD 0x4198
+#define GPIO_DFX8_GPIOS_30_PCONF0 0x41A0
+#define GPIO_DFX8_GPIOS_30_PAD 0x41A8
+#define USB_ULPI_0_CLK_GPIOS_31_PCONF0 0x4330
+#define USB_ULPI_0_CLK_GPIOS_31_PAD 0x4338
+#define USB_ULPI_0_DATA0_GPIOS_32_PCONF0 0x4380
+#define USB_ULPI_0_DATA0_GPIOS_32_PAD 0x4388
+#define USB_ULPI_0_DATA1_GPIOS_33_PCONF0 0x4360
+#define USB_ULPI_0_DATA1_GPIOS_33_PAD 0x4368
+#define USB_ULPI_0_DATA2_GPIOS_34_PCONF0 0x4310
+#define USB_ULPI_0_DATA2_GPIOS_34_PAD 0x4318
+#define USB_ULPI_0_DATA3_GPIOS_35_PCONF0 0x4370
+#define USB_ULPI_0_DATA3_GPIOS_35_PAD 0x4378
+#define USB_ULPI_0_DATA4_GPIOS_36_PCONF0 0x4300
+#define USB_ULPI_0_DATA4_GPIOS_36_PAD 0x4308
+#define USB_ULPI_0_DATA5_GPIOS_37_PCONF0 0x4390
+#define USB_ULPI_0_DATA5_GPIOS_37_PAD 0x4398
+#define USB_ULPI_0_DATA6_GPIOS_38_PCONF0 0x4320
+#define USB_ULPI_0_DATA6_GPIOS_38_PAD 0x4328
+#define USB_ULPI_0_DATA7_GPIOS_39_PCONF0 0x43A0
+#define USB_ULPI_0_DATA7_GPIOS_39_PAD 0x43A8
+#define USB_ULPI_0_DIR_GPIOS_40_PCONF0 0x4340
+#define USB_ULPI_0_DIR_GPIOS_40_PAD 0x4348
+#define USB_ULPI_0_NXT_GPIOS_41_PCONF0 0x4350
+#define USB_ULPI_0_NXT_GPIOS_41_PAD 0x4358
+#define USB_ULPI_0_STP_GPIOS_42_PCONF0 0x43B0
+#define USB_ULPI_0_STP_GPIOS_42_PAD 0x43B8
+#define USB_ULPI_0_REFCLK_GPIOS_43_PCONF0 0x4280
+#define USB_ULPI_0_REFCLK_GPIOS_43_PAD 0x4288
+
struct intel_dsi_host;
struct intel_dsi {
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 02f1cd5..1aa5b19 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -91,18 +91,181 @@ struct gpio_table {
};
static struct gpio_table gtable[] = {
- { GPI0_NC_0_HV_DDI0_HPD, GPIO_NC_0_HV_DDI0_PAD, 0 },
- { GPIO_NC_1_HV_DDI0_DDC_SDA, GPIO_NC_1_HV_DDI0_DDC_SDA_PAD, 0 },
- { GPIO_NC_2_HV_DDI0_DDC_SCL, GPIO_NC_2_HV_DDI0_DDC_SCL_PAD, 0 },
- { GPIO_NC_3_PANEL0_VDDEN, GPIO_NC_3_PANEL0_VDDEN_PAD, 0 },
- { GPIO_NC_4_PANEL0_BLKEN, GPIO_NC_4_PANEL0_BLKEN_PAD, 0 },
- { GPIO_NC_5_PANEL0_BLKCTL, GPIO_NC_5_PANEL0_BLKCTL_PAD, 0 },
- { GPIO_NC_6_PCONF0, GPIO_NC_6_PAD, 0 },
- { GPIO_NC_7_PCONF0, GPIO_NC_7_PAD, 0 },
- { GPIO_NC_8_PCONF0, GPIO_NC_8_PAD, 0 },
- { GPIO_NC_9_PCONF0, GPIO_NC_9_PAD, 0 },
- { GPIO_NC_10_PCONF0, GPIO_NC_10_PAD, 0},
- { GPIO_NC_11_PCONF0, GPIO_NC_11_PAD, 0}
+ {HV_DDI0_HPD_GPIONC_0_PCONF0, HV_DDI0_HPD_GPIONC_0_PAD, 0},
+ {HV_DDI0_DDC_SDA_GPIONC_1_PCONF0, HV_DDI0_DDC_SDA_GPIONC_1_PAD, 0},
+ {HV_DDI0_DDC_SCL_GPIONC_2_PCONF0, HV_DDI0_DDC_SCL_GPIONC_2_PAD, 0},
+ {PANEL0_VDDEN_GPIONC_3_PCONF0, PANEL0_VDDEN_GPIONC_3_PAD, 0},
+ {PANEL0_BKLTEN_GPIONC_4_PCONF0, PANEL0_BKLTEN_GPIONC_4_PAD, 0},
+ {PANEL0_BKLTCTL_GPIONC_5_PCONF0, PANEL0_BKLTCTL_GPIONC_5_PAD, 0},
+ {HV_DDI1_HPD_GPIONC_6_PCONF0, HV_DDI1_HPD_GPIONC_6_PAD, 0},
+ {HV_DDI1_DDC_SDA_GPIONC_7_PCONF0, HV_DDI1_DDC_SDA_GPIONC_7_PAD, 0},
+ {HV_DDI1_DDC_SCL_GPIONC_8_PCONF0, HV_DDI1_DDC_SCL_GPIONC_8_PAD, 0},
+ {PANEL1_VDDEN_GPIONC_9_PCONF0, PANEL1_VDDEN_GPIONC_9_PAD, 0},
+ {PANEL1_BKLTEN_GPIONC_10_PCONF0, PANEL1_BKLTEN_GPIONC_10_PAD, 0},
+ {PANEL1_BKLTCTL_GPIONC_11_PCONF0, PANEL1_BKLTCTL_GPIONC_11_PAD, 0},
+ {GP_INTD_DSI_TE1_GPIONC_12_PCONF0, GP_INTD_DSI_TE1_GPIONC_12_PAD, 0},
+ {HV_DDI2_DDC_SDA_GPIONC_13_PCONF0, HV_DDI2_DDC_SDA_GPIONC_13_PAD, 0},
+ {HV_DDI2_DDC_SCL_GPIONC_14_PCONF0, HV_DDI2_DDC_SCL_GPIONC_14_PAD, 0},
+ {GP_CAMERASB00_GPIONC_15_PCONF0, GP_CAMERASB00_GPIONC_15_PAD, 0},
+ {GP_CAMERASB01_GPIONC_16_PCONF0, GP_CAMERASB01_GPIONC_16_PAD, 0},
+ {GP_CAMERASB02_GPIONC_17_PCONF0, GP_CAMERASB02_GPIONC_17_PAD, 0},
+ {GP_CAMERASB03_GPIONC_18_PCONF0, GP_CAMERASB03_GPIONC_18_PAD, 0},
+ {GP_CAMERASB04_GPIONC_19_PCONF0, GP_CAMERASB04_GPIONC_19_PAD, 0},
+ {GP_CAMERASB05_GPIONC_20_PCONF0, GP_CAMERASB05_GPIONC_20_PAD, 0},
+ {GP_CAMERASB06_GPIONC_21_PCONF0, GP_CAMERASB06_GPIONC_21_PAD, 0},
+ {GP_CAMERASB07_GPIONC_22_PCONF0, GP_CAMERASB07_GPIONC_22_PAD, 0},
+ {GP_CAMERASB08_GPIONC_23_PCONF0, GP_CAMERASB08_GPIONC_23_PAD, 0},
+ {GP_CAMERASB09_GPIONC_24_PCONF0, GP_CAMERASB09_GPIONC_24_PAD, 0},
+ {GP_CAMERASB10_GPIONC_25_PCONF0, GP_CAMERASB10_GPIONC_25_PAD, 0},
+ {GP_CAMERASB11_GPIONC_26_PCONF0, GP_CAMERASB11_GPIONC_26_PAD, 0},
+
+ {SATA_GP0_GPIOC_0_PCONF0, SATA_GP0_GPIOC_0_PAD, 0},
+ {SATA_GP1_GPIOC_1_PCONF0, SATA_GP1_GPIOC_1_PAD, 0},
+ {SATA_LEDN_GPIOC_2_PCONF0, SATA_LEDN_GPIOC_2_PAD, 0},
+ {PCIE_CLKREQ0B_GPIOC_3_PCONF0, PCIE_CLKREQ0B_GPIOC_3_PAD, 0},
+ {PCIE_CLKREQ1B_GPIOC_4_PCONF0, PCIE_CLKREQ1B_GPIOC_4_PAD, 0},
+ {PCIE_CLKREQ2B_GPIOC_5_PCONF0, PCIE_CLKREQ2B_GPIOC_5_PAD, 0},
+ {PCIE_CLKREQ3B_GPIOC_6_PCONF0, PCIE_CLKREQ3B_GPIOC_6_PAD, 0},
+ {PCIE_CLKREQ4B_GPIOC_7_PCONF0, PCIE_CLKREQ4B_GPIOC_7_PAD, 0},
+ {HDA_RSTB_GPIOC_8_PCONF0, HDA_RSTB_GPIOC_8_PAD, 0},
+ {HDA_SYNC_GPIOC_9_PCONF0, HDA_SYNC_GPIOC_9_PAD, 0},
+ {HDA_CLK_GPIOC_10_PCONF0, HDA_CLK_GPIOC_10_PAD, 0},
+ {HDA_SDO_GPIOC_11_PCONF0, HDA_SDO_GPIOC_11_PAD, 0},
+ {HDA_SDI0_GPIOC_12_PCONF0, HDA_SDI0_GPIOC_12_PAD, 0},
+ {HDA_SDI1_GPIOC_13_PCONF0, HDA_SDI1_GPIOC_13_PAD, 0},
+ {HDA_DOCKRSTB_GPIOC_14_PCONF0, HDA_DOCKRSTB_GPIOC_14_PAD, 0},
+ {HDA_DOCKENB_GPIOC_15_PCONF0, HDA_DOCKENB_GPIOC_15_PAD, 0},
+ {SDMMC1_CLK_GPIOC_16_PCONF0, SDMMC1_CLK_GPIOC_16_PAD, 0},
+ {SDMMC1_D0_GPIOC_17_PCONF0, SDMMC1_D0_GPIOC_17_PAD, 0},
+ {SDMMC1_D1_GPIOC_18_PCONF0, SDMMC1_D1_GPIOC_18_PAD, 0},
+ {SDMMC1_D2_GPIOC_19_PCONF0, SDMMC1_D2_GPIOC_19_PAD, 0},
+ {SDMMC1_D3_CD_B_GPIOC_20_PCONF0, SDMMC1_D3_CD_B_GPIOC_20_PAD, 0},
+ {MMC1_D4_SD_WE_GPIOC_21_PCONF0, MMC1_D4_SD_WE_GPIOC_21_PAD, 0},
+ {MMC1_D5_GPIOC_22_PCONF0, MMC1_D5_GPIOC_22_PAD, 0},
+ {MMC1_D6_GPIOC_23_PCONF0, MMC1_D6_GPIOC_23_PAD, 0},
+ {MMC1_D7_GPIOC_24_PCONF0, MMC1_D7_GPIOC_24_PAD, 0},
+ {SDMMC1_CMD_GPIOC_25_PCONF0, SDMMC1_CMD_GPIOC_25_PAD, 0},
+ {MMC1_RESET_B_GPIOC_26_PCONF0, MMC1_RESET_B_GPIOC_26_PAD, 0},
+ {SDMMC2_CLK_GPIOC_27_PCONF0, SDMMC2_CLK_GPIOC_27_PAD, 0},
+ {SDMMC2_D0_GPIOC_28_PCONF0, SDMMC2_D0_GPIOC_28_PAD, 0},
+ {SDMMC2_D1_GPIOC_29_PCONF0, SDMMC2_D1_GPIOC_29_PAD, 0},
+ {SDMMC2_D2_GPIOC_30_PCONF0, SDMMC2_D2_GPIOC_30_PAD, 0},
+ {SDMMC2_D3_CD_B_GPIOC_31_PCONF0, SDMMC2_D3_CD_B_GPIOC_31_PAD, 0},
+ {SDMMC2_CMD_GPIOC_32_PCONF0, SDMMC2_CMD_GPIOC_32_PAD, 0},
+ {SDMMC3_CLK_GPIOC_33_PCONF0, SDMMC3_CLK_GPIOC_33_PAD, 0},
+ {SDMMC3_D0_GPIOC_34_PCONF0, SDMMC3_D0_GPIOC_34_PAD, 0},
+ {SDMMC3_D1_GPIOC_35_PCONF0, SDMMC3_D1_GPIOC_35_PAD, 0},
+ {SDMMC3_D2_GPIOC_36_PCONF0, SDMMC3_D2_GPIOC_36_PAD, 0},
+ {SDMMC3_D3_GPIOC_37_PCONF0, SDMMC3_D3_GPIOC_37_PAD, 0},
+ {SDMMC3_CD_B_GPIOC_38_PCONF0, SDMMC3_CD_B_GPIOC_38_PAD, 0},
+ {SDMMC3_CMD_GPIOC_39_PCONF0, SDMMC3_CMD_GPIOC_39_PAD, 0},
+ {SDMMC3_1P8_EN_GPIOC_40_PCONF0, SDMMC3_1P8_EN_GPIOC_40_PAD, 0},
+ {SDMMC3_PWR_EN_B_GPIOC_41_PCONF0, SDMMC3_PWR_EN_B_GPIOC_41_PAD, 0},
+ {LPC_AD0_GPIOC_42_PCONF0, LPC_AD0_GPIOC_42_PAD, 0},
+ {LPC_AD1_GPIOC_43_PCONF0, LPC_AD1_GPIOC_43_PAD, 0},
+ {LPC_AD2_GPIOC_44_PCONF0, LPC_AD2_GPIOC_44_PAD, 0},
+ {LPC_AD3_GPIOC_45_PCONF0, LPC_AD3_GPIOC_45_PAD, 0},
+ {LPC_FRAMEB_GPIOC_46_PCONF0, LPC_FRAMEB_GPIOC_46_PAD, 0},
+ {LPC_CLKOUT0_GPIOC_47_PCONF0, LPC_CLKOUT0_GPIOC_47_PAD, 0},
+ {LPC_CLKOUT1_GPIOC_48_PCONF0, LPC_CLKOUT1_GPIOC_48_PAD, 0},
+ {LPC_CLKRUNB_GPIOC_49_PCONF0, LPC_CLKRUNB_GPIOC_49_PAD, 0},
+ {ILB_SERIRQ_GPIOC_50_PCONF0, ILB_SERIRQ_GPIOC_50_PAD, 0},
+ {SMB_DATA_GPIOC_51_PCONF0, SMB_DATA_GPIOC_51_PAD, 0},
+ {SMB_CLK_GPIOC_52_PCONF0, SMB_CLK_GPIOC_52_PAD, 0},
+ {SMB_ALERTB_GPIOC_53_PCONF0, SMB_ALERTB_GPIOC_53_PAD, 0},
+ {SPKR_GPIOC_54_PCONF0, SPKR_GPIOC_54_PAD, 0},
+ {MHSI_ACDATA_GPIOC_55_PCONF0, MHSI_ACDATA_GPIOC_55_PAD, 0},
+ {MHSI_ACFLAG_GPIOC_56_PCONF0, MHSI_ACFLAG_GPIOC_56_PAD, 0},
+ {MHSI_ACREADY_GPIOC_57_PCONF0, MHSI_ACREADY_GPIOC_57_PAD, 0},
+ {MHSI_ACWAKE_GPIOC_58_PCONF0, MHSI_ACWAKE_GPIOC_58_PAD, 0},
+ {MHSI_CADATA_GPIOC_59_PCONF0, MHSI_CADATA_GPIOC_59_PAD, 0},
+ {MHSI_CAFLAG_GPIOC_60_PCONF0, MHSI_CAFLAG_GPIOC_60_PAD, 0},
+ {MHSI_CAREADY_GPIOC_61_PCONF0, MHSI_CAREADY_GPIOC_61_PAD, 0},
+ {GP_SSP_2_CLK_GPIOC_62_PCONF0, GP_SSP_2_CLK_GPIOC_62_PAD, 0},
+ {GP_SSP_2_FS_GPIOC_63_PCONF0, GP_SSP_2_FS_GPIOC_63_PAD, 0},
+ {GP_SSP_2_RXD_GPIOC_64_PCONF0, GP_SSP_2_RXD_GPIOC_64_PAD, 0},
+ {GP_SSP_2_TXD_GPIOC_65_PCONF0, GP_SSP_2_TXD_GPIOC_65_PAD, 0},
+ {SPI1_CS0_B_GPIOC_66_PCONF0, SPI1_CS0_B_GPIOC_66_PAD, 0},
+ {SPI1_MISO_GPIOC_67_PCONF0, SPI1_MISO_GPIOC_67_PAD, 0},
+ {SPI1_MOSI_GPIOC_68_PCONF0, SPI1_MOSI_GPIOC_68_PAD, 0},
+ {SPI1_CLK_GPIOC_69_PCONF0, SPI1_CLK_GPIOC_69_PAD, 0},
+ {UART1_RXD_GPIOC_70_PCONF0, UART1_RXD_GPIOC_70_PAD, 0},
+ {UART1_TXD_GPIOC_71_PCONF0, UART1_TXD_GPIOC_71_PAD, 0},
+ {UART1_RTS_B_GPIOC_72_PCONF0, UART1_RTS_B_GPIOC_72_PAD, 0},
+ {UART1_CTS_B_GPIOC_73_PCONF0, UART1_CTS_B_GPIOC_73_PAD, 0},
+ {UART2_RXD_GPIOC_74_PCONF0, UART2_RXD_GPIOC_74_PAD, 0},
+ {UART2_TXD_GPIOC_75_PCONF0, UART2_TXD_GPIOC_75_PAD, 0},
+ {UART2_RTS_B_GPIOC_76_PCONF0, UART2_RTS_B_GPIOC_76_PAD, 0},
+ {UART2_CTS_B_GPIOC_77_PCONF0, UART2_CTS_B_GPIOC_77_PAD, 0},
+ {I2C0_SDA_GPIOC_78_PCONF0, I2C0_SDA_GPIOC_78_PAD, 0},
+ {I2C0_SCL_GPIOC_79_PCONF0, I2C0_SCL_GPIOC_79_PAD, 0},
+ {I2C1_SDA_GPIOC_80_PCONF0, I2C1_SDA_GPIOC_80_PAD, 0},
+ {I2C1_SCL_GPIOC_81_PCONF0, I2C1_SCL_GPIOC_81_PAD, 0},
+ {I2C2_SDA_GPIOC_82_PCONF0, I2C2_SDA_GPIOC_82_PAD, 0},
+ {I2C2_SCL_GPIOC_83_PCONF0, I2C2_SCL_GPIOC_83_PAD, 0},
+ {I2C3_SDA_GPIOC_84_PCONF0, I2C3_SDA_GPIOC_84_PAD, 0},
+ {I2C3_SCL_GPIOC_85_PCONF0, I2C3_SCL_GPIOC_85_PAD, 0},
+ {I2C4_SDA_GPIOC_86_PCONF0, I2C4_SDA_GPIOC_86_PAD, 0},
+ {I2C4_SCL_GPIOC_87_PCONF0, I2C4_SCL_GPIOC_87_PAD, 0},
+ {I2C5_SDA_GPIOC_88_PCONF0, I2C5_SDA_GPIOC_88_PAD, 0},
+ {I2C5_SCL_GPIOC_89_PCONF0, I2C5_SCL_GPIOC_89_PAD, 0},
+ {I2C6_SDA_GPIOC_90_PCONF0, I2C6_SDA_GPIOC_90_PAD, 0},
+ {I2C6_SCL_GPIOC_91_PCONF0, I2C6_SCL_GPIOC_91_PAD, 0},
+ {I2C_NFC_SDA_GPIOC_92_PCONF0, I2C_NFC_SDA_GPIOC_92_PAD, 0},
+ {I2C_NFC_SCL_GPIOC_93_PCONF0, I2C_NFC_SCL_GPIOC_93_PAD, 0},
+ {PWM0_GPIOC_94_PCONF0, PWM0_GPIOC_94_PAD, 0},
+ {PWM1_GPIOC_95_PCONF0, PWM1_GPIOC_95_PAD, 0},
+ {PLT_CLK0_GPIOC_96_PCONF0, PLT_CLK0_GPIOC_96_PAD, 0},
+ {PLT_CLK1_GPIOC_97_PCONF0, PLT_CLK1_GPIOC_97_PAD, 0},
+ {PLT_CLK2_GPIOC_98_PCONF0, PLT_CLK2_GPIOC_98_PAD, 0},
+ {PLT_CLK3_GPIOC_99_PCONF0, PLT_CLK3_GPIOC_99_PAD, 0},
+ {PLT_CLK4_GPIOC_100_PCONF0, PLT_CLK4_GPIOC_100_PAD, 0},
+ {PLT_CLK5_GPIOC_101_PCONF0, PLT_CLK5_GPIOC_101_PAD, 0},
+
+ {GPIO_SUS0_GPIO_SUS0_PCONF0, GPIO_SUS0_GPIO_SUS0_PAD, 0},
+ {GPIO_SUS1_GPIO_SUS1_PCONF0, GPIO_SUS1_GPIO_SUS1_PAD, 0},
+ {GPIO_SUS2_GPIO_SUS2_PCONF0, GPIO_SUS2_GPIO_SUS2_PAD, 0},
+ {GPIO_SUS3_GPIO_SUS3_PCONF0, GPIO_SUS3_GPIO_SUS3_PAD, 0},
+ {GPIO_SUS4_GPIO_SUS4_PCONF0, GPIO_SUS4_GPIO_SUS4_PAD, 0},
+ {GPIO_SUS5_GPIO_SUS5_PCONF0, GPIO_SUS5_GPIO_SUS5_PAD, 0},
+ {GPIO_SUS6_GPIO_SUS6_PCONF0, GPIO_SUS6_GPIO_SUS6_PAD, 0},
+ {GPIO_SUS7_GPIO_SUS7_PCONF0, GPIO_SUS7_GPIO_SUS7_PAD, 0},
+ {SEC_GPIO_SUS8_GPIO_SUS8_PCONF0, SEC_GPIO_SUS8_GPIO_SUS8_PAD, 0},
+ {SEC_GPIO_SUS9_GPIO_SUS9_PCONF0, SEC_GPIO_SUS9_GPIO_SUS9_PAD, 0},
+ {SEC_GPIO_SUS10_GPIO_SUS10_PCONF0, SEC_GPIO_SUS10_GPIO_SUS10_PAD, 0},
+ {SUSPWRDNACK_GPIOS_11_PCONF0, SUSPWRDNACK_GPIOS_11_PAD, 0},
+ {PMU_SUSCLK_GPIOS_12_PCONF0, PMU_SUSCLK_GPIOS_12_PAD, 0},
+ {PMU_SLP_S0IX_B_GPIOS_13_PCONF0, PMU_SLP_S0IX_B_GPIOS_13_PAD, 0},
+ {PMU_SLP_LAN_B_GPIOS_14_PCONF0, PMU_SLP_LAN_B_GPIOS_14_PAD, 0},
+ {PMU_WAKE_B_GPIOS_15_PCONF0, PMU_WAKE_B_GPIOS_15_PAD, 0},
+ {PMU_PWRBTN_B_GPIOS_16_PCONF0, PMU_PWRBTN_B_GPIOS_16_PAD, 0},
+ {PMU_WAKE_LAN_B_GPIOS_17_PCONF0, PMU_WAKE_LAN_B_GPIOS_17_PAD, 0},
+ {SUS_STAT_B_GPIOS_18_PCONF0, SUS_STAT_B_GPIOS_18_PAD, 0},
+ {USB_OC0_B_GPIOS_19_PCONF0, USB_OC0_B_GPIOS_19_PAD, 0},
+ {USB_OC1_B_GPIOS_20_PCONF0, USB_OC1_B_GPIOS_20_PAD, 0},
+ {SPI_CS1_B_GPIOS_21_PCONF0, SPI_CS1_B_GPIOS_21_PAD, 0},
+ {GPIO_DFX0_GPIOS_22_PCONF0, GPIO_DFX0_GPIOS_22_PAD, 0},
+ {GPIO_DFX1_GPIOS_23_PCONF0, GPIO_DFX1_GPIOS_23_PAD, 0},
+ {GPIO_DFX2_GPIOS_24_PCONF0, GPIO_DFX2_GPIOS_24_PAD, 0},
+ {GPIO_DFX3_GPIOS_25_PCONF0, GPIO_DFX3_GPIOS_25_PAD, 0},
+ {GPIO_DFX4_GPIOS_26_PCONF0, GPIO_DFX4_GPIOS_26_PAD, 0},
+ {GPIO_DFX5_GPIOS_27_PCONF0, GPIO_DFX5_GPIOS_27_PAD, 0},
+ {GPIO_DFX6_GPIOS_28_PCONF0, GPIO_DFX6_GPIOS_28_PAD, 0},
+ {GPIO_DFX7_GPIOS_29_PCONF0, GPIO_DFX7_GPIOS_29_PAD, 0},
+ {GPIO_DFX8_GPIOS_30_PCONF0, GPIO_DFX8_GPIOS_30_PAD, 0},
+ {USB_ULPI_0_CLK_GPIOS_31_PCONF0, USB_ULPI_0_CLK_GPIOS_31_PAD, 0},
+ {USB_ULPI_0_DATA0_GPIOS_32_PCONF0, USB_ULPI_0_DATA0_GPIOS_32_PAD, 0},
+ {USB_ULPI_0_DATA1_GPIOS_33_PCONF0, USB_ULPI_0_DATA1_GPIOS_33_PAD, 0},
+ {USB_ULPI_0_DATA2_GPIOS_34_PCONF0, USB_ULPI_0_DATA2_GPIOS_34_PAD, 0},
+ {USB_ULPI_0_DATA3_GPIOS_35_PCONF0, USB_ULPI_0_DATA3_GPIOS_35_PAD, 0},
+ {USB_ULPI_0_DATA4_GPIOS_36_PCONF0, USB_ULPI_0_DATA4_GPIOS_36_PAD, 0},
+ {USB_ULPI_0_DATA5_GPIOS_37_PCONF0, USB_ULPI_0_DATA5_GPIOS_37_PAD, 0},
+ {USB_ULPI_0_DATA6_GPIOS_38_PCONF0, USB_ULPI_0_DATA6_GPIOS_38_PAD, 0},
+ {USB_ULPI_0_DATA7_GPIOS_39_PCONF0, USB_ULPI_0_DATA7_GPIOS_39_PAD, 0},
+ {USB_ULPI_0_DIR_GPIOS_40_PCONF0, USB_ULPI_0_DIR_GPIOS_40_PAD, 0},
+ {USB_ULPI_0_NXT_GPIOS_41_PCONF0, USB_ULPI_0_NXT_GPIOS_41_PAD, 0},
+ {USB_ULPI_0_STP_GPIOS_42_PCONF0, USB_ULPI_0_STP_GPIOS_42_PAD, 0},
+ {USB_ULPI_0_REFCLK_GPIOS_43_PCONF0, USB_ULPI_0_REFCLK_GPIOS_43_PAD, 0}
};
static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
@@ -261,14 +424,42 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
u8 gpio, action;
u16 function, pad;
u32 val;
+ u8 block;
struct drm_device *dev = intel_dsi->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ DRM_DEBUG_DRIVER("MIPI: executing gpio element\n");
+
+ /*
+ * Skipping the first byte as it is of no
+ * interest for android in new version
+ */
+ if (dev_priv->vbt.dsi.seq_version >= 3)
+ data++;
+
gpio = *data++;
/* pull up/down */
action = *data++;
+ if (dev_priv->vbt.dsi.seq_version >= 3) {
+ if (gpio <= MAX_GPIO_NUM_NC) {
+ DRM_DEBUG_DRIVER("GPIO is in the north Block\n");
+ block = IOSF_PORT_GPIO_NC;
+ } else if (gpio > MAX_GPIO_NUM_NC && gpio <= MAX_GPIO_NUM_SC) {
+ DRM_DEBUG_DRIVER("GPIO is in the south Block\n");
+ block = IOSF_PORT_GPIO_SC;
+ } else if (gpio > MAX_GPIO_NUM_SC && gpio <= MAX_GPIO_NUM) {
+ DRM_DEBUG_DRIVER("GPIO is in the SUS Block\n");
+ block = IOSF_PORT_GPIO_SUS;
+ } else {
+ DRM_ERROR("GPIO number is not present in the table\n");
+ return NULL;
+ }
+ } else {
+ block = IOSF_PORT_GPIO_NC;
+ }
+
function = gtable[gpio].function_reg;
pad = gtable[gpio].pad_reg;
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [MIPI SEQ PARSING v2 PATCH 07/11] drm/i915: Added the generic gpio sequence support and gpio table
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 07/11] drm/i915: Added the generic gpio sequence support and gpio table Deepak M
@ 2015-09-17 14:44 ` Jani Nikula
0 siblings, 0 replies; 25+ messages in thread
From: Jani Nikula @ 2015-09-17 14:44 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
On Thu, 10 Sep 2015, Deepak M <m.deepak@intel.com> wrote:
> The generic gpio is sequence is parsed from the VBT and the
> GPIO table is updated with the North core, South core and
> SUS core elements.
>
> v2: Move changes in sideband.c file to new patch(Jani), rebase
>
> Signed-off-by: Deepak M <m.deepak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 5 +
> drivers/gpu/drm/i915/intel_dsi.h | 351 ++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 215 ++++++++++++++++-
> 3 files changed, 559 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 84ed9ab..5bef50c 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -568,6 +568,11 @@
> #define IOSF_PORT_DPIO 0x12
> #define IOSF_PORT_DPIO_2 0x1a
> #define IOSF_PORT_GPIO_NC 0x13
> +#define IOSF_PORT_GPIO_SC 0x48
> +#define IOSF_PORT_GPIO_SUS 0xA8
> +#define MAX_GPIO_NUM_NC 26
> +#define MAX_GPIO_NUM_SC 128
> +#define MAX_GPIO_NUM 172
Please send these as a separate prep patch.
> #define IOSF_PORT_CCK 0x14
> #define IOSF_PORT_CCU 0xA9
> #define IOSF_PORT_GPS_CORE 0x48
> diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
> index 42a6859..fc89a6b 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.h
> +++ b/drivers/gpu/drm/i915/intel_dsi.h
> @@ -34,6 +34,357 @@
> #define DSI_DUAL_LINK_FRONT_BACK 1
> #define DSI_DUAL_LINK_PIXEL_ALT 2
>
> +#define HV_DDI0_HPD_GPIONC_0_PCONF0 0x4130
> +#define HV_DDI0_HPD_GPIONC_0_PAD 0x4138
> +#define HV_DDI0_DDC_SDA_GPIONC_1_PCONF0 0x4120
> +#define HV_DDI0_DDC_SDA_GPIONC_1_PAD 0x4128
> +#define HV_DDI0_DDC_SCL_GPIONC_2_PCONF0 0x4110
> +#define HV_DDI0_DDC_SCL_GPIONC_2_PAD 0x4118
> +#define PANEL0_VDDEN_GPIONC_3_PCONF0 0x4140
> +#define PANEL0_VDDEN_GPIONC_3_PAD 0x4148
> +#define PANEL0_BKLTEN_GPIONC_4_PCONF0 0x4150
> +#define PANEL0_BKLTEN_GPIONC_4_PAD 0x4158
> +#define PANEL0_BKLTCTL_GPIONC_5_PCONF0 0x4160
> +#define PANEL0_BKLTCTL_GPIONC_5_PAD 0x4168
> +#define HV_DDI1_HPD_GPIONC_6_PCONF0 0x4180
> +#define HV_DDI1_HPD_GPIONC_6_PAD 0x4188
> +#define HV_DDI1_DDC_SDA_GPIONC_7_PCONF0 0x4190
> +#define HV_DDI1_DDC_SDA_GPIONC_7_PAD 0x4198
> +#define HV_DDI1_DDC_SCL_GPIONC_8_PCONF0 0x4170
> +#define HV_DDI1_DDC_SCL_GPIONC_8_PAD 0x4178
> +#define PANEL1_VDDEN_GPIONC_9_PCONF0 0x4100
> +#define PANEL1_VDDEN_GPIONC_9_PAD 0x4108
> +#define PANEL1_BKLTEN_GPIONC_10_PCONF0 0x40E0
> +#define PANEL1_BKLTEN_GPIONC_10_PAD 0x40E8
> +#define PANEL1_BKLTCTL_GPIONC_11_PCONF0 0x40F0
> +#define PANEL1_BKLTCTL_GPIONC_11_PAD 0x40F8
> +#define GP_INTD_DSI_TE1_GPIONC_12_PCONF0 0x40C0
> +#define GP_INTD_DSI_TE1_GPIONC_12_PAD 0x40C8
> +#define HV_DDI2_DDC_SDA_GPIONC_13_PCONF0 0x41A0
> +#define HV_DDI2_DDC_SDA_GPIONC_13_PAD 0x41A8
> +#define HV_DDI2_DDC_SCL_GPIONC_14_PCONF0 0x41B0
> +#define HV_DDI2_DDC_SCL_GPIONC_14_PAD 0x41B8
> +#define GP_CAMERASB00_GPIONC_15_PCONF0 0x4010
> +#define GP_CAMERASB00_GPIONC_15_PAD 0x4018
> +#define GP_CAMERASB01_GPIONC_16_PCONF0 0x4040
> +#define GP_CAMERASB01_GPIONC_16_PAD 0x4048
> +#define GP_CAMERASB02_GPIONC_17_PCONF0 0x4080
> +#define GP_CAMERASB02_GPIONC_17_PAD 0x4088
> +#define GP_CAMERASB03_GPIONC_18_PCONF0 0x40B0
> +#define GP_CAMERASB03_GPIONC_18_PAD 0x40B8
> +#define GP_CAMERASB04_GPIONC_19_PCONF0 0x4000
> +#define GP_CAMERASB04_GPIONC_19_PAD 0x4008
> +#define GP_CAMERASB05_GPIONC_20_PCONF0 0x4030
> +#define GP_CAMERASB05_GPIONC_20_PAD 0x4038
> +#define GP_CAMERASB06_GPIONC_21_PCONF0 0x4060
> +#define GP_CAMERASB06_GPIONC_21_PAD 0x4068
> +#define GP_CAMERASB07_GPIONC_22_PCONF0 0x40A0
> +#define GP_CAMERASB07_GPIONC_22_PAD 0x40A8
> +#define GP_CAMERASB08_GPIONC_23_PCONF0 0x40D0
> +#define GP_CAMERASB08_GPIONC_23_PAD 0x40D8
> +#define GP_CAMERASB09_GPIONC_24_PCONF0 0x4020
> +#define GP_CAMERASB09_GPIONC_24_PAD 0x4028
> +#define GP_CAMERASB10_GPIONC_25_PCONF0 0x4050
> +#define GP_CAMERASB10_GPIONC_25_PAD 0x4058
> +#define GP_CAMERASB11_GPIONC_26_PCONF0 0x4090
> +#define GP_CAMERASB11_GPIONC_26_PAD 0x4098
> +
> +#define SATA_GP0_GPIOC_0_PCONF0 0x4550
> +#define SATA_GP0_GPIOC_0_PAD 0x4558
> +#define SATA_GP1_GPIOC_1_PCONF0 0x4590
> +#define SATA_GP1_GPIOC_1_PAD 0x4598
> +#define SATA_LEDN_GPIOC_2_PCONF0 0x45D0
> +#define SATA_LEDN_GPIOC_2_PAD 0x45D8
> +#define PCIE_CLKREQ0B_GPIOC_3_PCONF0 0x4600
> +#define PCIE_CLKREQ0B_GPIOC_3_PAD 0x4608
> +#define PCIE_CLKREQ1B_GPIOC_4_PCONF0 0x4630
> +#define PCIE_CLKREQ1B_GPIOC_4_PAD 0x4638
> +#define PCIE_CLKREQ2B_GPIOC_5_PCONF0 0x4660
> +#define PCIE_CLKREQ2B_GPIOC_5_PAD 0x4668
> +#define PCIE_CLKREQ3B_GPIOC_6_PCONF0 0x4620
> +#define PCIE_CLKREQ3B_GPIOC_6_PAD 0x4628
> +#define PCIE_CLKREQ4B_GPIOC_7_PCONF0 0x4650
> +#define PCIE_CLKREQ4B_GPIOC_7_PAD 0x4658
> +#define HDA_RSTB_GPIOC_8_PCONF0 0x4220
> +#define HDA_RSTB_GPIOC_8_PAD 0x4228
> +#define HDA_SYNC_GPIOC_9_PCONF0 0x4250
> +#define HDA_SYNC_GPIOC_9_PAD 0x4258
> +#define HDA_CLK_GPIOC_10_PCONF0 0x4240
> +#define HDA_CLK_GPIOC_10_PAD 0x4248
> +#define HDA_SDO_GPIOC_11_PCONF0 0x4260
> +#define HDA_SDO_GPIOC_11_PAD 0x4268
> +#define HDA_SDI0_GPIOC_12_PCONF0 0x4270
> +#define HDA_SDI0_GPIOC_12_PAD 0x4278
> +#define HDA_SDI1_GPIOC_13_PCONF0 0x4230
> +#define HDA_SDI1_GPIOC_13_PAD 0x4238
> +#define HDA_DOCKRSTB_GPIOC_14_PCONF0 0x4280
> +#define HDA_DOCKRSTB_GPIOC_14_PAD 0x4288
> +#define HDA_DOCKENB_GPIOC_15_PCONF0 0x4540
> +#define HDA_DOCKENB_GPIOC_15_PAD 0x4548
> +#define SDMMC1_CLK_GPIOC_16_PCONF0 0x43E0
> +#define SDMMC1_CLK_GPIOC_16_PAD 0x43E8
> +#define SDMMC1_D0_GPIOC_17_PCONF0 0x43D0
> +#define SDMMC1_D0_GPIOC_17_PAD 0x43D8
> +#define SDMMC1_D1_GPIOC_18_PCONF0 0x4400
> +#define SDMMC1_D1_GPIOC_18_PAD 0x4408
> +#define SDMMC1_D2_GPIOC_19_PCONF0 0x43B0
> +#define SDMMC1_D2_GPIOC_19_PAD 0x43B8
> +#define SDMMC1_D3_CD_B_GPIOC_20_PCONF0 0x4360
> +#define SDMMC1_D3_CD_B_GPIOC_20_PAD 0x4368
> +#define MMC1_D4_SD_WE_GPIOC_21_PCONF0 0x4380
> +#define MMC1_D4_SD_WE_GPIOC_21_PAD 0x4388
> +#define MMC1_D5_GPIOC_22_PCONF0 0x43C0
> +#define MMC1_D5_GPIOC_22_PAD 0x43C8
> +#define MMC1_D6_GPIOC_23_PCONF0 0x4370
> +#define MMC1_D6_GPIOC_23_PAD 0x4378
> +#define MMC1_D7_GPIOC_24_PCONF0 0x43F0
> +#define MMC1_D7_GPIOC_24_PAD 0x43F8
> +#define SDMMC1_CMD_GPIOC_25_PCONF0 0x4390
> +#define SDMMC1_CMD_GPIOC_25_PAD 0x4398
> +#define MMC1_RESET_B_GPIOC_26_PCONF0 0x4330
> +#define MMC1_RESET_B_GPIOC_26_PAD 0x4338
> +#define SDMMC2_CLK_GPIOC_27_PCONF0 0x4320
> +#define SDMMC2_CLK_GPIOC_27_PAD 0x4328
> +#define SDMMC2_D0_GPIOC_28_PCONF0 0x4350
> +#define SDMMC2_D0_GPIOC_28_PAD 0x4358
> +#define SDMMC2_D1_GPIOC_29_PCONF0 0x42F0
> +#define SDMMC2_D1_GPIOC_29_PAD 0x42F8
> +#define SDMMC2_D2_GPIOC_30_PCONF0 0x4340
> +#define SDMMC2_D2_GPIOC_30_PAD 0x4348
> +#define SDMMC2_D3_CD_B_GPIOC_31_PCONF0 0x4310
> +#define SDMMC2_D3_CD_B_GPIOC_31_PAD 0x4318
> +#define SDMMC2_CMD_GPIOC_32_PCONF0 0x4300
> +#define SDMMC2_CMD_GPIOC_32_PAD 0x4308
> +#define SDMMC3_CLK_GPIOC_33_PCONF0 0x42B0
> +#define SDMMC3_CLK_GPIOC_33_PAD 0x42B8
> +#define SDMMC3_D0_GPIOC_34_PCONF0 0x42E0
> +#define SDMMC3_D0_GPIOC_34_PAD 0x42E8
> +#define SDMMC3_D1_GPIOC_35_PCONF0 0x4290
> +#define SDMMC3_D1_GPIOC_35_PAD 0x4298
> +#define SDMMC3_D2_GPIOC_36_PCONF0 0x42D0
> +#define SDMMC3_D2_GPIOC_36_PAD 0x42D8
> +#define SDMMC3_D3_GPIOC_37_PCONF0 0x42A0
> +#define SDMMC3_D3_GPIOC_37_PAD 0x42A8
> +#define SDMMC3_CD_B_GPIOC_38_PCONF0 0x43A0
> +#define SDMMC3_CD_B_GPIOC_38_PAD 0x43A8
> +#define SDMMC3_CMD_GPIOC_39_PCONF0 0x42C0
> +#define SDMMC3_CMD_GPIOC_39_PAD 0x42C8
> +#define SDMMC3_1P8_EN_GPIOC_40_PCONF0 0x45F0
> +#define SDMMC3_1P8_EN_GPIOC_40_PAD 0x45F8
> +#define SDMMC3_PWR_EN_B_GPIOC_41_PCONF0 0x4690
> +#define SDMMC3_PWR_EN_B_GPIOC_41_PAD 0x4698
> +#define LPC_AD0_GPIOC_42_PCONF0 0x4460
> +#define LPC_AD0_GPIOC_42_PAD 0x4468
> +#define LPC_AD1_GPIOC_43_PCONF0 0x4440
> +#define LPC_AD1_GPIOC_43_PAD 0x4448
> +#define LPC_AD2_GPIOC_44_PCONF0 0x4430
> +#define LPC_AD2_GPIOC_44_PAD 0x4438
> +#define LPC_AD3_GPIOC_45_PCONF0 0x4420
> +#define LPC_AD3_GPIOC_45_PAD 0x4428
> +#define LPC_FRAMEB_GPIOC_46_PCONF0 0x4450
> +#define LPC_FRAMEB_GPIOC_46_PAD 0x4458
> +#define LPC_CLKOUT0_GPIOC_47_PCONF0 0x4470
> +#define LPC_CLKOUT0_GPIOC_47_PAD 0x4478
> +#define LPC_CLKOUT1_GPIOC_48_PCONF0 0x4410
> +#define LPC_CLKOUT1_GPIOC_48_PAD 0x4418
> +#define LPC_CLKRUNB_GPIOC_49_PCONF0 0x4480
> +#define LPC_CLKRUNB_GPIOC_49_PAD 0x4488
> +#define ILB_SERIRQ_GPIOC_50_PCONF0 0x4560
> +#define ILB_SERIRQ_GPIOC_50_PAD 0x4568
> +#define SMB_DATA_GPIOC_51_PCONF0 0x45A0
> +#define SMB_DATA_GPIOC_51_PAD 0x45A8
> +#define SMB_CLK_GPIOC_52_PCONF0 0x4580
> +#define SMB_CLK_GPIOC_52_PAD 0x4588
> +#define SMB_ALERTB_GPIOC_53_PCONF0 0x45C0
> +#define SMB_ALERTB_GPIOC_53_PAD 0x45C8
> +#define SPKR_GPIOC_54_PCONF0 0x4670
> +#define SPKR_GPIOC_54_PAD 0x4678
> +#define MHSI_ACDATA_GPIOC_55_PCONF0 0x44D0
> +#define MHSI_ACDATA_GPIOC_55_PAD 0x44D8
> +#define MHSI_ACFLAG_GPIOC_56_PCONF0 0x44F0
> +#define MHSI_ACFLAG_GPIOC_56_PAD 0x44F8
> +#define MHSI_ACREADY_GPIOC_57_PCONF0 0x4530
> +#define MHSI_ACREADY_GPIOC_57_PAD 0x4538
> +#define MHSI_ACWAKE_GPIOC_58_PCONF0 0x44E0
> +#define MHSI_ACWAKE_GPIOC_58_PAD 0x44E8
> +#define MHSI_CADATA_GPIOC_59_PCONF0 0x4510
> +#define MHSI_CADATA_GPIOC_59_PAD 0x4518
> +#define MHSI_CAFLAG_GPIOC_60_PCONF0 0x4500
> +#define MHSI_CAFLAG_GPIOC_60_PAD 0x4508
> +#define MHSI_CAREADY_GPIOC_61_PCONF0 0x4520
> +#define MHSI_CAREADY_GPIOC_61_PAD 0x4528
> +#define GP_SSP_2_CLK_GPIOC_62_PCONF0 0x40D0
> +#define GP_SSP_2_CLK_GPIOC_62_PAD 0x40D8
> +#define GP_SSP_2_FS_GPIOC_63_PCONF0 0x40C0
> +#define GP_SSP_2_FS_GPIOC_63_PAD 0x40C8
> +#define GP_SSP_2_RXD_GPIOC_64_PCONF0 0x40F0
> +#define GP_SSP_2_RXD_GPIOC_64_PAD 0x40F8
> +#define GP_SSP_2_TXD_GPIOC_65_PCONF0 0x40E0
> +#define GP_SSP_2_TXD_GPIOC_65_PAD 0x40E8
> +#define SPI1_CS0_B_GPIOC_66_PCONF0 0x4110
> +#define SPI1_CS0_B_GPIOC_66_PAD 0x4118
> +#define SPI1_MISO_GPIOC_67_PCONF0 0x4120
> +#define SPI1_MISO_GPIOC_67_PAD 0x4128
> +#define SPI1_MOSI_GPIOC_68_PCONF0 0x4130
> +#define SPI1_MOSI_GPIOC_68_PAD 0x4138
> +#define SPI1_CLK_GPIOC_69_PCONF0 0x4100
> +#define SPI1_CLK_GPIOC_69_PAD 0x4108
> +#define UART1_RXD_GPIOC_70_PCONF0 0x4020
> +#define UART1_RXD_GPIOC_70_PAD 0x4028
> +#define UART1_TXD_GPIOC_71_PCONF0 0x4010
> +#define UART1_TXD_GPIOC_71_PAD 0x4018
> +#define UART1_RTS_B_GPIOC_72_PCONF0 0x4000
> +#define UART1_RTS_B_GPIOC_72_PAD 0x4008
> +#define UART1_CTS_B_GPIOC_73_PCONF0 0x4040
> +#define UART1_CTS_B_GPIOC_73_PAD 0x4048
> +#define UART2_RXD_GPIOC_74_PCONF0 0x4060
> +#define UART2_RXD_GPIOC_74_PAD 0x4068
> +#define UART2_TXD_GPIOC_75_PCONF0 0x4070
> +#define UART2_TXD_GPIOC_75_PAD 0x4078
> +#define UART2_RTS_B_GPIOC_76_PCONF0 0x4090
> +#define UART2_RTS_B_GPIOC_76_PAD 0x4098
> +#define UART2_CTS_B_GPIOC_77_PCONF0 0x4080
> +#define UART2_CTS_B_GPIOC_77_PAD 0x4088
> +#define I2C0_SDA_GPIOC_78_PCONF0 0x4210
> +#define I2C0_SDA_GPIOC_78_PAD 0x4218
> +#define I2C0_SCL_GPIOC_79_PCONF0 0x4200
> +#define I2C0_SCL_GPIOC_79_PAD 0x4208
> +#define I2C1_SDA_GPIOC_80_PCONF0 0x41F0
> +#define I2C1_SDA_GPIOC_80_PAD 0x41F8
> +#define I2C1_SCL_GPIOC_81_PCONF0 0x41E0
> +#define I2C1_SCL_GPIOC_81_PAD 0x41E8
> +#define I2C2_SDA_GPIOC_82_PCONF0 0x41D0
> +#define I2C2_SDA_GPIOC_82_PAD 0x41D8
> +#define I2C2_SCL_GPIOC_83_PCONF0 0x41B0
> +#define I2C2_SCL_GPIOC_83_PAD 0x41B8
> +#define I2C3_SDA_GPIOC_84_PCONF0 0x4190
> +#define I2C2_SCL_GPIOC_83_PAD 0x41B8
> +#define I2C3_SDA_GPIOC_84_PCONF0 0x4190
> +#define I2C3_SDA_GPIOC_84_PAD 0x4198
> +#define I2C3_SCL_GPIOC_85_PCONF0 0x41C0
> +#define I2C3_SCL_GPIOC_85_PAD 0x41C8
> +#define I2C4_SDA_GPIOC_86_PCONF0 0x41A0
> +#define I2C4_SDA_GPIOC_86_PAD 0x41A8
> +#define I2C4_SCL_GPIOC_87_PCONF0 0x4170
> +#define I2C4_SCL_GPIOC_87_PAD 0x4178
> +#define I2C5_SDA_GPIOC_88_PCONF0 0x4150
> +#define I2C5_SDA_GPIOC_88_PAD 0x4158
> +#define I2C5_SCL_GPIOC_89_PCONF0 0x4140
> +#define I2C5_SCL_GPIOC_89_PAD 0x4148
> +#define I2C6_SDA_GPIOC_90_PCONF0 0x4180
> +#define I2C6_SDA_GPIOC_90_PAD 0x4188
> +#define I2C6_SCL_GPIOC_91_PCONF0 0x4160
> +#define I2C6_SCL_GPIOC_91_PAD 0x4168
> +#define I2C_NFC_SDA_GPIOC_92_PCONF0 0x4050
> +#define I2C_NFC_SDA_GPIOC_92_PAD 0x4058
> +#define I2C_NFC_SCL_GPIOC_93_PCONF0 0x4030
> +#define I2C_NFC_SCL_GPIOC_93_PAD 0x4038
> +#define PWM0_GPIOC_94_PCONF0 0x40A0
> +#define PWM0_GPIOC_94_PAD 0x40A8
> +#define PWM1_GPIOC_95_PCONF0 0x40B0
> +#define PWM1_GPIOC_95_PAD 0x40B8
> +#define PLT_CLK0_GPIOC_96_PCONF0 0x46A0
> +#define PLT_CLK0_GPIOC_96_PAD 0x46A8
> +#define PLT_CLK1_GPIOC_97_PCONF0 0x4570
> +#define PLT_CLK1_GPIOC_97_PAD 0x4578
> +#define PLT_CLK2_GPIOC_98_PCONF0 0x45B0
> +#define PLT_CLK2_GPIOC_98_PAD 0x45B8
> +#define PLT_CLK3_GPIOC_99_PCONF0 0x4680
> +#define PLT_CLK3_GPIOC_99_PAD 0x4688
> +#define PLT_CLK4_GPIOC_100_PCONF0 0x4610
> +#define PLT_CLK4_GPIOC_100_PAD 0x4618
> +#define PLT_CLK5_GPIOC_101_PCONF0 0x4640
> +#define PLT_CLK5_GPIOC_101_PAD 0x4648
> +
> +#define GPIO_SUS0_GPIO_SUS0_PCONF0 0x41D0
> +#define GPIO_SUS0_GPIO_SUS0_PAD 0x41D8
> +#define GPIO_SUS1_GPIO_SUS1_PCONF0 0x4210
> +#define GPIO_SUS1_GPIO_SUS1_PAD 0x4218
> +#define GPIO_SUS2_GPIO_SUS2_PCONF0 0x41E0
> +#define GPIO_SUS2_GPIO_SUS2_PAD 0x41E8
> +#define GPIO_SUS3_GPIO_SUS3_PCONF0 0x41F0
> +#define GPIO_SUS3_GPIO_SUS3_PAD 0x41F8
> +#define GPIO_SUS4_GPIO_SUS4_PCONF0 0x4200
> +#define GPIO_SUS4_GPIO_SUS4_PAD 0x4208
> +#define GPIO_SUS5_GPIO_SUS5_PCONF0 0x4220
> +#define GPIO_SUS5_GPIO_SUS5_PAD 0x4228
> +#define GPIO_SUS6_GPIO_SUS6_PCONF0 0x4240
> +#define GPIO_SUS6_GPIO_SUS6_PAD 0x4248
> +#define GPIO_SUS7_GPIO_SUS7_PCONF0 0x4230
> +#define GPIO_SUS7_GPIO_SUS7_PAD 0x4238
> +#define SEC_GPIO_SUS8_GPIO_SUS8_PCONF0 0x4260
> +#define SEC_GPIO_SUS8_GPIO_SUS8_PAD 0x4268
> +#define SEC_GPIO_SUS9_GPIO_SUS9_PCONF0 0x4250
> +#define SEC_GPIO_SUS9_GPIO_SUS9_PAD 0x4258
> +#define SEC_GPIO_SUS10_GPIO_SUS10_PCONF0 0x4120
> +#define SEC_GPIO_SUS10_GPIO_SUS10_PAD 0x4128
> +#define SUSPWRDNACK_GPIOS_11_PCONF0 0x4070
> +#define SUSPWRDNACK_GPIOS_11_PAD 0x4078
> +#define PMU_SUSCLK_GPIOS_12_PCONF0 0x40B0
> +#define PMU_SUSCLK_GPIOS_12_PAD 0x40B8
> +#define PMU_SLP_S0IX_B_GPIOS_13_PCONF0 0x4140
> +#define PMU_SLP_S0IX_B_GPIOS_13_PAD 0x4148
> +#define PMU_SLP_LAN_B_GPIOS_14_PCONF0 0x4110
> +#define PMU_SLP_LAN_B_GPIOS_14_PAD 0x4118
> +#define PMU_WAKE_B_GPIOS_15_PCONF0 0x4010
> +#define PMU_WAKE_B_GPIOS_15_PAD 0x4018
> +#define PMU_PWRBTN_B_GPIOS_16_PCONF0 0x4080
> +#define PMU_PWRBTN_B_GPIOS_16_PAD 0x4088
> +#define PMU_WAKE_LAN_B_GPIOS_17_PCONF0 0x40A0
> +#define PMU_WAKE_LAN_B_GPIOS_17_PAD 0x40A8
> +#define SUS_STAT_B_GPIOS_18_PCONF0 0x4130
> +#define SUS_STAT_B_GPIOS_18_PAD 0x4138
> +#define USB_OC0_B_GPIOS_19_PCONF0 0x40C0
> +#define USB_OC0_B_GPIOS_19_PAD 0x40C8
> +#define USB_OC1_B_GPIOS_20_PCONF0 0x4000
> +#define USB_OC1_B_GPIOS_20_PAD 0x4008
> +#define SPI_CS1_B_GPIOS_21_PCONF0 0x4020
> +#define SPI_CS1_B_GPIOS_21_PAD 0x4028
> +#define GPIO_DFX0_GPIOS_22_PCONF0 0x4170
> +#define GPIO_DFX0_GPIOS_22_PAD 0x4178
> +#define GPIO_DFX1_GPIOS_23_PCONF0 0x4270
> +#define GPIO_DFX1_GPIOS_23_PAD 0x4278
> +#define GPIO_DFX2_GPIOS_24_PCONF0 0x41C0
> +#define GPIO_DFX2_GPIOS_24_PAD 0x41C8
> +#define GPIO_DFX3_GPIOS_25_PCONF0 0x41B0
> +#define GPIO_DFX3_GPIOS_25_PAD 0x41B8
> +#define GPIO_DFX4_GPIOS_26_PCONF0 0x4160
> +#define GPIO_DFX4_GPIOS_26_PAD 0x4168
> +#define GPIO_DFX5_GPIOS_27_PCONF0 0x4150
> +#define GPIO_DFX5_GPIOS_27_PAD 0x4158
> +#define GPIO_DFX6_GPIOS_28_PCONF0 0x4180
> +#define GPIO_DFX6_GPIOS_28_PAD 0x4188
> +#define GPIO_DFX7_GPIOS_29_PCONF0 0x4190
> +#define GPIO_DFX7_GPIOS_29_PAD 0x4198
> +#define GPIO_DFX8_GPIOS_30_PCONF0 0x41A0
> +#define GPIO_DFX8_GPIOS_30_PAD 0x41A8
> +#define USB_ULPI_0_CLK_GPIOS_31_PCONF0 0x4330
> +#define USB_ULPI_0_CLK_GPIOS_31_PAD 0x4338
> +#define USB_ULPI_0_DATA0_GPIOS_32_PCONF0 0x4380
> +#define USB_ULPI_0_DATA0_GPIOS_32_PAD 0x4388
> +#define USB_ULPI_0_DATA1_GPIOS_33_PCONF0 0x4360
> +#define USB_ULPI_0_DATA1_GPIOS_33_PAD 0x4368
> +#define USB_ULPI_0_DATA2_GPIOS_34_PCONF0 0x4310
> +#define USB_ULPI_0_DATA2_GPIOS_34_PAD 0x4318
> +#define USB_ULPI_0_DATA3_GPIOS_35_PCONF0 0x4370
> +#define USB_ULPI_0_DATA3_GPIOS_35_PAD 0x4378
> +#define USB_ULPI_0_DATA4_GPIOS_36_PCONF0 0x4300
> +#define USB_ULPI_0_DATA4_GPIOS_36_PAD 0x4308
> +#define USB_ULPI_0_DATA5_GPIOS_37_PCONF0 0x4390
> +#define USB_ULPI_0_DATA5_GPIOS_37_PAD 0x4398
> +#define USB_ULPI_0_DATA6_GPIOS_38_PCONF0 0x4320
> +#define USB_ULPI_0_DATA6_GPIOS_38_PAD 0x4328
> +#define USB_ULPI_0_DATA7_GPIOS_39_PCONF0 0x43A0
> +#define USB_ULPI_0_DATA7_GPIOS_39_PAD 0x43A8
> +#define USB_ULPI_0_DIR_GPIOS_40_PCONF0 0x4340
> +#define USB_ULPI_0_DIR_GPIOS_40_PAD 0x4348
> +#define USB_ULPI_0_NXT_GPIOS_41_PCONF0 0x4350
> +#define USB_ULPI_0_NXT_GPIOS_41_PAD 0x4358
> +#define USB_ULPI_0_STP_GPIOS_42_PCONF0 0x43B0
> +#define USB_ULPI_0_STP_GPIOS_42_PAD 0x43B8
> +#define USB_ULPI_0_REFCLK_GPIOS_43_PCONF0 0x4280
> +#define USB_ULPI_0_REFCLK_GPIOS_43_PAD 0x4288
> +
Please keep these in intel_dsi_panel_vbt.c.
Frankly they probably belong in a separate gpio driver or ACPI table
somewhere else completely.
> struct intel_dsi_host;
>
> struct intel_dsi {
> diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> index 02f1cd5..1aa5b19 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> @@ -91,18 +91,181 @@ struct gpio_table {
> };
>
> static struct gpio_table gtable[] = {
> - { GPI0_NC_0_HV_DDI0_HPD, GPIO_NC_0_HV_DDI0_PAD, 0 },
> - { GPIO_NC_1_HV_DDI0_DDC_SDA, GPIO_NC_1_HV_DDI0_DDC_SDA_PAD, 0 },
> - { GPIO_NC_2_HV_DDI0_DDC_SCL, GPIO_NC_2_HV_DDI0_DDC_SCL_PAD, 0 },
> - { GPIO_NC_3_PANEL0_VDDEN, GPIO_NC_3_PANEL0_VDDEN_PAD, 0 },
> - { GPIO_NC_4_PANEL0_BLKEN, GPIO_NC_4_PANEL0_BLKEN_PAD, 0 },
> - { GPIO_NC_5_PANEL0_BLKCTL, GPIO_NC_5_PANEL0_BLKCTL_PAD, 0 },
> - { GPIO_NC_6_PCONF0, GPIO_NC_6_PAD, 0 },
> - { GPIO_NC_7_PCONF0, GPIO_NC_7_PAD, 0 },
> - { GPIO_NC_8_PCONF0, GPIO_NC_8_PAD, 0 },
> - { GPIO_NC_9_PCONF0, GPIO_NC_9_PAD, 0 },
> - { GPIO_NC_10_PCONF0, GPIO_NC_10_PAD, 0},
> - { GPIO_NC_11_PCONF0, GPIO_NC_11_PAD, 0}
You're not removing the defines for these, although you're removing the
use.
> + {HV_DDI0_HPD_GPIONC_0_PCONF0, HV_DDI0_HPD_GPIONC_0_PAD, 0},
> + {HV_DDI0_DDC_SDA_GPIONC_1_PCONF0, HV_DDI0_DDC_SDA_GPIONC_1_PAD, 0},
> + {HV_DDI0_DDC_SCL_GPIONC_2_PCONF0, HV_DDI0_DDC_SCL_GPIONC_2_PAD, 0},
> + {PANEL0_VDDEN_GPIONC_3_PCONF0, PANEL0_VDDEN_GPIONC_3_PAD, 0},
> + {PANEL0_BKLTEN_GPIONC_4_PCONF0, PANEL0_BKLTEN_GPIONC_4_PAD, 0},
> + {PANEL0_BKLTCTL_GPIONC_5_PCONF0, PANEL0_BKLTCTL_GPIONC_5_PAD, 0},
> + {HV_DDI1_HPD_GPIONC_6_PCONF0, HV_DDI1_HPD_GPIONC_6_PAD, 0},
> + {HV_DDI1_DDC_SDA_GPIONC_7_PCONF0, HV_DDI1_DDC_SDA_GPIONC_7_PAD, 0},
> + {HV_DDI1_DDC_SCL_GPIONC_8_PCONF0, HV_DDI1_DDC_SCL_GPIONC_8_PAD, 0},
> + {PANEL1_VDDEN_GPIONC_9_PCONF0, PANEL1_VDDEN_GPIONC_9_PAD, 0},
> + {PANEL1_BKLTEN_GPIONC_10_PCONF0, PANEL1_BKLTEN_GPIONC_10_PAD, 0},
> + {PANEL1_BKLTCTL_GPIONC_11_PCONF0, PANEL1_BKLTCTL_GPIONC_11_PAD, 0},
> + {GP_INTD_DSI_TE1_GPIONC_12_PCONF0, GP_INTD_DSI_TE1_GPIONC_12_PAD, 0},
> + {HV_DDI2_DDC_SDA_GPIONC_13_PCONF0, HV_DDI2_DDC_SDA_GPIONC_13_PAD, 0},
> + {HV_DDI2_DDC_SCL_GPIONC_14_PCONF0, HV_DDI2_DDC_SCL_GPIONC_14_PAD, 0},
> + {GP_CAMERASB00_GPIONC_15_PCONF0, GP_CAMERASB00_GPIONC_15_PAD, 0},
> + {GP_CAMERASB01_GPIONC_16_PCONF0, GP_CAMERASB01_GPIONC_16_PAD, 0},
> + {GP_CAMERASB02_GPIONC_17_PCONF0, GP_CAMERASB02_GPIONC_17_PAD, 0},
> + {GP_CAMERASB03_GPIONC_18_PCONF0, GP_CAMERASB03_GPIONC_18_PAD, 0},
> + {GP_CAMERASB04_GPIONC_19_PCONF0, GP_CAMERASB04_GPIONC_19_PAD, 0},
> + {GP_CAMERASB05_GPIONC_20_PCONF0, GP_CAMERASB05_GPIONC_20_PAD, 0},
> + {GP_CAMERASB06_GPIONC_21_PCONF0, GP_CAMERASB06_GPIONC_21_PAD, 0},
> + {GP_CAMERASB07_GPIONC_22_PCONF0, GP_CAMERASB07_GPIONC_22_PAD, 0},
> + {GP_CAMERASB08_GPIONC_23_PCONF0, GP_CAMERASB08_GPIONC_23_PAD, 0},
> + {GP_CAMERASB09_GPIONC_24_PCONF0, GP_CAMERASB09_GPIONC_24_PAD, 0},
> + {GP_CAMERASB10_GPIONC_25_PCONF0, GP_CAMERASB10_GPIONC_25_PAD, 0},
> + {GP_CAMERASB11_GPIONC_26_PCONF0, GP_CAMERASB11_GPIONC_26_PAD, 0},
> +
> + {SATA_GP0_GPIOC_0_PCONF0, SATA_GP0_GPIOC_0_PAD, 0},
> + {SATA_GP1_GPIOC_1_PCONF0, SATA_GP1_GPIOC_1_PAD, 0},
> + {SATA_LEDN_GPIOC_2_PCONF0, SATA_LEDN_GPIOC_2_PAD, 0},
> + {PCIE_CLKREQ0B_GPIOC_3_PCONF0, PCIE_CLKREQ0B_GPIOC_3_PAD, 0},
> + {PCIE_CLKREQ1B_GPIOC_4_PCONF0, PCIE_CLKREQ1B_GPIOC_4_PAD, 0},
> + {PCIE_CLKREQ2B_GPIOC_5_PCONF0, PCIE_CLKREQ2B_GPIOC_5_PAD, 0},
> + {PCIE_CLKREQ3B_GPIOC_6_PCONF0, PCIE_CLKREQ3B_GPIOC_6_PAD, 0},
> + {PCIE_CLKREQ4B_GPIOC_7_PCONF0, PCIE_CLKREQ4B_GPIOC_7_PAD, 0},
> + {HDA_RSTB_GPIOC_8_PCONF0, HDA_RSTB_GPIOC_8_PAD, 0},
> + {HDA_SYNC_GPIOC_9_PCONF0, HDA_SYNC_GPIOC_9_PAD, 0},
> + {HDA_CLK_GPIOC_10_PCONF0, HDA_CLK_GPIOC_10_PAD, 0},
> + {HDA_SDO_GPIOC_11_PCONF0, HDA_SDO_GPIOC_11_PAD, 0},
> + {HDA_SDI0_GPIOC_12_PCONF0, HDA_SDI0_GPIOC_12_PAD, 0},
> + {HDA_SDI1_GPIOC_13_PCONF0, HDA_SDI1_GPIOC_13_PAD, 0},
> + {HDA_DOCKRSTB_GPIOC_14_PCONF0, HDA_DOCKRSTB_GPIOC_14_PAD, 0},
> + {HDA_DOCKENB_GPIOC_15_PCONF0, HDA_DOCKENB_GPIOC_15_PAD, 0},
> + {SDMMC1_CLK_GPIOC_16_PCONF0, SDMMC1_CLK_GPIOC_16_PAD, 0},
> + {SDMMC1_D0_GPIOC_17_PCONF0, SDMMC1_D0_GPIOC_17_PAD, 0},
> + {SDMMC1_D1_GPIOC_18_PCONF0, SDMMC1_D1_GPIOC_18_PAD, 0},
> + {SDMMC1_D2_GPIOC_19_PCONF0, SDMMC1_D2_GPIOC_19_PAD, 0},
> + {SDMMC1_D3_CD_B_GPIOC_20_PCONF0, SDMMC1_D3_CD_B_GPIOC_20_PAD, 0},
> + {MMC1_D4_SD_WE_GPIOC_21_PCONF0, MMC1_D4_SD_WE_GPIOC_21_PAD, 0},
> + {MMC1_D5_GPIOC_22_PCONF0, MMC1_D5_GPIOC_22_PAD, 0},
> + {MMC1_D6_GPIOC_23_PCONF0, MMC1_D6_GPIOC_23_PAD, 0},
> + {MMC1_D7_GPIOC_24_PCONF0, MMC1_D7_GPIOC_24_PAD, 0},
> + {SDMMC1_CMD_GPIOC_25_PCONF0, SDMMC1_CMD_GPIOC_25_PAD, 0},
> + {MMC1_RESET_B_GPIOC_26_PCONF0, MMC1_RESET_B_GPIOC_26_PAD, 0},
> + {SDMMC2_CLK_GPIOC_27_PCONF0, SDMMC2_CLK_GPIOC_27_PAD, 0},
> + {SDMMC2_D0_GPIOC_28_PCONF0, SDMMC2_D0_GPIOC_28_PAD, 0},
> + {SDMMC2_D1_GPIOC_29_PCONF0, SDMMC2_D1_GPIOC_29_PAD, 0},
> + {SDMMC2_D2_GPIOC_30_PCONF0, SDMMC2_D2_GPIOC_30_PAD, 0},
> + {SDMMC2_D3_CD_B_GPIOC_31_PCONF0, SDMMC2_D3_CD_B_GPIOC_31_PAD, 0},
> + {SDMMC2_CMD_GPIOC_32_PCONF0, SDMMC2_CMD_GPIOC_32_PAD, 0},
> + {SDMMC3_CLK_GPIOC_33_PCONF0, SDMMC3_CLK_GPIOC_33_PAD, 0},
> + {SDMMC3_D0_GPIOC_34_PCONF0, SDMMC3_D0_GPIOC_34_PAD, 0},
> + {SDMMC3_D1_GPIOC_35_PCONF0, SDMMC3_D1_GPIOC_35_PAD, 0},
> + {SDMMC3_D2_GPIOC_36_PCONF0, SDMMC3_D2_GPIOC_36_PAD, 0},
> + {SDMMC3_D3_GPIOC_37_PCONF0, SDMMC3_D3_GPIOC_37_PAD, 0},
> + {SDMMC3_CD_B_GPIOC_38_PCONF0, SDMMC3_CD_B_GPIOC_38_PAD, 0},
> + {SDMMC3_CMD_GPIOC_39_PCONF0, SDMMC3_CMD_GPIOC_39_PAD, 0},
> + {SDMMC3_1P8_EN_GPIOC_40_PCONF0, SDMMC3_1P8_EN_GPIOC_40_PAD, 0},
> + {SDMMC3_PWR_EN_B_GPIOC_41_PCONF0, SDMMC3_PWR_EN_B_GPIOC_41_PAD, 0},
> + {LPC_AD0_GPIOC_42_PCONF0, LPC_AD0_GPIOC_42_PAD, 0},
> + {LPC_AD1_GPIOC_43_PCONF0, LPC_AD1_GPIOC_43_PAD, 0},
> + {LPC_AD2_GPIOC_44_PCONF0, LPC_AD2_GPIOC_44_PAD, 0},
> + {LPC_AD3_GPIOC_45_PCONF0, LPC_AD3_GPIOC_45_PAD, 0},
> + {LPC_FRAMEB_GPIOC_46_PCONF0, LPC_FRAMEB_GPIOC_46_PAD, 0},
> + {LPC_CLKOUT0_GPIOC_47_PCONF0, LPC_CLKOUT0_GPIOC_47_PAD, 0},
> + {LPC_CLKOUT1_GPIOC_48_PCONF0, LPC_CLKOUT1_GPIOC_48_PAD, 0},
> + {LPC_CLKRUNB_GPIOC_49_PCONF0, LPC_CLKRUNB_GPIOC_49_PAD, 0},
> + {ILB_SERIRQ_GPIOC_50_PCONF0, ILB_SERIRQ_GPIOC_50_PAD, 0},
> + {SMB_DATA_GPIOC_51_PCONF0, SMB_DATA_GPIOC_51_PAD, 0},
> + {SMB_CLK_GPIOC_52_PCONF0, SMB_CLK_GPIOC_52_PAD, 0},
> + {SMB_ALERTB_GPIOC_53_PCONF0, SMB_ALERTB_GPIOC_53_PAD, 0},
> + {SPKR_GPIOC_54_PCONF0, SPKR_GPIOC_54_PAD, 0},
> + {MHSI_ACDATA_GPIOC_55_PCONF0, MHSI_ACDATA_GPIOC_55_PAD, 0},
> + {MHSI_ACFLAG_GPIOC_56_PCONF0, MHSI_ACFLAG_GPIOC_56_PAD, 0},
> + {MHSI_ACREADY_GPIOC_57_PCONF0, MHSI_ACREADY_GPIOC_57_PAD, 0},
> + {MHSI_ACWAKE_GPIOC_58_PCONF0, MHSI_ACWAKE_GPIOC_58_PAD, 0},
> + {MHSI_CADATA_GPIOC_59_PCONF0, MHSI_CADATA_GPIOC_59_PAD, 0},
> + {MHSI_CAFLAG_GPIOC_60_PCONF0, MHSI_CAFLAG_GPIOC_60_PAD, 0},
> + {MHSI_CAREADY_GPIOC_61_PCONF0, MHSI_CAREADY_GPIOC_61_PAD, 0},
> + {GP_SSP_2_CLK_GPIOC_62_PCONF0, GP_SSP_2_CLK_GPIOC_62_PAD, 0},
> + {GP_SSP_2_FS_GPIOC_63_PCONF0, GP_SSP_2_FS_GPIOC_63_PAD, 0},
> + {GP_SSP_2_RXD_GPIOC_64_PCONF0, GP_SSP_2_RXD_GPIOC_64_PAD, 0},
> + {GP_SSP_2_TXD_GPIOC_65_PCONF0, GP_SSP_2_TXD_GPIOC_65_PAD, 0},
> + {SPI1_CS0_B_GPIOC_66_PCONF0, SPI1_CS0_B_GPIOC_66_PAD, 0},
> + {SPI1_MISO_GPIOC_67_PCONF0, SPI1_MISO_GPIOC_67_PAD, 0},
> + {SPI1_MOSI_GPIOC_68_PCONF0, SPI1_MOSI_GPIOC_68_PAD, 0},
> + {SPI1_CLK_GPIOC_69_PCONF0, SPI1_CLK_GPIOC_69_PAD, 0},
> + {UART1_RXD_GPIOC_70_PCONF0, UART1_RXD_GPIOC_70_PAD, 0},
> + {UART1_TXD_GPIOC_71_PCONF0, UART1_TXD_GPIOC_71_PAD, 0},
> + {UART1_RTS_B_GPIOC_72_PCONF0, UART1_RTS_B_GPIOC_72_PAD, 0},
> + {UART1_CTS_B_GPIOC_73_PCONF0, UART1_CTS_B_GPIOC_73_PAD, 0},
> + {UART2_RXD_GPIOC_74_PCONF0, UART2_RXD_GPIOC_74_PAD, 0},
> + {UART2_TXD_GPIOC_75_PCONF0, UART2_TXD_GPIOC_75_PAD, 0},
> + {UART2_RTS_B_GPIOC_76_PCONF0, UART2_RTS_B_GPIOC_76_PAD, 0},
> + {UART2_CTS_B_GPIOC_77_PCONF0, UART2_CTS_B_GPIOC_77_PAD, 0},
> + {I2C0_SDA_GPIOC_78_PCONF0, I2C0_SDA_GPIOC_78_PAD, 0},
> + {I2C0_SCL_GPIOC_79_PCONF0, I2C0_SCL_GPIOC_79_PAD, 0},
> + {I2C1_SDA_GPIOC_80_PCONF0, I2C1_SDA_GPIOC_80_PAD, 0},
> + {I2C1_SCL_GPIOC_81_PCONF0, I2C1_SCL_GPIOC_81_PAD, 0},
> + {I2C2_SDA_GPIOC_82_PCONF0, I2C2_SDA_GPIOC_82_PAD, 0},
> + {I2C2_SCL_GPIOC_83_PCONF0, I2C2_SCL_GPIOC_83_PAD, 0},
> + {I2C3_SDA_GPIOC_84_PCONF0, I2C3_SDA_GPIOC_84_PAD, 0},
> + {I2C3_SCL_GPIOC_85_PCONF0, I2C3_SCL_GPIOC_85_PAD, 0},
> + {I2C4_SDA_GPIOC_86_PCONF0, I2C4_SDA_GPIOC_86_PAD, 0},
> + {I2C4_SCL_GPIOC_87_PCONF0, I2C4_SCL_GPIOC_87_PAD, 0},
> + {I2C5_SDA_GPIOC_88_PCONF0, I2C5_SDA_GPIOC_88_PAD, 0},
> + {I2C5_SCL_GPIOC_89_PCONF0, I2C5_SCL_GPIOC_89_PAD, 0},
> + {I2C6_SDA_GPIOC_90_PCONF0, I2C6_SDA_GPIOC_90_PAD, 0},
> + {I2C6_SCL_GPIOC_91_PCONF0, I2C6_SCL_GPIOC_91_PAD, 0},
> + {I2C_NFC_SDA_GPIOC_92_PCONF0, I2C_NFC_SDA_GPIOC_92_PAD, 0},
> + {I2C_NFC_SCL_GPIOC_93_PCONF0, I2C_NFC_SCL_GPIOC_93_PAD, 0},
> + {PWM0_GPIOC_94_PCONF0, PWM0_GPIOC_94_PAD, 0},
> + {PWM1_GPIOC_95_PCONF0, PWM1_GPIOC_95_PAD, 0},
> + {PLT_CLK0_GPIOC_96_PCONF0, PLT_CLK0_GPIOC_96_PAD, 0},
> + {PLT_CLK1_GPIOC_97_PCONF0, PLT_CLK1_GPIOC_97_PAD, 0},
> + {PLT_CLK2_GPIOC_98_PCONF0, PLT_CLK2_GPIOC_98_PAD, 0},
> + {PLT_CLK3_GPIOC_99_PCONF0, PLT_CLK3_GPIOC_99_PAD, 0},
> + {PLT_CLK4_GPIOC_100_PCONF0, PLT_CLK4_GPIOC_100_PAD, 0},
> + {PLT_CLK5_GPIOC_101_PCONF0, PLT_CLK5_GPIOC_101_PAD, 0},
> +
> + {GPIO_SUS0_GPIO_SUS0_PCONF0, GPIO_SUS0_GPIO_SUS0_PAD, 0},
> + {GPIO_SUS1_GPIO_SUS1_PCONF0, GPIO_SUS1_GPIO_SUS1_PAD, 0},
> + {GPIO_SUS2_GPIO_SUS2_PCONF0, GPIO_SUS2_GPIO_SUS2_PAD, 0},
> + {GPIO_SUS3_GPIO_SUS3_PCONF0, GPIO_SUS3_GPIO_SUS3_PAD, 0},
> + {GPIO_SUS4_GPIO_SUS4_PCONF0, GPIO_SUS4_GPIO_SUS4_PAD, 0},
> + {GPIO_SUS5_GPIO_SUS5_PCONF0, GPIO_SUS5_GPIO_SUS5_PAD, 0},
> + {GPIO_SUS6_GPIO_SUS6_PCONF0, GPIO_SUS6_GPIO_SUS6_PAD, 0},
> + {GPIO_SUS7_GPIO_SUS7_PCONF0, GPIO_SUS7_GPIO_SUS7_PAD, 0},
> + {SEC_GPIO_SUS8_GPIO_SUS8_PCONF0, SEC_GPIO_SUS8_GPIO_SUS8_PAD, 0},
> + {SEC_GPIO_SUS9_GPIO_SUS9_PCONF0, SEC_GPIO_SUS9_GPIO_SUS9_PAD, 0},
> + {SEC_GPIO_SUS10_GPIO_SUS10_PCONF0, SEC_GPIO_SUS10_GPIO_SUS10_PAD, 0},
> + {SUSPWRDNACK_GPIOS_11_PCONF0, SUSPWRDNACK_GPIOS_11_PAD, 0},
> + {PMU_SUSCLK_GPIOS_12_PCONF0, PMU_SUSCLK_GPIOS_12_PAD, 0},
> + {PMU_SLP_S0IX_B_GPIOS_13_PCONF0, PMU_SLP_S0IX_B_GPIOS_13_PAD, 0},
> + {PMU_SLP_LAN_B_GPIOS_14_PCONF0, PMU_SLP_LAN_B_GPIOS_14_PAD, 0},
> + {PMU_WAKE_B_GPIOS_15_PCONF0, PMU_WAKE_B_GPIOS_15_PAD, 0},
> + {PMU_PWRBTN_B_GPIOS_16_PCONF0, PMU_PWRBTN_B_GPIOS_16_PAD, 0},
> + {PMU_WAKE_LAN_B_GPIOS_17_PCONF0, PMU_WAKE_LAN_B_GPIOS_17_PAD, 0},
> + {SUS_STAT_B_GPIOS_18_PCONF0, SUS_STAT_B_GPIOS_18_PAD, 0},
> + {USB_OC0_B_GPIOS_19_PCONF0, USB_OC0_B_GPIOS_19_PAD, 0},
> + {USB_OC1_B_GPIOS_20_PCONF0, USB_OC1_B_GPIOS_20_PAD, 0},
> + {SPI_CS1_B_GPIOS_21_PCONF0, SPI_CS1_B_GPIOS_21_PAD, 0},
> + {GPIO_DFX0_GPIOS_22_PCONF0, GPIO_DFX0_GPIOS_22_PAD, 0},
> + {GPIO_DFX1_GPIOS_23_PCONF0, GPIO_DFX1_GPIOS_23_PAD, 0},
> + {GPIO_DFX2_GPIOS_24_PCONF0, GPIO_DFX2_GPIOS_24_PAD, 0},
> + {GPIO_DFX3_GPIOS_25_PCONF0, GPIO_DFX3_GPIOS_25_PAD, 0},
> + {GPIO_DFX4_GPIOS_26_PCONF0, GPIO_DFX4_GPIOS_26_PAD, 0},
> + {GPIO_DFX5_GPIOS_27_PCONF0, GPIO_DFX5_GPIOS_27_PAD, 0},
> + {GPIO_DFX6_GPIOS_28_PCONF0, GPIO_DFX6_GPIOS_28_PAD, 0},
> + {GPIO_DFX7_GPIOS_29_PCONF0, GPIO_DFX7_GPIOS_29_PAD, 0},
> + {GPIO_DFX8_GPIOS_30_PCONF0, GPIO_DFX8_GPIOS_30_PAD, 0},
> + {USB_ULPI_0_CLK_GPIOS_31_PCONF0, USB_ULPI_0_CLK_GPIOS_31_PAD, 0},
> + {USB_ULPI_0_DATA0_GPIOS_32_PCONF0, USB_ULPI_0_DATA0_GPIOS_32_PAD, 0},
> + {USB_ULPI_0_DATA1_GPIOS_33_PCONF0, USB_ULPI_0_DATA1_GPIOS_33_PAD, 0},
> + {USB_ULPI_0_DATA2_GPIOS_34_PCONF0, USB_ULPI_0_DATA2_GPIOS_34_PAD, 0},
> + {USB_ULPI_0_DATA3_GPIOS_35_PCONF0, USB_ULPI_0_DATA3_GPIOS_35_PAD, 0},
> + {USB_ULPI_0_DATA4_GPIOS_36_PCONF0, USB_ULPI_0_DATA4_GPIOS_36_PAD, 0},
> + {USB_ULPI_0_DATA5_GPIOS_37_PCONF0, USB_ULPI_0_DATA5_GPIOS_37_PAD, 0},
> + {USB_ULPI_0_DATA6_GPIOS_38_PCONF0, USB_ULPI_0_DATA6_GPIOS_38_PAD, 0},
> + {USB_ULPI_0_DATA7_GPIOS_39_PCONF0, USB_ULPI_0_DATA7_GPIOS_39_PAD, 0},
> + {USB_ULPI_0_DIR_GPIOS_40_PCONF0, USB_ULPI_0_DIR_GPIOS_40_PAD, 0},
> + {USB_ULPI_0_NXT_GPIOS_41_PCONF0, USB_ULPI_0_NXT_GPIOS_41_PAD, 0},
> + {USB_ULPI_0_STP_GPIOS_42_PCONF0, USB_ULPI_0_STP_GPIOS_42_PAD, 0},
> + {USB_ULPI_0_REFCLK_GPIOS_43_PCONF0, USB_ULPI_0_REFCLK_GPIOS_43_PAD, 0}
Add space after {.
> };
>
> static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
> @@ -261,14 +424,42 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
> u8 gpio, action;
> u16 function, pad;
> u32 val;
> + u8 block;
> struct drm_device *dev = intel_dsi->base.base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
>
> + DRM_DEBUG_DRIVER("MIPI: executing gpio element\n");
> +
> + /*
> + * Skipping the first byte as it is of no
> + * interest for android in new version
> + */
> + if (dev_priv->vbt.dsi.seq_version >= 3)
> + data++;
> +
> gpio = *data++;
>
> /* pull up/down */
> action = *data++;
>
> + if (dev_priv->vbt.dsi.seq_version >= 3) {
> + if (gpio <= MAX_GPIO_NUM_NC) {
> + DRM_DEBUG_DRIVER("GPIO is in the north Block\n");
> + block = IOSF_PORT_GPIO_NC;
> + } else if (gpio > MAX_GPIO_NUM_NC && gpio <= MAX_GPIO_NUM_SC) {
> + DRM_DEBUG_DRIVER("GPIO is in the south Block\n");
> + block = IOSF_PORT_GPIO_SC;
> + } else if (gpio > MAX_GPIO_NUM_SC && gpio <= MAX_GPIO_NUM) {
> + DRM_DEBUG_DRIVER("GPIO is in the SUS Block\n");
> + block = IOSF_PORT_GPIO_SUS;
> + } else {
> + DRM_ERROR("GPIO number is not present in the table\n");
> + return NULL;
> + }
> + } else {
> + block = IOSF_PORT_GPIO_NC;
> + }
> +
> function = gtable[gpio].function_reg;
> pad = gtable[gpio].pad_reg;
>
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 25+ messages in thread
* [MIPI SEQ PARSING v2 PATCH 08/11] drm/i915: GPIO for CHT generic MIPI
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (6 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 07/11] drm/i915: Added the generic gpio sequence support and gpio table Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 09/11] drm: Add few more wrapper functions for drm panel Deepak M
` (2 subsequent siblings)
10 siblings, 0 replies; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx
From: Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
The GPIO configuration and register offsets are different from
baytrail for cherrytrail. Port the gpio programming accordingly
for cherrytrail in this patch.
v2: Rebase
Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 23 ++++++
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 117 +++++++++++++++++++++++-----
2 files changed, 122 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5bef50c..c5bea41 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -568,11 +568,21 @@
#define IOSF_PORT_DPIO 0x12
#define IOSF_PORT_DPIO_2 0x1a
#define IOSF_PORT_GPIO_NC 0x13
+#define CHV_IOSF_PORT_GPIO_N 0x13
#define IOSF_PORT_GPIO_SC 0x48
+#define CHV_IOSF_PORT_GPIO_SE 0x48
+#define CHV_IOSF_PORT_GPIO_SW 0xB2
#define IOSF_PORT_GPIO_SUS 0xA8
+#define CHV_IOSF_PORT_GPIO_E 0xA8
#define MAX_GPIO_NUM_NC 26
#define MAX_GPIO_NUM_SC 128
#define MAX_GPIO_NUM 172
+#define CHV_MAX_GPIO_NUM_N 72
+#define CHV_MAX_GPIO_NUM_SE 99
+#define CHV_MAX_GPIO_NUM_SW 197
+#define CHV_MIN_GPIO_NUM_SE 73
+#define CHV_MIN_GPIO_NUM_SW 100
+#define CHV_MIN_GPIO_NUM_E 198
#define IOSF_PORT_CCK 0x14
#define IOSF_PORT_CCU 0xA9
#define IOSF_PORT_GPS_CORE 0x48
@@ -580,6 +590,19 @@
#define VLV_IOSF_DATA (VLV_DISPLAY_BASE + 0x2104)
#define VLV_IOSF_ADDR (VLV_DISPLAY_BASE + 0x2108)
+#define VLV_GPIO_CFG 0x2000CC00
+#define VLV_GPIO_INPUT_DIS 0x04
+
+#define CHV_PAD_FMLY_BASE 0x4400
+#define CHV_PAD_FMLY_SIZE 0x400
+#define CHV_PAD_CFG_0_1_REG_SIZE 0x8
+#define CHV_PAD_CFG_REG_SIZE 0x4
+#define CHV_VBT_MAX_PINS_PER_FMLY 15
+
+#define CHV_GPIO_CFG_UNLOCK 0x00000000
+#define CHV_GPIO_CFG_HiZ 0x00008100
+#define CHV_GPIO_CFG_TX_STATE_SHIFT 1
+
/* See configdb bunit SB addr map */
#define BUNIT_REG_BISOC 0x11
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 1aa5b19..b0d09f6 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -418,17 +418,75 @@ static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data)
return data;
}
-
-static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
+static int chv_program_gpio(struct intel_dsi *intel_dsi,
+ const u8 *data, const u8 **cur_data)
{
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u8 gpio, action;
+ u16 family_num;
u16 function, pad;
- u32 val;
u8 block;
+
+ /*
+ * Skipping the first byte as it is of no
+ * interest for linux kernel in new VBT version
+ */
+ if (dev_priv->vbt.dsi.seq_version >= 3)
+ data++;
+
+ gpio = *data++;
+
+ /* pull up/down */
+ action = *data++;
+
+ if (dev_priv->vbt.dsi.seq_version >= 3) {
+ if (gpio <= CHV_MAX_GPIO_NUM_N) {
+ block = CHV_IOSF_PORT_GPIO_N;
+ DRM_DEBUG_DRIVER("GPIO is in the north Block\n");
+ } else if (gpio <= CHV_MAX_GPIO_NUM_SE) {
+ block = CHV_IOSF_PORT_GPIO_SE;
+ gpio = gpio - CHV_MIN_GPIO_NUM_SE;
+ DRM_DEBUG_DRIVER("GPIO is in the south east Block\n");
+ } else if (gpio <= CHV_MAX_GPIO_NUM_SW) {
+ block = CHV_IOSF_PORT_GPIO_SW;
+ gpio = gpio - CHV_MIN_GPIO_NUM_SW;
+ DRM_DEBUG_DRIVER("GPIO is in the south west Block\n");
+ } else {
+ block = CHV_IOSF_PORT_GPIO_E;
+ gpio = gpio - CHV_MIN_GPIO_NUM_E;
+ DRM_DEBUG_DRIVER("GPIO is in the east Block\n");
+ }
+ } else
+ block = IOSF_PORT_GPIO_NC;
+
+ family_num = gpio / CHV_VBT_MAX_PINS_PER_FMLY;
+ gpio = gpio - (family_num * CHV_VBT_MAX_PINS_PER_FMLY);
+ pad = CHV_PAD_FMLY_BASE + (family_num * CHV_PAD_FMLY_SIZE) +
+ (((u16)gpio) * CHV_PAD_CFG_0_1_REG_SIZE);
+ function = pad + CHV_PAD_CFG_REG_SIZE;
+
+ mutex_lock(&dev_priv->sb_lock);
+ vlv_gpio_write(dev_priv, block, function,
+ CHV_GPIO_CFG_UNLOCK);
+ vlv_gpio_write(dev_priv, block, pad, CHV_GPIO_CFG_HiZ |
+ (action << CHV_GPIO_CFG_TX_STATE_SHIFT));
+ mutex_unlock(&dev_priv->sb_lock);
+
+ *cur_data = data;
+
+ return 0;
+}
+
+static int vlv_program_gpio(struct intel_dsi *intel_dsi,
+ const u8 *data, const u8 **cur_data)
+{
struct drm_device *dev = intel_dsi->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
-
- DRM_DEBUG_DRIVER("MIPI: executing gpio element\n");
+ u8 gpio, action;
+ u16 function, pad;
+ u32 val;
+ u8 block;
/*
* Skipping the first byte as it is of no
@@ -444,39 +502,62 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
if (dev_priv->vbt.dsi.seq_version >= 3) {
if (gpio <= MAX_GPIO_NUM_NC) {
- DRM_DEBUG_DRIVER("GPIO is in the north Block\n");
block = IOSF_PORT_GPIO_NC;
+ DRM_DEBUG_DRIVER("GPIO is in the north Block\n");
} else if (gpio > MAX_GPIO_NUM_NC && gpio <= MAX_GPIO_NUM_SC) {
- DRM_DEBUG_DRIVER("GPIO is in the south Block\n");
block = IOSF_PORT_GPIO_SC;
+ DRM_DEBUG_DRIVER("GPIO is in the south Block\n");
} else if (gpio > MAX_GPIO_NUM_SC && gpio <= MAX_GPIO_NUM) {
- DRM_DEBUG_DRIVER("GPIO is in the SUS Block\n");
block = IOSF_PORT_GPIO_SUS;
+ DRM_DEBUG_DRIVER("GPIO is in the SUS Block\n");
} else {
DRM_ERROR("GPIO number is not present in the table\n");
- return NULL;
+ return -EINVAL;
}
- } else {
+ } else
block = IOSF_PORT_GPIO_NC;
- }
function = gtable[gpio].function_reg;
pad = gtable[gpio].pad_reg;
mutex_lock(&dev_priv->sb_lock);
+
if (!gtable[gpio].init) {
- /* program the function */
- /* FIXME: remove constant below */
- vlv_gpio_write(dev_priv, IOSF_PORT_GPIO_NC, function, 0x2000CC00);
- gtable[gpio].init = 1;
+ vlv_gpio_write(dev_priv, block, function,
+ VLV_GPIO_CFG);
+ gtable[gpio].init = true;
}
-
- val = 0x4 | action;
+ val = VLV_GPIO_INPUT_DIS | action;
/* pull up/down */
- vlv_gpio_write(dev_priv, IOSF_PORT_GPIO_NC, pad, val);
+ vlv_gpio_write(dev_priv, block, pad, val);
+
mutex_unlock(&dev_priv->sb_lock);
+ *cur_data = data;
+
+ return 0;
+}
+
+static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
+{
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ int ret;
+
+ DRM_DEBUG_DRIVER("MIPI: executing gpio element\n");
+
+ ret = -EINVAL;
+
+ if (IS_CHERRYVIEW(dev))
+ ret = chv_program_gpio(intel_dsi, data, &data);
+ else if (IS_VALLEYVIEW(dev))
+ ret = vlv_program_gpio(intel_dsi, data, &data);
+ else
+ DRM_ERROR("GPIO programming missing for this platform.\n");
+
+ if (ret)
+ return NULL;
+
return data;
}
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* [MIPI SEQ PARSING v2 PATCH 09/11] drm: Add few more wrapper functions for drm panel
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (7 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 08/11] drm/i915: GPIO for CHT generic MIPI Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 10/11] drm/i915: Add functions to execute the new sequences from VBT Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 11/11] drm/i915: BXT GPIO support for backlight and panel control Deepak M
10 siblings, 0 replies; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M
Currently there are few pair of functions which
are called during the panel enable/disable sequence.
To improve the granularity, adding few more wrapper
functions so that the functions are more specific
on what they are doing.
v2: rebase
Signed-off-by: Deepak M <m.deepak@intel.com>
Signed-off-by: Gaurav K Singh <gaurav.k.singh@intel.com>
---
include/drm/drm_panel.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 13ff44b..c729f6d 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -73,6 +73,12 @@ struct drm_panel_funcs {
int (*get_modes)(struct drm_panel *panel);
int (*get_timings)(struct drm_panel *panel, unsigned int num_timings,
struct display_timing *timings);
+ int (*power_on)(struct drm_panel *panel);
+ int (*power_off)(struct drm_panel *panel);
+ int (*backlight_on)(struct drm_panel *panel);
+ int (*backlight_off)(struct drm_panel *panel);
+ int (*get_info)(struct drm_panel *panel,
+ struct drm_connector *connector);
};
struct drm_panel {
@@ -117,6 +123,47 @@ static inline int drm_panel_enable(struct drm_panel *panel)
return panel ? -ENOSYS : -EINVAL;
}
+static inline int drm_panel_power_on(struct drm_panel *panel)
+{
+ if (panel && panel->funcs && panel->funcs->power_on)
+ return panel->funcs->power_on(panel);
+
+ return panel ? -ENOSYS : -EINVAL;
+}
+
+static inline int drm_panel_power_off(struct drm_panel *panel)
+{
+ if (panel && panel->funcs && panel->funcs->power_off)
+ return panel->funcs->power_off(panel);
+
+ return panel ? -ENOSYS : -EINVAL;
+}
+
+static inline int drm_panel_backlight_on(struct drm_panel *panel)
+{
+ if (panel && panel->funcs && panel->funcs->backlight_on)
+ return panel->funcs->backlight_on(panel);
+
+ return panel ? -ENOSYS : -EINVAL;
+}
+
+static inline int drm_panel_backlight_off(struct drm_panel *panel)
+{
+ if (panel && panel->funcs && panel->funcs->backlight_off)
+ return panel->funcs->backlight_off(panel);
+
+ return panel ? -ENOSYS : -EINVAL;
+}
+
+static inline int drm_panel_get_info(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ if (connector && panel && panel->funcs && panel->funcs->get_info)
+ return panel->funcs->get_info(panel, connector);
+
+ return panel ? -ENOSYS : -EINVAL;
+}
+
static inline int drm_panel_get_modes(struct drm_panel *panel)
{
if (panel && panel->funcs && panel->funcs->get_modes)
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* [MIPI SEQ PARSING v2 PATCH 10/11] drm/i915: Add functions to execute the new sequences from VBT
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (8 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 09/11] drm: Add few more wrapper functions for drm panel Deepak M
@ 2015-09-09 23:24 ` Deepak M
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 11/11] drm/i915: BXT GPIO support for backlight and panel control Deepak M
10 siblings, 0 replies; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak M, Shobhit Kumar
From: Gaurav K Singh <gaurav.k.singh@intel.com>
New sequences are added in the mipi sequence block of the
VBT from version 3 onwards. The sequences are added to
make the code more generic as the panel related info
are placed in the VBT.
v2: rebase
Signed-off-by: Gaurav K Singh <gaurav.k.singh@intel.com>
Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
Signed-off-by: Deepak M <m.deepak@intel.com>
---
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 84 +++++++++++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index b0d09f6..2263559 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -584,7 +584,13 @@ static const char * const seq_name[] = {
"MIPI_SEQ_INIT_OTP",
"MIPI_SEQ_DISPLAY_ON",
"MIPI_SEQ_DISPLAY_OFF",
- "MIPI_SEQ_DEASSERT_RESET"
+ "MIPI_SEQ_DEASSERT_RESET",
+ "MIPI_SEQ_BACKLIGHT_ON",
+ "MIPI_SEQ_BACKLIGHT_OFF",
+ "MIPI_SEQ_TEAR_ON",
+ "MIPI_SEQ_TEAR_OFF",
+ "MIPI_SEQ_POWER_ON",
+ "MIPI_SEQ_POWER_OFF"
};
static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
@@ -713,12 +719,88 @@ static int vbt_panel_get_modes(struct drm_panel *panel)
return 1;
}
+static int vbt_panel_power_on(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_POWER_ON];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_power_off(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_POWER_OFF];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_backlight_on(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_BACKLIGHT_ON];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_backlight_off(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_BACKLIGHT_OFF];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_get_info(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct intel_connector *intel_connector =
+ to_intel_connector(connector);
+
+ if (intel_connector) {
+ connector->display_info.width_mm =
+ intel_connector->panel.fixed_mode->width_mm;
+ connector->display_info.height_mm =
+ intel_connector->panel.fixed_mode->height_mm;
+ }
+ return 0;
+}
+
static const struct drm_panel_funcs vbt_panel_funcs = {
.disable = vbt_panel_disable,
.unprepare = vbt_panel_unprepare,
.prepare = vbt_panel_prepare,
.enable = vbt_panel_enable,
.get_modes = vbt_panel_get_modes,
+ .power_on = vbt_panel_power_on,
+ .power_off = vbt_panel_power_off,
+ .backlight_on = vbt_panel_backlight_on,
+ .backlight_off = vbt_panel_backlight_off,
+ .get_info = vbt_panel_get_info,
};
struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id)
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread* [MIPI SEQ PARSING v2 PATCH 11/11] drm/i915: BXT GPIO support for backlight and panel control
2015-09-09 23:24 [MIPI SEQ PARSING v2 PATCH 00/11] Patches to support the version 3 of MIPI sequence in VBT Deepak M
` (9 preceding siblings ...)
2015-09-09 23:24 ` [MIPI SEQ PARSING v2 PATCH 10/11] drm/i915: Add functions to execute the new sequences from VBT Deepak M
@ 2015-09-09 23:24 ` Deepak M
10 siblings, 0 replies; 25+ messages in thread
From: Deepak M @ 2015-09-09 23:24 UTC (permalink / raw)
To: intel-gfx
From: Uma Shankar <uma.shankar@intel.com>
Added the BXT GPIO pin configuration and programming logic for
backlight and panel control.
v2: rebase
Signed-off-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 46 ++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 2263559..4c5e33a 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <video/mipi_display.h>
#include <linux/i2c.h>
+#include <linux/gpio.h>
#include <asm/intel-mid.h>
#include <video/mipi_display.h>
#include "i915_drv.h"
@@ -327,6 +328,16 @@ out:
return data;
}
+struct bxt_gpio_table {
+ u16 gpio_pin;
+ u16 offset;
+};
+
+static struct bxt_gpio_table bxt_gtable[] = {
+ {0xC1, 270},
+ {0x1B, 456}
+};
+
static inline enum port intel_dsi_seq_port_to_port(u8 port)
{
return port ? PORT_C : PORT_A;
@@ -539,6 +550,39 @@ static int vlv_program_gpio(struct intel_dsi *intel_dsi,
return 0;
}
+static int bxt_program_gpio(struct intel_dsi *intel_dsi,
+ const u8 *data, const u8 **cur_data)
+{
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u8 gpio, action;
+ u16 function;
+
+ /*
+ * Skipping the first byte as it is of no
+ * interest for android in new version
+ */
+ if (dev_priv->vbt.dsi.seq_version >= 3)
+ data++;
+
+ gpio = *data++;
+
+ /* pull up/down */
+ action = *data++;
+ function = (bxt_gtable[0].gpio_pin == gpio) ?
+ bxt_gtable[0].offset :
+ (bxt_gtable[1].gpio_pin == gpio) ?
+ bxt_gtable[1].offset : 0;
+ if (!function)
+ return -1;
+
+ gpio_request_one(function, GPIOF_DIR_OUT, "MIPI");
+ gpio_set_value(function, action);
+
+ *cur_data = data;
+ return 0;
+}
+
static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
{
struct drm_device *dev = intel_dsi->base.base.dev;
@@ -552,6 +596,8 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
ret = chv_program_gpio(intel_dsi, data, &data);
else if (IS_VALLEYVIEW(dev))
ret = vlv_program_gpio(intel_dsi, data, &data);
+ else if (IS_BROXTON(dev))
+ ret = bxt_program_gpio(intel_dsi, data, &data);
else
DRM_ERROR("GPIO programming missing for this platform.\n");
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 25+ messages in thread